Exemplo n.º 1
0
    def __init__(self,
                 gold,
                 silver,
                 timecontrol=None,
                 start_position=None,
                 strict_setup=True,
                 min_timeleft=None):
        self.engines = (gold, silver)
        try:
            self.timecontrol = timecontrol[0]
            self.side_tc = timecontrol
        except TypeError:
            self.timecontrol = timecontrol
            self.side_tc = [timecontrol, timecontrol]
        self.reserves = [None, None]
        if timecontrol:
            for side, eng in enumerate(self.engines):
                if not self.side_tc[side]:
                    continue
                self.reserves[side] = self.side_tc[side].reserve
                eng.setoption("tcmove", self.side_tc[side].move)
                eng.setoption("tcreserve", self.side_tc[side].reserve)
                eng.setoption("tcpercent", self.side_tc[side].percent)
                eng.setoption("tcmax", self.side_tc[side].max_reserve)
                eng.setoption("tcturns", self.side_tc[side].turn_limit)
                eng.setoption("tctotal", self.side_tc[side].time_limit)
                eng.setoption("tcturntime", self.side_tc[side].max_turntime)
        for eng in self.engines:
            eng.newgame()
            if start_position:
                eng.setposition(start_position)
            resps = eng.isready()
            side = "gs"[self.engines.index(eng)]
            eng_name = eng.ident["name"]
            for response in resps:
                if response.type == "info":
                    log.info("%s (%s) info: %s", eng_name, side,
                             response.message)
                elif response.type == "log":
                    log.info("%s (%s) log: %s", eng_name, side,
                             response.message)
                else:
                    log.warn(
                        "Unexpected response while initializing %s (%s) (%s).",
                        eng_name, side, response.type)

        self.insetup = False
        self.position = start_position
        if not start_position:
            self.insetup = True
            self.position = Position(Color.GOLD, 4, BLANK_BOARD)
        self.strict_setup = strict_setup
        self.min_timeleft = min_timeleft
        self.movenumber = 1
        self.limit_winner = 1
        self.moves = []
        self.repetition_count = defaultdict(int)
        self.result = None
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
Arquivo: game.py Projeto: Janzert/AEI
    def __init__(self, gold, silver,
                 timecontrol=None,
                 start_position=None,
                 strict_setup=True,
                 min_timeleft=None):
        self.engines = (gold, silver)
        try:
            self.timecontrol = timecontrol[0]
            self.side_tc = timecontrol
        except TypeError:
            self.timecontrol = timecontrol
            self.side_tc = [timecontrol, timecontrol]
        self.reserves = [None, None]
        if timecontrol:
            for side, eng in enumerate(self.engines):
                if not self.side_tc[side]:
                    continue
                self.reserves[side] = self.side_tc[side].reserve
                eng.setoption("tcmove", self.side_tc[side].move)
                eng.setoption("tcreserve", self.side_tc[side].reserve)
                eng.setoption("tcpercent", self.side_tc[side].percent)
                eng.setoption("tcmax", self.side_tc[side].max_reserve)
                eng.setoption("tcturns", self.side_tc[side].turn_limit)
                eng.setoption("tctotal", self.side_tc[side].time_limit)
                eng.setoption("tcturntime", self.side_tc[side].max_turntime)
        for eng in self.engines:
            eng.newgame()
            if start_position:
                eng.setposition(start_position)
            resps = eng.isready()
            side = "gs" [self.engines.index(eng)]
            eng_name = eng.ident["name"]
            for response in resps:
                if response.type == "info":
                    log.info("%s (%s) info: %s", eng_name, side,
                             response.message)
                elif response.type == "log":
                    log.info("%s (%s) log: %s", eng_name, side,
                             response.message)
                else:
                    log.warn(
                        "Unexpected response while initializing %s (%s) (%s).",
                        eng_name, side, response.type)

        self.insetup = False
        self.position = start_position
        if not start_position:
            self.insetup = True
            self.position = Position(Color.GOLD, 4, BLANK_BOARD)
        self.strict_setup = strict_setup
        self.min_timeleft = min_timeleft
        self.movenumber = 1
        self.limit_winner = 1
        self.moves = []
        self.repetition_count = defaultdict(int)
        self.result = None
Exemplo n.º 5
0
 def test_contruction(self):
     p = MockEngine()
     game = Game(p, p)
     self.assertEqual(game.movenumber, 1)
     self.assertEqual(game.insetup, True)
     tc = TimeControl("30s/60s")
     game = Game(p, p, tc)
     self.assertEqual(game.timecontrol, tc)
     pos = Position(Color.GOLD, 4, BASIC_SETUP)
     game = Game(p, p, tc, pos)
     self.assertEqual(game.position, pos)
     self.assertEqual(game.insetup, False)
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
 def test_contruction(self):
     p = MockEngine()
     game = Game(p, p)
     self.assertEqual(game.movenumber, 1)
     self.assertEqual(game.insetup, True)
     tc = TimeControl("30s/60s")
     game = Game(p, p, tc)
     self.assertEqual(game.timecontrol, tc)
     pos = Position(Color.GOLD, 4, BASIC_SETUP)
     game = Game(p, p, tc, pos)
     self.assertEqual(game.position, pos)
     self.assertEqual(game.insetup, False)
     real_log = pyrimaa.game.log
     mock_log = MockLog()
     pyrimaa.game.log = mock_log
     try:
         info = MockResponse("info")
         info.message = "Test info message."
         pl = MockEngine(isready=[info])
         game = Game(pl, p)
         self.assertEqual(game.movenumber, 1)
         self.assertEqual(game.insetup, True)
         self.assertEqual(len(mock_log.info_logs), 1)
         self.assertEqual(len(mock_log.warn_logs), 0)
         self.assertIn(info.message, mock_log.info_logs[0])
         mock_log.reset()
         log = MockResponse("log")
         log.message = "Test log message."
         pl = MockEngine(isready=[log])
         game = Game(pl, p)
         self.assertEqual(game.movenumber, 1)
         self.assertEqual(game.insetup, True)
         self.assertEqual(len(mock_log.info_logs), 1)
         self.assertEqual(len(mock_log.warn_logs), 0)
         self.assertIn(log.message, mock_log.info_logs[0])
         mock_log.reset()
         invalid = MockResponse("bestmove")
         invalid.move = " "
         pl = MockEngine(isready=[invalid])
         game = Game(pl, p)
         self.assertEqual(game.movenumber, 1)
         self.assertEqual(game.insetup, True)
         self.assertEqual(len(mock_log.info_logs), 0)
         self.assertEqual(len(mock_log.warn_logs), 1)
         mock_log.reset()
     finally:
         pyrimaa.game.log = real_log
Exemplo n.º 9
0
Arquivo: game.py Projeto: Janzert/AEI
class Game(object):
    def __init__(self, gold, silver,
                 timecontrol=None,
                 start_position=None,
                 strict_setup=True,
                 min_timeleft=None):
        self.engines = (gold, silver)
        try:
            self.timecontrol = timecontrol[0]
            self.side_tc = timecontrol
        except TypeError:
            self.timecontrol = timecontrol
            self.side_tc = [timecontrol, timecontrol]
        self.reserves = [None, None]
        if timecontrol:
            for side, eng in enumerate(self.engines):
                if not self.side_tc[side]:
                    continue
                self.reserves[side] = self.side_tc[side].reserve
                eng.setoption("tcmove", self.side_tc[side].move)
                eng.setoption("tcreserve", self.side_tc[side].reserve)
                eng.setoption("tcpercent", self.side_tc[side].percent)
                eng.setoption("tcmax", self.side_tc[side].max_reserve)
                eng.setoption("tcturns", self.side_tc[side].turn_limit)
                eng.setoption("tctotal", self.side_tc[side].time_limit)
                eng.setoption("tcturntime", self.side_tc[side].max_turntime)
        for eng in self.engines:
            eng.newgame()
            if start_position:
                eng.setposition(start_position)
            resps = eng.isready()
            side = "gs" [self.engines.index(eng)]
            eng_name = eng.ident["name"]
            for response in resps:
                if response.type == "info":
                    log.info("%s (%s) info: %s", eng_name, side,
                             response.message)
                elif response.type == "log":
                    log.info("%s (%s) log: %s", eng_name, side,
                             response.message)
                else:
                    log.warn(
                        "Unexpected response while initializing %s (%s) (%s).",
                        eng_name, side, response.type)

        self.insetup = False
        self.position = start_position
        if not start_position:
            self.insetup = True
            self.position = Position(Color.GOLD, 4, BLANK_BOARD)
        self.strict_setup = strict_setup
        self.min_timeleft = min_timeleft
        self.movenumber = 1
        self.limit_winner = 1
        self.moves = []
        self.repetition_count = defaultdict(int)
        self.result = None

    def play(self):
        if self.result:
            raise RuntimeError("Tried to play a game that was already played.")
        starttime = time.time()
        while not self.position.is_end_state() or self.insetup:
            try:
                result = self.play_next_move(starttime)
                if result:
                    break
            except IllegalMove as e:
                log.info("Illegal move played: %s" % e)
                result = (self.position.color ^ 1, "i")
                break
        if not result:
            if self.position.is_goal():
                result = (0 - min(self.position.is_goal(), 0), "g")
            elif self.position.is_rabbit_loss():
                result = (0 - min(self.position.is_rabbit_loss(), 0), "e")
            else:  # immobilization
                assert len(self.position.get_steps()) == 0
                result = (self.position.color ^ 1, "m")
        self.result = result
        return result

    def play_next_move(self, starttime):
        position = self.position
        side = position.color
        engine = self.engines[side]
        tc = self.side_tc[side]
        if tc:
            if tc.time_limit:
                endtime_limit = starttime + tc.time_limit
            if engine.protocol_version == 0:
                if self.reserves[0] is not None:
                    engine.setoption("wreserve", int(self.reserves[0]))
                if self.reserves[1] is not None:
                    engine.setoption("breserve", int(self.reserves[1]))
                engine.setoption("tcmoveused", 0)
            if self.reserves[0] is not None:
                engine.setoption("greserve", int(self.reserves[0]))
            if self.reserves[1] is not None:
                engine.setoption("sreserve", int(self.reserves[1]))
            engine.setoption("moveused", 0)
        movestart = time.time()
        engine.go()
        if tc:
            timeout = movestart + tc.move + self.reserves[side]
            if tc.max_turntime and movestart + tc.max_turntime < timeout:
                timeout = movestart + tc.max_turntime
            if tc.time_limit and endtime_limit < timeout:
                timeout = endtime_limit
        else:
            timeout = None
        waittime = None
        resp = None
        stopsent = False
        stoptime = None
        if timeout and self.min_timeleft:
            stoptime = timeout - self.min_timeleft
        while True:
            now = time.time()
            if stoptime and not stopsent and now >= stoptime:
                # try and get a move before time runs out
                engine.stop()
                log.info("Engine sent stop command to prevent timeout")
                stopsent = True
            if timeout and now > timeout:
                if not stopsent:
                    engine.stop()
                break
            if timeout:
                waittime = timeout - now
                if stoptime and not stopsent and now + waittime > stoptime:
                    waittime = max(0, (stoptime - now) + 0.2)
            try:
                resp = engine.get_response(waittime)
                if resp.type == "bestmove":
                    break
                if resp.type == "info":
                    log.info("%s (%s) info: %s", engine.ident["name"],
                             "gs" [side], resp.message)
                elif resp.type == "log":
                    log.info("%s (%s) log: %s", engine.ident["name"],
                             "gs" [side], resp.message)
            except socket.timeout:
                pass
        moveend = time.time()

        if tc and moveend > timeout:
            if tc.time_limit and endtime_limit < moveend:
                return (self.limit_winner, "s")
            else:
                return (side ^ 1, "t")
        if not resp or resp.type != "bestmove": # pragma: no cover
            raise RuntimeError(
                "Stopped waiting without a timeout or a move")
        if tc:
            if not self.insetup:
                reserve_change = tc.move - (moveend - movestart)
                if reserve_change > 0:
                    # if we are adding to the reserve only apply the
                    # percentage specified by the time control
                    reserve_change *= tc.percent / 100.0
                self.reserves[side] += reserve_change
                if tc.max_reserve:
                    self.reserves[side] = min(self.reserves[side],
                                              tc.max_reserve)
        move = resp.move
        if move.lower() == "resign":
            return (side ^ 1, "r")
        self.moves.append("%d%s %s" % (self.movenumber,
                                       "gs" [position.color], move))
        if self.insetup:
            position = position.do_move_str(
                move,
                strict_checks=self.strict_setup)
        else:
            position = position.do_move_str(move)
        if position.bitBoards == self.position.bitBoards:
            raise IllegalMove("Tried move that did not change the position, %s" % move)
        self.repetition_count[position] += 1
        if self.repetition_count[position] > 2:
            raise IllegalMove("Tried move resulting in a 3rd time repetition")
        self.position = position
        if position.color == Color.GOLD:
            self.movenumber += 1
        log.debug("position:\n%s", position.board_to_str())
        for eng in self.engines:
            eng.makemove(move)
        if self.insetup and side == Color.SILVER:
            self.insetup = False
        if not self.insetup:
            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
        if tc and tc.turn_limit and self.movenumber > tc.turn_limit:
            return (limit_winner, "s")
Exemplo n.º 10
0
 def newgame(self):
     self.position = Position(Color.GOLD, 4, board.BLANK_BOARD)
     self.insetup = True
Exemplo n.º 11
0
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)
Exemplo n.º 12
0
 def newgame(self):
     self.position = Position(Color.GOLD, 4, BLANK_BOARD)
     self.insetup = True
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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
Exemplo n.º 15
0
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
Exemplo n.º 16
0
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
Exemplo n.º 17
0
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
Exemplo n.º 18
0
class Game(object):
    def __init__(self,
                 gold,
                 silver,
                 timecontrol=None,
                 start_position=None,
                 strict_setup=True,
                 min_timeleft=None):
        self.engines = (gold, silver)
        try:
            self.timecontrol = timecontrol[0]
            self.side_tc = timecontrol
        except TypeError:
            self.timecontrol = timecontrol
            self.side_tc = [timecontrol, timecontrol]
        self.reserves = [None, None]
        if timecontrol:
            for side, eng in enumerate(self.engines):
                if not self.side_tc[side]:
                    continue
                self.reserves[side] = self.side_tc[side].reserve
                eng.setoption("tcmove", self.side_tc[side].move)
                eng.setoption("tcreserve", self.side_tc[side].reserve)
                eng.setoption("tcpercent", self.side_tc[side].percent)
                eng.setoption("tcmax", self.side_tc[side].max_reserve)
                eng.setoption("tcturns", self.side_tc[side].turn_limit)
                eng.setoption("tctotal", self.side_tc[side].time_limit)
                eng.setoption("tcturntime", self.side_tc[side].max_turntime)
        for eng in self.engines:
            eng.newgame()
            if start_position:
                eng.setposition(start_position)
            resps = eng.isready()
            side = "gs"[self.engines.index(eng)]
            eng_name = eng.ident["name"]
            for response in resps:
                if response.type == "info":
                    log.info("%s (%s) info: %s", eng_name, side,
                             response.message)
                elif response.type == "log":
                    log.info("%s (%s) log: %s", eng_name, side,
                             response.message)
                else:
                    log.warn(
                        "Unexpected response while initializing %s (%s) (%s).",
                        eng_name, side, response.type)

        self.insetup = False
        self.position = start_position
        if not start_position:
            self.insetup = True
            self.position = Position(Color.GOLD, 4, BLANK_BOARD)
        self.strict_setup = strict_setup
        self.min_timeleft = min_timeleft
        self.movenumber = 1
        self.limit_winner = 1
        self.moves = []
        self.repetition_count = defaultdict(int)
        self.result = None

    def play(self):
        if self.result:
            raise RuntimeError("Tried to play a game that was already played.")
        starttime = time.time()
        while not self.position.is_end_state() or self.insetup:
            try:
                result = self.play_next_move(starttime)
                if result:
                    break
            except IllegalMove as e:
                log.info("Illegal move played: %s" % e)
                result = (self.position.color ^ 1, "i")
                break
        if not result:
            if self.position.is_goal():
                result = (0 - min(self.position.is_goal(), 0), "g")
            elif self.position.is_rabbit_loss():
                result = (0 - min(self.position.is_rabbit_loss(), 0), "e")
            else:  # immobilization
                assert len(self.position.get_steps()) == 0
                result = (self.position.color ^ 1, "m")
        self.result = result
        return result

    def play_next_move(self, starttime):
        position = self.position
        side = position.color
        engine = self.engines[side]
        tc = self.side_tc[side]
        if tc:
            if tc.time_limit:
                endtime_limit = starttime + tc.time_limit
            if engine.protocol_version == 0:
                if self.reserves[0] is not None:
                    engine.setoption("wreserve", int(self.reserves[0]))
                if self.reserves[1] is not None:
                    engine.setoption("breserve", int(self.reserves[1]))
                engine.setoption("tcmoveused", 0)
            if self.reserves[0] is not None:
                engine.setoption("greserve", int(self.reserves[0]))
            if self.reserves[1] is not None:
                engine.setoption("sreserve", int(self.reserves[1]))
            engine.setoption("moveused", 0)
        movestart = time.time()
        engine.go()
        if tc:
            timeout = movestart + tc.move + self.reserves[side]
            if tc.max_turntime and movestart + tc.max_turntime < timeout:
                timeout = movestart + tc.max_turntime
            if tc.time_limit and endtime_limit < timeout:
                timeout = endtime_limit
        else:
            timeout = None
        waittime = None
        resp = None
        stopsent = False
        stoptime = None
        if timeout and self.min_timeleft:
            stoptime = timeout - self.min_timeleft
        while True:
            now = time.time()
            if stoptime and not stopsent and now >= stoptime:
                # try and get a move before time runs out
                engine.stop()
                log.info("Engine sent stop command to prevent timeout")
                stopsent = True
            if timeout and now > timeout:
                if not stopsent:
                    engine.stop()
                break
            if timeout:
                waittime = timeout - now
                if stoptime and not stopsent and now + waittime > stoptime:
                    waittime = max(0, (stoptime - now) + 0.2)
            try:
                resp = engine.get_response(waittime)
                if resp.type == "bestmove":
                    break
                if resp.type == "info":
                    log.info("%s (%s) info: %s", engine.ident["name"],
                             "gs"[side], resp.message)
                elif resp.type == "log":
                    log.info("%s (%s) log: %s", engine.ident["name"],
                             "gs"[side], resp.message)
            except socket.timeout:
                pass
        moveend = time.time()

        if tc and moveend > timeout:
            if tc.time_limit and endtime_limit < moveend:
                return (self.limit_winner, "s")
            else:
                return (side ^ 1, "t")
        if not resp or resp.type != "bestmove":  # pragma: no cover
            raise RuntimeError("Stopped waiting without a timeout or a move")
        if tc:
            if not self.insetup:
                reserve_change = tc.move - (moveend - movestart)
                if reserve_change > 0:
                    # if we are adding to the reserve only apply the
                    # percentage specified by the time control
                    reserve_change *= tc.percent / 100.0
                self.reserves[side] += reserve_change
                if tc.max_reserve:
                    self.reserves[side] = min(self.reserves[side],
                                              tc.max_reserve)
        move = resp.move
        if move.lower() == "resign":
            return (side ^ 1, "r")
        self.moves.append("%d%s %s" %
                          (self.movenumber, "gs"[position.color], move))
        if self.insetup:
            position = position.do_move_str(move,
                                            strict_checks=self.strict_setup)
        else:
            position = position.do_move_str(move)
        if position.bitBoards == self.position.bitBoards:
            raise IllegalMove(
                "Tried move that did not change the position, %s" % move)
        self.repetition_count[position] += 1
        if self.repetition_count[position] > 2:
            raise IllegalMove("Tried move resulting in a 3rd time repetition")
        self.position = position
        if position.color == Color.GOLD:
            self.movenumber += 1
        log.debug("position:\n%s", position.board_to_str())
        for eng in self.engines:
            eng.makemove(move)
        if self.insetup and side == Color.SILVER:
            self.insetup = False
        if not self.insetup:
            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
        if tc and tc.turn_limit and self.movenumber > tc.turn_limit:
            return (limit_winner, "s")
Exemplo n.º 19
0
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)
Exemplo n.º 20
0
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