-
Notifications
You must be signed in to change notification settings - Fork 0
/
gtp.lua
111 lines (100 loc) · 2.89 KB
/
gtp.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
ENGINE = { name = "gnugo", bin = "/usr/bin/gnugo --mode gtp" }
-- ENGINE = { name = "pachi", bin = "/usr/bin/pachi" }
--[[ for testing gtp:
local KOMI = 6.5
local SIZE = 19
local TO_PLAY = -1
--]]
function gtp_setup()
if IS_AI.black then
GTP_BLACK_CO = coroutine.create(gtp_repl)
local success, err = coroutine.resume(GTP_BLACK_CO, BLACK)
if not success then
print("Error starting coroutine: " .. err)
end
end
if IS_AI.white then
GTP_WHITE_CO = coroutine.create(gtp_repl)
local success, err = coroutine.resume(GTP_WHITE_CO, WHITE)
if not success then
print("Error starting coroutine: " .. err)
end
end
return GTP_BLACK_CO, GTP_WHITE_CO
end
function gtp_turn(gtp_coroutine)
success, move = coroutine.resume(gtp_coroutine, JUST_PLAYED)
print("The move is:", move.x, move.y)
CURRENT.x, CURRENT.y = move.x, move.y
place_stone()
end
function gtp_sync(engine)
send_command(engine, "clear_board")
for _, stone in ipairs(STONES) do
if stone.color == BLACK then
color = "black"
else
color = "white"
end
gtp_play(engine, color, gtp_to_engine(stone.x, stone.y))
end
end
function send_command(engine, command)
print("sending command", command)
engine:write(command .. "\n")
engine:flush()
-- check success from file, '='
end
function gtp_play(engine, color, move)
return send_command(engine, "play " .. color .. " " .. move) ~= false
end
function gtp_genmove(engine, color)
local move = send_command(engine, "genmove " .. color)
return move
end
function gtp_undo(engine)
return send_command(engine, "undo") ~= false
end
function gtp_pass(engine)
return send_command(engine, "pass") ~= false
end
-- TODO add check for pass
function gtp_repl(player_color)
if player_color == WHITE then
player, opponent = "white", "black"
else
player, opponent = "black", "white"
end
local temp_file = os.tmpname()
local prev_move
engine = io.popen(ENGINE.bin .. " > " .. temp_file, "w")
send_command(engine, "boardsize " .. SIZE)
send_command(engine, "komi " .. KOMI)
send_command(engine, "clear_board")
print("Setup complete.")
move = coroutine.yield()
while true do
if move.x then
gtp_play(engine, opponent, gtp_to_engine(move.x, move.y))
elseif move.undo then
gtp_play(engine, opponent, "undo")
JUST_PLAYED.undo = nil
else
gtp_play(engine, opponent, "pass")
end
gtp_genmove(engine, player)
repeat
repeat
-- add clause to clear file when exceeds given size
genmove = (io.open(temp_file, "r"):read("*a")) -- prints whole file
genmove = string.sub(genmove, -6)
genmove = genmove:gsub("[\n= %s\r\n]", "")
until genmove ~= prev_move
os.execute("sleep 1")
local x, _ = gtp_from_engine(genmove)
until x ~= false
prev_move = genmove
local x, y = gtp_from_engine(genmove)
move = coroutine.yield({ x = x, y = y })
end
end