# This class implements a thread that handles the networking connection. # It expects a copy of the board and an open socket to the remote host, which # it will bind to a GTPSocket. # This is the only thread that should be calling get(), but send() could be called # twice, so we wrap it in a mutex. # The board is also wrapped in a mutex, even though only this thread should modify it # if it exists. import threading class NetworkThread(threading.Thread): dispatcher = { 'quit': do_quit, 'boardsize': do_boardsize, 'clear_board': do_clear_board, 'komi': do_komi, 'play': do_play, 'genmove': do_genmove } def __init__(self, goban, socket): self.goban = goban self.goban_lock = threading.Lock() self.socket = GTPSocket(socket) self.send_lock = threading.Lock() GTPSocket.known_cmds = GTPSocket.known_cmds & set(NetworkThread.dispatcher.keys()) def run(self): while True: gtp = self.socket.get() if gtp is not None: NetworkThread.dispatcher[gtp.command](gtp) def do_quit(self, gtp): pass def do_boardsize(self, gtp): with self.goban_lock: self.goban.set_board_size(int(gtp.arguments[0])) def do_clear_board(self, gtp): with self.goban_lock: self.goban.reset() def do_komi(self, gtp): with self.goban_lock: self.goban.komi = float(gtp.arguments[0]) def do_play(self, gtp): if gtp.arguments[0] == 'black': color = goban.Goban.BLACK elif gtp.arguments[0] == 'white': color = goban.Goban.WHITE row = int(gtp.arguments[1][1:]) col = ord(gtp.arguments[1][0]) - 96 with self.goban_lock: self.goban.play_move((row,col), color) def do_genmove(self, gtp): pass