connect gtp and gui

This commit is contained in:
rtz19970824 2017-12-07 17:51:58 +08:00
parent 2d9d1ff945
commit 67a9a39e92
4 changed files with 53 additions and 17 deletions

View File

@ -138,6 +138,7 @@ class GTPEngine():
return self.known_commands, True return self.known_commands, True
def cmd_quit(self, args, **kwargs): def cmd_quit(self, args, **kwargs):
self.disconnect = True
return None, True return None, True
def cmd_boardsize(self, args, **kwargs): def cmd_boardsize(self, args, **kwargs):
@ -180,3 +181,8 @@ class GTPEngine():
return self._vertex_point2string(move), True return self._vertex_point2string(move), True
else: else:
return 'unknown player', False return 'unknown player', False
if __name__ == "main":
game = Game()
engine = GTPEngine(game_obj=Game)

View File

@ -15,13 +15,17 @@ import numpy as np
# This means that swapping colors is as simple as multiplying array by -1. # This means that swapping colors is as simple as multiplying array by -1.
WHITE, EMPTY, BLACK, FILL, KO, UNKNOWN = range(-1, 5) WHITE, EMPTY, BLACK, FILL, KO, UNKNOWN = range(-1, 5)
class PlayerMove(namedtuple('PlayerMove', ['color', 'move'])): pass class PlayerMove(namedtuple('PlayerMove', ['color', 'move'])): pass
# Represents "group not found" in the LibertyTracker object # Represents "group not found" in the LibertyTracker object
MISSING_GROUP_ID = -1 MISSING_GROUP_ID = -1
class IllegalMove(Exception): pass class IllegalMove(Exception): pass
# these are initialized by set_board_size # these are initialized by set_board_size
N = None N = None
ALL_COORDS = [] ALL_COORDS = []
@ -29,6 +33,7 @@ EMPTY_BOARD = None
NEIGHBORS = {} NEIGHBORS = {}
DIAGONALS = {} DIAGONALS = {}
def set_board_size(n): def set_board_size(n):
''' '''
Hopefully nobody tries to run both 9x9 and 19x19 game instances at once. Hopefully nobody tries to run both 9x9 and 19x19 game instances at once.
@ -39,17 +44,23 @@ def set_board_size(n):
N = n N = n
ALL_COORDS = [(i, j) for i in range(n) for j in range(n)] ALL_COORDS = [(i, j) for i in range(n) for j in range(n)]
EMPTY_BOARD = np.zeros([n, n], dtype=np.int8) EMPTY_BOARD = np.zeros([n, n], dtype=np.int8)
def check_bounds(c): def check_bounds(c):
return c[0] % n == c[0] and c[1] % n == c[1] return c[0] % n == c[0] and c[1] % n == c[1]
NEIGHBORS = {(x, y): list(filter(check_bounds, [(x+1, y), (x-1, y), (x, y+1), (x, y-1)])) for x, y in ALL_COORDS} NEIGHBORS = {(x, y): list(filter(check_bounds, [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)])) for x, y in
DIAGONALS = {(x, y): list(filter(check_bounds, [(x+1, y+1), (x+1, y-1), (x-1, y+1), (x-1, y-1)])) for x, y in ALL_COORDS} ALL_COORDS}
DIAGONALS = {(x, y): list(filter(check_bounds, [(x + 1, y + 1), (x + 1, y - 1), (x - 1, y + 1), (x - 1, y - 1)]))
for x, y in ALL_COORDS}
def place_stones(board, color, stones): def place_stones(board, color, stones):
for s in stones: for s in stones:
board[s] = color board[s] = color
def find_reached(board, c): def find_reached(board, c):
# that can reach from one place
color = board[c] color = board[c]
chain = set([c]) chain = set([c])
reached = set() reached = set()
@ -58,12 +69,13 @@ def find_reached(board, c):
current = frontier.pop() current = frontier.pop()
chain.add(current) chain.add(current)
for n in NEIGHBORS[current]: for n in NEIGHBORS[current]:
if board[n] == color and not n in chain: if board[n] == color and (not n in chain):
frontier.append(n) frontier.append(n)
elif board[n] != color: elif board[n] != color:
reached.add(n) reached.add(n)
return chain, reached return chain, reached
def is_koish(board, c): def is_koish(board, c):
'Check if c is surrounded on all sides by 1 color, and return that color' 'Check if c is surrounded on all sides by 1 color, and return that color'
if board[c] != EMPTY: return None if board[c] != EMPTY: return None
@ -73,6 +85,7 @@ def is_koish(board, c):
else: else:
return None return None
def is_eyeish(board, c): def is_eyeish(board, c):
'Check if c is an eye, for the purpose of restricting MC rollouts.' 'Check if c is an eye, for the purpose of restricting MC rollouts.'
color = is_koish(board, c) color = is_koish(board, c)
@ -90,17 +103,19 @@ def is_eyeish(board, c):
else: else:
return color return color
class Group(namedtuple('Group', ['id', 'stones', 'liberties', 'color'])): class Group(namedtuple('Group', ['id', 'stones', 'liberties', 'color'])):
''' '''
stones: a set of Coordinates belonging to this group stones: a set of Coordinates belonging to this group
liberties: a set of Coordinates that are empty and adjacent to this group. liberties: a set of Coordinates that are empty and adjacent to this group.
color: color of this group color: color of this group
''' '''
def __eq__(self, other): def __eq__(self, other):
return self.stones == other.stones and self.liberties == other.liberties and self.color == other.color return self.stones == other.stones and self.liberties == other.liberties and self.color == other.color
class LibertyTracker(): class LibertyTracker(object):
@staticmethod @staticmethod
def from_board(board): def from_board(board):
board = np.copy(board) board = np.copy(board)
@ -233,8 +248,10 @@ class LibertyTracker():
if group_id != MISSING_GROUP_ID: if group_id != MISSING_GROUP_ID:
self._update_liberties(group_id, add={s}) self._update_liberties(group_id, add={s})
class Position(): class Position():
def __init__(self, board=None, n=0, komi=7.5, caps=(0, 0), lib_tracker=None, ko=None, recent=tuple(), to_play=BLACK): def __init__(self, board=None, n=0, komi=7.5, caps=(0, 0), lib_tracker=None, ko=None, recent=tuple(),
to_play=BLACK):
''' '''
board: a numpy array board: a numpy array
n: an int representing moves played so far n: an int representing moves played so far
@ -276,7 +293,7 @@ class Position():
row = [] row = []
for j in range(N): for j in range(N):
appended = '<' if (self.recent and (i, j) == self.recent[-1].move) else ' ' appended = '<' if (self.recent and (i, j) == self.recent[-1].move) else ' '
row.append(pretty_print_map[board[i,j]] + appended) row.append(pretty_print_map[board[i, j]] + appended)
row.append('\x1b[0m') row.append('\x1b[0m')
raw_board_contents.append(''.join(row)) raw_board_contents.append(''.join(row))
@ -407,4 +424,5 @@ class Position():
else: else:
return 'DRAW' return 'DRAW'
set_board_size(19) set_board_size(19)

View File

@ -3,7 +3,7 @@ from engine import GTPEngine
import re import re
g = Game() g = Game()
pattern = "[A-Z]{1}[0-9]{1}"
g.show_board() g.show_board()
e = GTPEngine(game_obj=g) e = GTPEngine(game_obj=g)
@ -15,7 +15,12 @@ while not (black_pass and white_pass):
if num % 2 == 0: if num % 2 == 0:
res = e.run_cmd(str(num) + " genmove BLACK") res = e.run_cmd(str(num) + " genmove BLACK")
num += 1 num += 1
print(res) # print(res)
match = re.search(pattern, res)
if match is not None:
print(match.group())
else:
print("pass")
if re.search("pass", res) is not None: if re.search("pass", res) is not None:
black_pass = True black_pass = True
else: else:
@ -23,7 +28,11 @@ while not (black_pass and white_pass):
else: else:
res = e.run_cmd(str(num) + " genmove WHITE") res = e.run_cmd(str(num) + " genmove WHITE")
num += 1 num += 1
print(res) match = re.search(pattern, res)
if match is not None:
print(match.group())
else:
print("pass")
if re.search("pass", res) is not None: if re.search("pass", res) is not None:
white_pass = True white_pass = True
else: else:

View File

@ -1,11 +1,14 @@
import sys
from game import Game from game import Game
from engine import GTPEngine from engine import GTPEngine
import utils import utils
game = Game()
engine = GTPEngine(game_obj=game, name='tianshou')
cmd = raw_input
while not engine.disconnect:
g = Game() command = cmd()
e = GTPEngine(game_obj = g) result = engine.run_cmd(command)
sys.stdout.write(result)
res = e.run_cmd('8 genmove BLACK') sys.stdout.flush()
print(res)