Created
April 30, 2016 16:58
-
-
Save anonymous/166eda49cad4549f89f2c59587f81c78 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
内藤九段将棋秘伝 (FC) 思考ログ出力 | |
--]] | |
---------------------------------------------------------------------- | |
-- utility | |
---------------------------------------------------------------------- | |
local function mem_read_u8(addr) | |
return memory.readbyte(addr) | |
end | |
---------------------------------------------------------------------- | |
-- log | |
---------------------------------------------------------------------- | |
local out = nil | |
local function out_init() | |
local path = os.date("log/%Y%m%d-%H%M%S.log") | |
out = io.open(path, "w") | |
return out and true or false | |
end | |
local function out_fin() | |
if out then | |
out:close() | |
out = nil | |
end | |
end | |
local function info(msg) | |
out:write(msg) | |
out:write("\n") | |
end | |
---------------------------------------------------------------------- | |
-- game utility | |
---------------------------------------------------------------------- | |
-- pt: 駒種 | |
-- pcp: PLAYER駒 | |
-- pcc: COM駒 | |
local KANDIGIT = { | |
"一", "二", "三", "四", "五", "六", "七", "八", "九" | |
} | |
--[[ | |
local PT_NAME = { | |
"KING", | |
"ROOK", | |
"BISHOP", | |
"GOLD", | |
"SILVER", | |
"KNIGHT", | |
"LANCE", | |
"PAWN", | |
"DRAGON", | |
"HORSE", | |
nil, | |
"PRO_SILVER", | |
"PRO_KNIGHT", | |
"PRO_LANCE", | |
"PRO_PAWN", | |
} | |
--]] | |
local PT_NAME = { | |
"玉", | |
"飛", | |
"角", | |
"金", | |
"銀", | |
"桂", | |
"香", | |
"歩", | |
"竜", | |
"馬", | |
nil, | |
"全", | |
"圭", | |
"杏", | |
"と" | |
} | |
local function sq_is_ok(sq) | |
return 12 <= sq and sq <= 108 | |
end | |
local function drop_pt(drop) | |
return 209 - drop | |
end | |
local function drop_is_ok(drop) | |
return 201 <= drop and drop <= 207 | |
end | |
local function pt_is_ok(pt) | |
return 1 <= pt and pt <= #PT_NAME and PT_NAME[pt] | |
end | |
local function pcp_type(pcp) | |
return pcp | |
end | |
local function pcp_is_ok(pcp) | |
return pt_is_ok(pcp_type(pcp)) | |
end | |
local function pcc_type(pcc) | |
return pcc - 0x0F | |
end | |
local function pcc_is_ok(pcc) | |
return pt_is_ok(pcc_type(pcc)) | |
end | |
local function sq2xy(sq) | |
local x = sq % 11 | |
local y = math.floor(sq / 11) | |
return x, y | |
end | |
local function xy2sq(x, y) | |
return x + 11 * y | |
end | |
local function board_player(sq) | |
return mem_read_u8(0x03A9 + sq) | |
end | |
local function board_com(sq) | |
return mem_read_u8(0x049B + sq) | |
end | |
local function hand_player() | |
local hand = {} | |
for i = 1, 7 do | |
hand[i] = mem_read_u8(0x058D + i-1) | |
end | |
return hand | |
end | |
local function hand_com() | |
local hand = {} | |
for i = 1, 7 do | |
hand[i] = mem_read_u8(0x0594 + i-1) | |
end | |
return hand | |
end | |
local function move_str(src, dst, pt) | |
local dst_file, dst_rank = sq2xy(dst) | |
dst_file = 10 - dst_file -- 将棋の表記法に合わせる | |
if drop_is_ok(src) then | |
--return string.format("%d%d %s DROP", dst_file, dst_rank, PT_NAME[pt]) | |
return string.format("%d%d%s打", dst_file, dst_rank, PT_NAME[pt]) | |
else | |
local src_file, src_rank = sq2xy(src) | |
src_file = 10 - src_file | |
--return string.format("%d%d %s (%d%d)", dst_file, dst_rank, PT_NAME[pt], src_file, src_rank) | |
return string.format("%d%d%s (%d%d)", dst_file, dst_rank, PT_NAME[pt], src_file, src_rank) | |
end | |
end | |
local function hand_str(hand) | |
local s = "" | |
for i, n in ipairs(hand) do | |
if n > 0 then | |
s = s .. string.format("%s%d ", PT_NAME[i+1], n) | |
end | |
end | |
return s | |
end | |
local function print_position() | |
info("▽持駒: " .. hand_str(hand_com())) | |
info(" 9 8 7 6 5 4 3 2 1") | |
info("┌──┬──┬──┬──┬──┬──┬──┬──┬──┐") | |
for y = 1, 9 do | |
local line = "│" | |
for x = 1, 9 do | |
local pcp = board_player(xy2sq(x, y)) | |
local pcc = board_com(xy2sq(x, y)) | |
assert(pcp == 0 or pcc == 0, "pcp && pcc") | |
if pcp_is_ok(pcp) then | |
line = line .. "▲" .. PT_NAME[pcp_type(pcp)] | |
elseif pcc_is_ok(pcc) then | |
line = line .. "▽" .. PT_NAME[pcc_type(pcc)] | |
else | |
line = line .. "__" | |
end | |
line = line .. "│" | |
end | |
line = line .. KANDIGIT[y] | |
info(line) | |
if y ~= 9 then info("├──┼──┼──┼──┼──┼──┼──┼──┼──┤") end | |
end | |
info("└──┴──┴──┴──┴──┴──┴──┴──┴──┘") | |
info("▲持駒: " .. hand_str(hand_player())) | |
end | |
---------------------------------------------------------------------- | |
-- callback | |
---------------------------------------------------------------------- | |
-- ルート局面を出力 | |
-- 候補手生成ループ直前に呼び出される | |
local function log_root() | |
info("[ルート局面]") | |
local move_src_player = mem_read_u8(0x05A2) | |
local move_dst_player = mem_read_u8(0x05A1) | |
local move_pt_player = pcp_type(board_player(move_dst_player)) | |
info(string.format("num_move2: %d", mem_read_u8(0x05C1))) | |
info(string.format("progress: %d", mem_read_u8(0x028E))) | |
info(string.format("formation: %d", mem_read_u8(0x05BE))) | |
info(string.format("player move: %s", | |
move_str(move_src_player, move_dst_player, move_pt_player))) | |
info("") | |
print_position() | |
info("") | |
info(string.format("root_power_player: %d", mem_read_u8(0x05E7))) | |
info(string.format("root_rbp_com: %d", mem_read_u8(0x05EA))) | |
info(string.format("root_power_com: %d", mem_read_u8(0x05E4))) | |
info(string.format("root_adv_score: %d", mem_read_u8(0x0280))) | |
info(string.format("root_disadv_score: %d", mem_read_u8(0x0282))) | |
info(string.format("root_player_offer: %s", tostring(mem_read_u8(0x05DE) == 2))) | |
info("") | |
info("[候補手生成開始]") | |
end | |
-- 1つの候補手を出力 | |
-- 候補手生成後それが評価される直前に呼び出される | |
-- よって出力は全ての合法手となるはず | |
-- ただし完全な合法手というわけではない。以下のものも含まれる: | |
-- * 自殺手 | |
-- * 打ち歩詰め | |
-- 以下のものは含まれない: | |
-- * 不成 (COMは成れるときは必ず成る) | |
-- * 行き所のない駒 | |
-- * 二歩 | |
local function log_cand() | |
local src = mem_read_u8(0x0277) | |
local dst = mem_read_u8(0x0276) | |
local pt = pcc_type(mem_read_u8(0x5F)) | |
assert(sq_is_ok(src) or drop_is_ok(src), "invalid src") | |
assert(sq_is_ok(dst), "invalid dst") | |
assert(pt_is_ok(pt), "invalid pt") | |
if drop_is_ok(src) then assert(drop_pt(src) == pt, "drop_pt(src) ~= pt") end | |
info(move_str(src, dst, pt)) | |
info(string.format(" cand_score: %d", mem_read_u8(0x0278))) | |
info(string.format(" cand_offer: %d", mem_read_u8(0x027C))) | |
info(string.format(" adv_score: %d", mem_read_u8(0x0272))) | |
info(string.format(" adv_sq: %d", mem_read_u8(0x0273))) | |
info(string.format(" disadv_score: %d", mem_read_u8(0x0274))) | |
info(string.format(" disadv_sq: %d", mem_read_u8(0x0275))) | |
info(string.format(" num_promoted_com: %d", mem_read_u8(0x0293))) | |
info(string.format(" dist_dst_kp: %d", mem_read_u8(0x0294))) | |
info(string.format(" dist_src_kc: %d", mem_read_u8(0x0298))) | |
info(string.format(" threat_far_player: %d", mem_read_u8(0x0299))) | |
info(string.format(" safety_far_com: %d", mem_read_u8(0x0295))) | |
info(string.format(" threat_far_com: %d", mem_read_u8(0x0296))) | |
info(string.format(" threat_near_com: %d", mem_read_u8(0x05EB))) | |
info(string.format(" surround_com: %d", mem_read_u8(0x05E5))) | |
info(string.format(" num_loose_com: %d", mem_read_u8(0x0297))) | |
info(string.format(" dangling_pawn_lance: %d", mem_read_u8(0x05DF))) | |
info(string.format(" $02A4: %d", mem_read_u8(0x02A4))) | |
info(string.format(" $05E0: %d", mem_read_u8(0x05E0))) | |
end | |
-- 候補手評価完了時の評価値を出力 | |
-- 一部のタダ捨て、および打ち歩詰めは評価完了前に切り捨てられる | |
local function log_eval() | |
info(" [評価完了]") | |
info(string.format(" mate_player: %d", mem_read_u8(0x05DD))) | |
info(string.format(" cand_score: %d", mem_read_u8(0x0278))) | |
info(string.format(" adv_score: %d", mem_read_u8(0x0272))) | |
info(string.format(" disadv_score: %d", mem_read_u8(0x0274))) | |
info(string.format(" $02A4: %d", mem_read_u8(0x02A4))) | |
info(string.format(" $05E0: %d", mem_read_u8(0x05E0))) | |
end | |
-- 最善手更新時にその旨出力 | |
local function log_best() | |
info(" [最善手更新]") | |
end | |
---------------------------------------------------------------------- | |
-- main | |
---------------------------------------------------------------------- | |
local function main() | |
if not out_init() then | |
print("Can't open file") | |
return | |
end | |
emu.registerexit(out_fin) | |
memory.registerexec(0xF045, log_root) | |
memory.registerexec(0xF282, log_cand) | |
memory.registerexec(0xF674, log_eval) | |
memory.registerexec(0xF6F9, log_best) | |
end | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment