class AEIAdapter(object): def __init__(self, command, controller): pid = str(os.getpid()) self.posFileName = "running/matchPos" + pid self.moveFileName = "running/matchMove" + pid self.gamestateFileName = "running/matchGamestate" + pid self.command = command + " " + self.posFileName + " " + \ self.moveFileName + " " + self.gamestateFileName if not os.path.exists(os.getcwd() + "/running"): os.mkdir(os.getcwd() + "/running") self.controller = controller try: header = controller.messages.get(30) except Empty: raise Exception("Timed out waiting for AEI header") if header != "aei": raise Exception("No AEI header received, instead (%s)" % header) controller.send("protocol-version 1") controller.send("id name Adapter") controller.send("id author Rabbits") controller.send("aeiok") self.options = {} self.turnnumber = 1 self.color = Color.GOLD self.newgame() self.movesSoFar = "" def newgame(self): self.position = Position(Color.GOLD, 4, board.BLANK_BOARD) self.insetup = True def setposition(self, side_str, pos_str): side = "gswb".find(side_str) % 2 self.position = board.parse_short_pos(side, 4, pos_str) self.insetup = False def setoption(self, name, value): if name == "wreserve": name = "greserve" elif name == "breserve": name = "sreserve" elif name == "moveused": name = "tcmoveused" std_opts = set(["tcmove", "tcreserve", "tcpercent", "tcmax", "tctotal", "tcturns", "tcturntime", "greserve", "sreserve", "gused", "sused", "lastmoveused", "tcmoveused", "opponent", "opponent_rating"]) if name in std_opts: self.options[name] = int(value) else: self.log("Warning: Received unrecognized option, %s" % (name)) def makemove(self, move_str): self.position = self.position.do_move_str(move_str) movetag = str(self.turnnumber) if self.insetup and self.position.color == Color.GOLD: self.insetup = False if self.color == Color.SILVER: self.turnnumber += 1 self.color = Color.GOLD movetag += "b " # s else: self.color = Color.SILVER movetag += "w " # g self.movesSoFar += movetag + move_str + "\n" def go(self): self.writeRunningFiles() (status, move_str) = commands.getstatusoutput(self.command) # This assumes that the last (or only) line of output is the move choice move_lines = move_str.split("\n") self.bestmove(move_lines.pop()) def log(self, msg): self.controller.send("log " + msg) def bestmove(self, move_str): self.controller.send("bestmove " + move_str) def main(self): ctl = self.controller while not ctl.stop.isSet(): msg = ctl.messages.get() if msg == "isready": ctl.send("readyok") elif msg == "newgame": self.newgame() elif msg.startswith("setposition"): side, pos_str = msg.split(None, 2)[1:] self.setposition(side, pos_str) elif msg.startswith("setoption"): words = msg.split() name = words[2] v_ix = msg.find(name) + len(name) v_ix = msg.find("value", v_ix) if v_ix != -1: value = msg[v_ix + 5:] else: value = None self.setoption(name, value) elif msg.startswith("makemove"): move_str = msg.split(None, 1)[1] self.makemove(move_str) elif msg.startswith("go"): if len(msg.split()) == 1: self.go() elif msg == "stop": pass elif msg == "quit": self.removeRunningFiles() return def writeRunningFiles(self): posFile = open(self.posFileName, "w") posFile.write(self.positionString()) posFile.close() moveFile = open(self.moveFileName, "w") moveFile.write(self.moveListString()) moveFile.close() gamestateFile = open(self.gamestateFileName, "w") gamestateFile.write(self.gamestateString()) gamestateFile.close() def positionString(self): turn = str(self.turnnumber) if self.color == Color.GOLD: turn += "w" # g else: turn += "b" # s board_str = self.position.board_to_str(dots=False) # Fairy needs big X's. board_str = board_str.replace("x", "X") return turn + "\n" + board_str def moveListString(self): string = self.movesSoFar string += str(self.turnnumber) if self.color == Color.GOLD: string += "w" # g else: string += "b" # s return string + "\n" def gamestateString(self): gamestate = "" for k, v in self.options.iteritems(): if k == "greserve": key = "tcwreserve" elif k == "sreserve": key = "tcbreserve" else: key = k gamestate += k + "=" + str(v) + "\n" if self.color == Color.GOLD: gamestate += "turn=w\n" else: gamestate += "turn=b\n" gamestate += "--END--" return gamestate def removeRunningFiles(self): os.remove(self.posFileName) os.remove(self.moveFileName) os.remove(self.gamestateFileName)
class AEIEngine(object): def __init__(self, controller): self.strict_checks = True self.move_delay = None self.total_move_time = 0.0 self.controller = controller try: header = controller.messages.get(30) except Empty: raise AEIException("Timed out waiting for aei header") if header != "aei": raise AEIException("Did not receive aei header, instead (%s)" % (header)) controller.send("protocol-version 1") controller.send("id name Sample Engine") controller.send("id author Janzert") controller.send("aeiok") self.newgame() def newgame(self): self.position = Position(Color.GOLD, 4, BLANK_BOARD) self.insetup = True def setposition(self, side_str, pos_str): side = "gswb".find(side_str) % 2 self.position = parse_short_pos(side, 4, pos_str) self.insetup = False def setoption(self, name, value): std_opts = set(["tcmove", "tcreserve", "tcpercent", "tcmax", "tctotal", "tcturns", "tcturntime", "greserve", "sreserve", "gused", "sused", "lastmoveused", "moveused", "opponent", "opponent_rating"]) if name == "checkmoves": self.strict_checks = value.lower() in ["false", "no", "0"] elif name == "delaymove": self.move_delay = float(value) elif name not in std_opts: self.log("Warning: Received unrecognized option, %s" % (name)) def makemove(self, move_str): try: self.position = self.position.do_move_str(move_str, self.strict_checks) except IllegalMove as exc: self.log("Error: received illegal move %s" % (move_str,)) return False if self.insetup and self.position.color == Color.GOLD: self.insetup = False return True def go(self): pos = self.position start_time = time.time() if self.insetup: setup = Position(Color.GOLD, 4, BASIC_SETUP) setup_moves = setup.to_placing_move() move_str = setup_moves[pos.color][2:] else: steps, result = pos.get_rnd_step_move() if steps is None: # we are immobilized, return an empty move move_str = "" self.log("Warning: move requested when immobilized.") else: move_str = pos.steps_to_str(steps) if self.move_delay: time.sleep(self.move_delay) move_time = time.time() - start_time self.total_move_time += move_time self.info("time %d" % (int(round(move_time),))) self.bestmove(move_str) def info(self, msg): self.controller.send("info " + msg) def log(self, msg): self.controller.send("log " + msg) def bestmove(self, move_str): self.controller.send("bestmove " + move_str) def main(self): ctl = self.controller while not ctl.stop.isSet(): msg = ctl.messages.get() if msg == "isready": ctl.send("readyok") elif msg == "newgame": self.newgame() elif msg.startswith("setposition"): side, pos_str = msg.split(None, 2)[1:] self.setposition(side, pos_str) elif msg.startswith("setoption"): words = msg.split() name = words[2] v_ix = msg.find(name) + len(name) v_ix = msg.find("value", v_ix) if v_ix != -1: value = msg[v_ix + 5:] else: value = None self.setoption(name, value) elif msg.startswith("makemove"): move_str = msg.split(None, 1)[1] if not self.makemove(move_str): return elif msg.startswith("go"): if len(msg.split()) == 1: self.go() elif msg == "stop": pass elif msg == "quit": self.log("Debug: Exiting after receiving quit message.") if self.total_move_time > 0: self.info("move gen time %f" % (self.total_move_time,)) return
class AEIEngine(object): def __init__(self, controller): self.strict_checks = True self.move_delay = None self.total_move_time = 0.0 self.controller = controller try: header = controller.messages.get(30) except Empty: raise AEIException("Timed out waiting for aei header") if header != "aei": raise AEIException("Did not receive aei header, instead (%s)" % (header)) controller.send("protocol-version 1") controller.send("id name Sample Engine") controller.send("id author Janzert") controller.send("aeiok") self.newgame() def newgame(self): self.position = Position(Color.GOLD, 4, BLANK_BOARD) self.insetup = True def setposition(self, side_str, pos_str): side = "gswb".find(side_str) % 2 self.position = parse_short_pos(side, 4, pos_str) self.insetup = False def setoption(self, name, value): std_opts = set([ "tcmove", "tcreserve", "tcpercent", "tcmax", "tctotal", "tcturns", "tcturntime", "greserve", "sreserve", "gused", "sused", "lastmoveused", "moveused", "opponent", "opponent_rating" ]) if name == "checkmoves": self.strict_checks = value.lower().strip() not in [ "false", "no", "0" ] elif name == "delaymove": self.move_delay = float(value) elif name not in std_opts: self.log("Warning: Received unrecognized option, %s" % (name)) def makemove(self, move_str): try: self.position = self.position.do_move_str(move_str, self.strict_checks) except IllegalMove as exc: self.log("Error: received illegal move %s" % (move_str, )) return False if self.insetup and self.position.color == Color.GOLD: self.insetup = False return True def go(self): pos = self.position start_time = time.time() if self.insetup: setup = Position(Color.GOLD, 4, BASIC_SETUP) setup_moves = setup.to_placing_move() move_str = setup_moves[pos.color][2:] else: steps, result = pos.get_rnd_step_move() if steps is None: # we are immobilized, return an empty move move_str = "" self.log("Warning: move requested when immobilized.") else: move_str = pos.steps_to_str(steps) if self.move_delay: time.sleep(self.move_delay) move_time = time.time() - start_time self.total_move_time += move_time self.info("time %d" % (int(round(move_time), ))) self.bestmove(move_str) def info(self, msg): self.controller.send("info " + msg) def log(self, msg): self.controller.send("log " + msg) def bestmove(self, move_str): self.controller.send("bestmove " + move_str) def main(self): ctl = self.controller while not ctl.stop.isSet(): msg = ctl.messages.get() if msg == "isready": ctl.send("readyok") elif msg == "newgame": self.newgame() elif msg.startswith("setposition"): side, pos_str = msg.split(None, 2)[1:] self.setposition(side, pos_str) elif msg.startswith("setoption"): words = msg.split() name = words[2] v_ix = msg.find(name) + len(name) v_ix = msg.find("value", v_ix) if v_ix != -1: value = msg[v_ix + 5:] else: value = None self.setoption(name, value) elif msg.startswith("makemove"): move_str = msg.split(None, 1)[1] if not self.makemove(move_str): return elif msg.startswith("go"): if len(msg.split()) == 1: self.go() elif msg == "stop": pass elif msg == "quit": self.log("Debug: Exiting after receiving quit message.") if self.total_move_time > 0: self.info("move gen time %f" % (self.total_move_time, )) return
class AEIEngine(object): def __init__(self, controller): self.controller = controller try: header = controller.messages.get(30) except Empty: raise AEIException("Timed out waiting for aei header") if header != "aei": raise AEIException("Did not receive aei header, instead (%s)" % ( header)) controller.send("protocol-version 1") controller.send("id name Sample Engine") controller.send("id author Janzert") controller.send("aeiok") self.newgame() def newgame(self): self.position = Position(Color.GOLD, 4, BLANK_BOARD) self.insetup = True def setposition(self, side_str, pos_str): side = "gswb".find(side_str) % 2 self.position = parse_short_pos(side, 4, pos_str) self.insetup = False def setoption(self, name, value): std_opts = set(["tcmove", "tcreserve", "tcpercent", "tcmax", "tctotal", "tcturns", "tcturntime", "greserve", "sreserve", "gused", "sused", "lastmoveused", "moveused", "opponent", "opponent_rating"]) if name not in std_opts: self.log("Warning: Received unrecognized option, %s" % (name)) def makemove(self, move_str): self.position = self.position.do_move_str(move_str) if self.insetup and self.position.color == Color.GOLD: self.insetup = False def go(self): pos = self.position if self.insetup: setup = Position(Color.GOLD, 4, BASIC_SETUP) setup_moves = setup.to_placing_move() move_str = setup_moves[pos.color][2:] else: steps, result = pos.get_rnd_step_move() move_str = pos.steps_to_str(steps) self.bestmove(move_str) def log(self, msg): self.controller.send("log " + msg) def bestmove(self, move_str): self.controller.send("bestmove " + move_str) def main(self): ctl = self.controller while not ctl.stop.isSet(): msg = ctl.messages.get() if msg == "isready": ctl.send("readyok") elif msg == "newgame": self.newgame() elif msg.startswith("setposition"): side, pos_str = msg.split(None, 2)[1:] self.setposition(side, pos_str) elif msg.startswith("setoption"): words = msg.split() name = words[2] v_ix = msg.find(name) + len(name) v_ix = msg.find("value", v_ix) if v_ix != -1: value = msg[v_ix + 5:] else: value = None self.setoption(name, value) elif msg.startswith("makemove"): move_str = msg.split(None, 1)[1] self.makemove(move_str) elif msg.startswith("go"): if len(msg.split()) == 1: self.go() elif msg == "stop": pass elif msg == "quit": return
class AEIAdapter(object): def __init__(self, command, controller): pid = str(os.getpid()) self.posFileName = "running/matchPos" + pid self.moveFileName = "running/matchMove" + pid self.gamestateFileName = "running/matchGamestate" + pid self.command = command + " " + self.posFileName + " " + \ self.moveFileName + " " + self.gamestateFileName if not os.path.exists(os.getcwd() + "/running"): os.mkdir(os.getcwd() + "/running") self.controller = controller try: header = controller.messages.get(30) except Empty: raise Exception("Timed out waiting for AEI header") if header != "aei": raise Exception("No AEI header received, instead (%s)" % header) controller.send("protocol-version 1") controller.send("id name Adapter") controller.send("id author Rabbits") controller.send("aeiok") self.options = {} self.turnnumber = 1 self.color = Color.GOLD self.newgame() self.movesSoFar = "" def newgame(self): self.position = Position(Color.GOLD, 4, board.BLANK_BOARD) self.insetup = True def setposition(self, side_str, pos_str): side = "gswb".find(side_str) % 2 self.position = board.parse_short_pos(side, 4, pos_str) self.insetup = False def setoption(self, name, value): if name == "wreserve": name = "greserve" elif name == "breserve": name = "sreserve" elif name == "moveused": name = "tcmoveused" std_opts = set([ "tcmove", "tcreserve", "tcpercent", "tcmax", "tctotal", "tcturns", "tcturntime", "greserve", "sreserve", "gused", "sused", "lastmoveused", "tcmoveused", "opponent", "opponent_rating" ]) if name in std_opts: self.options[name] = int(value) else: self.log("Warning: Received unrecognized option, %s" % (name)) def makemove(self, move_str): self.position = self.position.do_move_str(move_str) movetag = str(self.turnnumber) if self.insetup and self.position.color == Color.GOLD: self.insetup = False if self.color == Color.SILVER: self.turnnumber += 1 self.color = Color.GOLD movetag += "b " # s else: self.color = Color.SILVER movetag += "w " # g self.movesSoFar += movetag + move_str + "\n" def go(self): self.writeRunningFiles() (status, move_str) = commands.getstatusoutput(self.command) # This assumes that the last (or only) line of output is the move choice move_lines = move_str.split("\n") self.bestmove(move_lines.pop()) def log(self, msg): self.controller.send("log " + msg) def bestmove(self, move_str): self.controller.send("bestmove " + move_str) def main(self): ctl = self.controller while not ctl.stop.isSet(): msg = ctl.messages.get() if msg == "isready": ctl.send("readyok") elif msg == "newgame": self.newgame() elif msg.startswith("setposition"): side, pos_str = msg.split(None, 2)[1:] self.setposition(side, pos_str) elif msg.startswith("setoption"): words = msg.split() name = words[2] v_ix = msg.find(name) + len(name) v_ix = msg.find("value", v_ix) if v_ix != -1: value = msg[v_ix + 5:] else: value = None self.setoption(name, value) elif msg.startswith("makemove"): move_str = msg.split(None, 1)[1] self.makemove(move_str) elif msg.startswith("go"): if len(msg.split()) == 1: self.go() elif msg == "stop": pass elif msg == "quit": self.removeRunningFiles() return def writeRunningFiles(self): posFile = open(self.posFileName, "w") posFile.write(self.positionString()) posFile.close() moveFile = open(self.moveFileName, "w") moveFile.write(self.moveListString()) moveFile.close() gamestateFile = open(self.gamestateFileName, "w") gamestateFile.write(self.gamestateString()) gamestateFile.close() def positionString(self): turn = str(self.turnnumber) if self.color == Color.GOLD: turn += "w" # g else: turn += "b" # s board_str = self.position.board_to_str(dots=False) # Fairy needs big X's. board_str = board_str.replace("x", "X") return turn + "\n" + board_str def moveListString(self): string = self.movesSoFar string += str(self.turnnumber) if self.color == Color.GOLD: string += "w" # g else: string += "b" # s return string + "\n" def gamestateString(self): gamestate = "" for k, v in self.options.iteritems(): if k == "greserve": key = "tcwreserve" elif k == "sreserve": key = "tcbreserve" else: key = k gamestate += k + "=" + str(v) + "\n" if self.color == Color.GOLD: gamestate += "turn=w\n" else: gamestate += "turn=b\n" gamestate += "--END--" return gamestate def removeRunningFiles(self): os.remove(self.posFileName) os.remove(self.moveFileName) os.remove(self.gamestateFileName)
class AEIEngine(object): def __init__(self, controller): self.controller = controller try: header = controller.messages.get(30) except Empty: raise AEIException("Timed out waiting for aei header") if header != "aei": raise AEIException("Did not receive aei header, instead (%s)" % (header)) controller.send("protocol-version 1") controller.send("id name Sample Engine") controller.send("id author Janzert") controller.send("aeiok") self.newgame() def newgame(self): self.position = Position(Color.GOLD, 4, BLANK_BOARD) self.insetup = True def setposition(self, side_str, pos_str): side = "gswb".find(side_str) % 2 self.position = parse_short_pos(side, 4, pos_str) self.insetup = False def setoption(self, name, value): std_opts = set(["tcmove", "tcreserve", "tcpercent", "tcmax", "tctotal", "tcturns", "tcturntime", "greserve", "sreserve", "gused", "sused", "lastmoveused", "moveused", "opponent", "opponent_rating"]) if name not in std_opts: self.log("Warning: Received unrecognized option, %s" % (name)) def makemove(self, move_str): self.position = self.position.do_move_str(move_str) if self.insetup and self.position.color == Color.GOLD: self.insetup = False def go(self): pos = self.position if self.insetup: setup = Position(Color.GOLD, 4, BASIC_SETUP) setup_moves = setup.to_placing_move() move_str = setup_moves[pos.color][2:] else: steps, result = pos.get_rnd_step_move() move_str = pos.steps_to_str(steps) self.bestmove(move_str) def log(self, msg): self.controller.send("log " + msg) def bestmove(self, move_str): self.controller.send("bestmove " + move_str) def main(self): ctl = self.controller while not ctl.stop.isSet(): msg = ctl.messages.get() if msg == "isready": ctl.send("readyok") elif msg == "newgame": self.newgame() elif msg.startswith("setposition"): side, pos_str = msg.split(None, 2)[1:] self.setposition(side, pos_str) elif msg.startswith("setoption"): words = msg.split() name = words[2] v_ix = msg.find(name) + len(name) v_ix = msg.find("value", v_ix) if v_ix != -1: value = msg[v_ix + 5:] else: value = None self.setoption(name, value) elif msg.startswith("makemove"): move_str = msg.split(None, 1)[1] self.makemove(move_str) elif msg.startswith("go"): if len(msg.split()) == 1: self.go() elif msg == "stop": pass elif msg == "quit": return
def playgame(gold_eng, silver_eng, timecontrol=None, position=None): engines = (gold_eng, silver_eng) if timecontrol: time_incr = timecontrol['move'] reserves = [0, 0] reserves[0] = reserves[1] = timecontrol['reserve'] reserve_per = timecontrol['percent'] / 100.0 reserve_max = timecontrol['max'] max_moves = timecontrol['turns'] max_gametime = timecontrol['total'] max_turn = timecontrol['turntime'] for eng in engines: eng.setoption("tcmove", time_incr) eng.setoption("tcreserve", timecontrol['reserve']) eng.setoption("tcpercent", timecontrol['percent']) eng.setoption("tcmax", reserve_max) eng.setoption("tcturns", max_moves) eng.setoption("tctotal", max_gametime) eng.setoption("tcturntime", max_turn) else: max_gametime = 0 max_moves = 0 for eng in engines: eng.newgame() if position: eng.setposition(position) eng.isready() insetup = False if not position: insetup = True position = Position(Color.GOLD, 4, board.BLANK_BOARD) starttime = time.time() if max_gametime: endtime_limit = starttime + max_gametime position.movenumber = 1 limit_winner = 1 while insetup or not position.is_end_state(): #print "%d%s" % (position.movenumber, "gs"[position.color]) #print position.board_to_str() side = position.color engine = engines[side] if timecontrol: if engine.protocol_version > 0: engine.setoption("greserve", int(reserves[0])) engine.setoption("sreserve", int(reserves[1])) else: engine.setoption("wreserve", int(reserves[0])) engine.setoption("breserve", int(reserves[1])) engine.setoption("tcmoveused", 0) movestart = time.time() engine.setoption("moveused", 0) engine.go() if timecontrol: timeout = movestart + time_incr + reserves[side] if max_turn and starttime + max_turn > timeout: timeout = starttime + max_turn if max_gametime and endtime_limit < timeout: timeout = endtime_limit bstr = position.board_to_str("short") gp = 0 for p in "EMHDCR": gp += bstr.count(p) sp = 0 for p in "emhdcr": sp += bstr.count(p) if gp > sp: limit_winner = 0 elif sp > gp: limit_winner = 1 else: timeout = None resp = None try: while not timeout or time.time() < timeout: if timeout: wait = timeout - time.time() else: wait = None resp = engine.get_response(wait) if resp.type == "bestmove": break if resp.type == "info": log.info("%s info: %s" % ("gs"[side], resp.message)) elif resp.type == "log": log.info("%s log: %s" % ("gs"[side], resp.message)) except socket.timeout: engine.stop() endtime = time.time() if resp and resp.type == "bestmove": if timecontrol: moveend = time.time() if moveend > timeout: return (side ^ 1, "t", position) if not insetup: reserve_incr = ((time_incr - (moveend - movestart)) * reserve_per) reserves[side] += reserve_incr if reserve_max: reserves[side] = min(reserves[side], reserve_max) move = resp.move mn = position.movenumber position = position.do_move_str(move) if position.color == Color.GOLD: mn += 1 position.movenumber = mn log.info("position:\n%s", position.board_to_str()) for eng in engines: eng.makemove(move) if insetup and side == Color.SILVER: insetup = False if max_moves and position.movenumber > max_moves: return (limit_winner, "s", position) elif not max_gametime or endtime < endtime_limit: return (side ^ 1, "t", position) else: # exceeded game time limit return (limit_winner, "s", position) if position.is_goal(): result = (min(position.is_goal(), 0), "g", position) elif position.is_rabbit_loss(): result = (min(position.is_rabbit_loss(), 0), "e", position) else: # immobilization assert len(position.get_steps()) == 0 result = (position.color ^ 1, "m", position) return result
def playgame(gold_eng, silver_eng, timecontrol=None, position=None): engines = (gold_eng, silver_eng) if timecontrol: time_incr = timecontrol['move'] reserves = [0, 0] reserves[0] = reserves[1] = timecontrol['reserve'] reserve_per = timecontrol['percent'] / 100.0 reserve_max = timecontrol['max'] max_moves = timecontrol['turns'] max_gametime = timecontrol['total'] max_turn = timecontrol['turntime'] for eng in engines: eng.setoption("tcmove", time_incr) eng.setoption("tcreserve", timecontrol['reserve']) eng.setoption("tcpercent", timecontrol['percent']) eng.setoption("tcmax", reserve_max) eng.setoption("tcturns", max_moves) eng.setoption("tctotal", max_gametime) eng.setoption("tcturntime", max_turn) else: max_gametime = 0 max_moves = 0 for eng in engines: eng.newgame() if position: eng.setposition(position) eng.isready() insetup = False if not position: insetup = True position = Position(Color.GOLD, 4, board.BLANK_BOARD) starttime = time.time() if max_gametime: endtime_limit = starttime + max_gametime position.movenumber = 1 limit_winner = 1 while insetup or not position.is_end_state(): #print "%d%s" % (position.movenumber, "gs"[position.color]) #print position.board_to_str() side = position.color engine = engines[side] if timecontrol: if engine.protocol_version > 0: engine.setoption("greserve", int(reserves[0])) engine.setoption("sreserve", int(reserves[1])) else: engine.setoption("wreserve", int(reserves[0])) engine.setoption("breserve", int(reserves[1])) engine.setoption("tcmoveused", 0) movestart = time.time() engine.setoption("moveused", 0) engine.go() if timecontrol: timeout = movestart + time_incr + reserves[side] if max_turn and starttime + max_turn > timeout: timeout = starttime + max_turn if max_gametime and endtime_limit < timeout: timeout = endtime_limit bstr = position.board_to_str("short") gp = 0 for p in "EMHDCR": gp += bstr.count(p) sp = 0 for p in "emhdcr": sp += bstr.count(p) if gp > sp: limit_winner = 0 elif sp > gp: limit_winner = 1 else: timeout = None resp = None try: while not timeout or time.time() < timeout: if timeout: wait = timeout - time.time() else: wait = None resp = engine.get_response(wait) if resp.type == "bestmove": break if resp.type == "info": log.info("%s info: %s" % ("gs"[side], resp.message)) elif resp.type == "log": log.info("%s log: %s" % ("gs"[side], resp.message)) except socket.timeout: engine.stop() endtime = time.time() if resp and resp.type == "bestmove": if timecontrol: moveend = time.time() if moveend > timeout: return (side^1, "t", position) if not insetup: reserve_incr = ((time_incr - (moveend - movestart)) * reserve_per) reserves[side] += reserve_incr if reserve_max: reserves[side] = min(reserves[side], reserve_max) move = resp.move mn = position.movenumber position = position.do_move_str(move) if position.color == Color.GOLD: mn += 1 position.movenumber = mn log.info("position:\n%s", position.board_to_str()) for eng in engines: eng.makemove(move) if insetup and side == Color.SILVER: insetup = False if max_moves and position.movenumber > max_moves: return (limit_winner, "s", position) elif not max_gametime or endtime < endtime_limit: return (side^1, "t", position) else: # exceeded game time limit return (limit_winner, "s", position) if position.is_goal(): result = (min(position.is_goal(), 0), "g", position) elif position.is_rabbit_loss(): result = (min(position.is_rabbit_loss(), 0), "e", position) else: # immobilization assert len(position.get_steps()) == 0 result = (position.color^1, "m", position) return result