Example #1
0
 def test_socketengine(self):
     path = os.path.dirname(__file__)
     adapter = os.path.join(path, "socketadapter.py")
     eng = aei.get_engine("socket", adapter)
     self.assertIsInstance(eng, aei.SocketEngine)
     self._check_engine(eng)
     eng = aei.get_engine("socket", adapter, "aei")
     self.assertIsInstance(eng, aei.SocketEngine)
     self._check_engine(eng)
     eng = aei.get_engine("2008cc", adapter + " --legacy")
     self._check_engine(eng)
Example #2
0
 def test_socketengine(self):
     path = os.path.dirname(__file__)
     adapter = os.path.join(path, "socketadapter.py")
     eng = aei.get_engine("socket", adapter)
     self.assertIsInstance(eng, aei.SocketEngine)
     self._check_engine(eng)
     eng = aei.get_engine("socket", adapter, "aei")
     self.assertIsInstance(eng, aei.SocketEngine)
     self._check_engine(eng)
     eng = aei.get_engine("2008cc", adapter + " --legacy")
     self._check_engine(eng)
Example #3
0
def run_bot(bot, config, global_options):
    cmdline = config.get(bot['name'], "cmdline")
    if config.has_option(bot['name'], "communication_method"):
        com_method = config.get(bot['name'], "communication_method").lower()
    else:
        com_method = "stdio"
    eng_com = aei.get_engine(com_method, cmdline, "roundrobin.aei")
    engine = aei.EngineController(eng_com)
    for option, value in global_options:
        engine.setoption(option, value)
    for name, value in config.items(bot['name']):
        if name.startswith("bot_"):
            engine.setoption(name[4:], value)
    return engine
Example #4
0
def run_bot(bot, config, global_options):
    cmdline = config.get(bot['name'], "cmdline")
    if config.has_option(bot['name'], "communication_method"):
        com_method = config.get(bot['name'], "communication_method").lower()
    else:
        com_method = "stdio"
    eng_com = aei.get_engine(com_method, cmdline, "roundrobin.aei")
    engine = aei.EngineController(eng_com)
    for option, value in global_options:
        engine.setoption(option, value)
    for name, value in config.items(bot['name']):
        if name.startswith("bot_"):
            engine.setoption(name[4:], value)
    return engine
Example #5
0
def main(args=None):
    try:
        cfg = get_config(args)
    except SystemExit as exc:
        return exc.code

    with open(cfg.position_file, 'r') as pfile:
        plines = pfile.readlines()
    try:
        have_board, start = parse_start(plines, cfg.move_number)
    except ParseError:
        print "File %s does not appear to be a board or move list." % (
            cfg.position_file, )
        return 0

    if cfg.strict_checks:
        print "Enabling full legality checking on moves"

    if cfg.strict_setup is not None:
        if cfg.strict_setup:
            print "Enabling full legality checking on setup"
        else:
            print "Disabling full legality checking on setup"

    eng_com = aei.get_engine(cfg.com_method, cfg.enginecmd, "analyze.aei")
    try:
        eng = aei.EngineController(eng_com)
    except aei.EngineException as exc:
        print exc.message
        print "Bot probably did not start. Is the command line correct?"
        eng_com.cleanup()
        return 1
    try:
        for option, value in cfg.bot_options:
            eng.setoption(option, value)

        eng.newgame()
        if have_board:
            pos = start
            eng.setposition(pos)
        else:
            pos = board.Position(board.Color.GOLD, 4, board.BLANK_BOARD)
            for mnum, move in enumerate(start):
                move = move[3:]
                if mnum < 2 and cfg.strict_setup is not None:
                    do_checks = cfg.strict_setup
                else:
                    do_checks = cfg.strict_checks
                pos = pos.do_move_str(move, do_checks)
                eng.makemove(move)
        print pos.board_to_str()

        for option, value in cfg.post_options:
            eng.setoption(option, value)

        if cfg.search_position:
            eng.go()

        while True:
            try:
                resp = eng.get_response(10)
                if resp.type == "info":
                    print resp.message
                elif resp.type == "log":
                    print "log: %s" % resp.message
                elif resp.type == "bestmove":
                    print "bestmove: %s" % resp.move
                    break
            except socket.timeout:
                if not cfg.search_position:
                    break

    finally:
        eng.quit()
        stop_waiting = time.time() + 20
        while time.time() < stop_waiting:
            try:
                resp = eng.get_response(1)
                if resp.type == "info":
                    print resp.message
                elif resp.type == "log":
                    print "log: %s" % (resp.message)
            except socket.timeout:
                try:
                    eng.quit()
                except IOError:
                    pass
            if not eng.is_running():
                break
        eng.cleanup()

    return 0
Example #6
0
def main(args=sys.argv):
    if len(args) < 2:
        print "usage: analyze <board or movelist file> [move to analyze]"
        sys.exit()

    have_board = False
    pfile = open(args[1], 'r')
    plines = pfile.readlines()
    plines = [l.strip() for l in plines]
    plines = [l for l in plines if l]
    while plines and not plines[0][0].isalnum():
        del plines[0]
    if not plines:
        print "File %s does not appear to be a board or move list." % (args[1],)
        sys.exit()
    if len(plines) < 2 or plines[1][0] != '+':
        have_board = False
        if len(args) > 2:
            stop_move = args[2]
        else:
            stop_move = None
        move_list = []
        while plines and plines[0][0].isdigit():
            move = plines.pop(0)
            if stop_move and move.startswith(stop_move):
                break
            move_list.append(move)
    else:
        movenum, pos = board.parse_long_pos(plines)
        have_board = True

    pfile.close()

    config = SafeConfigParser()
    if config.read("analyze.cfg") != ["analyze.cfg"]:
        print "Could not open 'analyze.cfg'"
        sys.exit(1)

    strict_checks = False
    if config.has_option("global", "strict_checks"):
        strict_checks = config.getboolean("global", "strict_checks")
        if strict_checks:
            print "Enabling full legality checking on moves"

    strict_setup = None
    if config.has_option("global", "strict_setup"):
        strict_setup = config.getboolean("global", "strict_setup")
        if strict_setup:
            print "Enabling full legality checking on setup"
        else:
            print "Disabling full legality checking on setup"


    bot_section = config.get("global", "default_engine")
    if config.has_option(bot_section, "communication_method"):
        com_method = config.get(bot_section, "communication_method").lower()
    else:
        com_method = "stdio"
    enginecmd = config.get(bot_section, "cmdline")

    eng_com = aei.get_engine(com_method, enginecmd, log)
    eng = aei.EngineController(eng_com)

    for option in config.options(bot_section):
        if option.startswith("bot_"):
            value = config.get(bot_section, option)
            eng.setoption(option[4:], value)

    eng.newgame()
    if have_board:
        eng.setposition(pos)
    else:
        pos = board.Position(board.Color.GOLD, 4, board.BLANK_BOARD)
        for mnum, move in enumerate(move_list):
            move = move[3:]
            if mnum < 2 and setup_checks is not None:
                do_checks = setup_checks
            else:
                do_checks = strict_checks
            pos = pos.do_move_str(move, do_checks)
            eng.makemove(move)
    print pos.board_to_str()

    for option in config.options(bot_section):
        if option.startswith("post_pos_"):
            value = config.get(bot_section, option)
            eng.setoption(option[9:], value)

    search_position = True
    if config.has_option("global", "search_position"):
        sp_str = config.get("global", "search_position")
        search_position = not (sp_str.lower() in ["false", "0", "no"])
    if search_position:
        eng.go()

    while True:
        try:
            resp = eng.get_response(10)
            if resp.type == "info":
                print resp.message
            elif resp.type == "log":
                print "log: %s" % resp.message
            elif resp.type == "bestmove":
                print "bestmove: %s" % resp.move
                break
        except socket.timeout:
            if not search_position:
                break

    eng.quit()
    stop_waiting = time.time() + 20
    while time.time() < stop_waiting:
        try:
            resp = eng.get_response(1)
            if resp.type == "info":
                print resp.message
            elif resp.type == "log":
                print "log: %s" % (resp.message)
        except socket.timeout:
            try:
                eng.quit()
            except IOError:
                pass
        if eng.engine.proc.poll() is not None:
            break
    eng.cleanup()
Example #7
0
def run_game(options, config):
    run_dir = config.get("global", "run_dir")
    if not os.path.exists(run_dir):
        log.warn(
            "Run file directory '%s' not found, attempting to create it." %
            (run_dir))
        os.makedirs(run_dir)
    bot_count = how_many_bots(run_dir)
    if bot_count >= config.getint("global", "max_bots"):
        log.info(
            "Max number of bot limit %d reached, need to wait until some bots finish."
            % (config.getint("global", "max_bots")))
        return

    if options['bot']:
        bot_section = options['bot']
    else:
        bot_section = config.get("global", "default_engine")
    if config.has_option(bot_section, "communication_method"):
        com_method = config.get(bot_section, "communication_method").lower()
    else:
        com_method = "stdio"
    enginecmd = config.get(bot_section, "cmdline")

    gameid_or_opponent = options['against']
    unknowns_caught = 0
    bot_crashes = 0
    while True:
        try:
            engine_com = aei.get_engine(com_method,
                                        enginecmd,
                                        logname="gameroom.aei")
            engine_ctl = aei.EngineController(engine_com)
        except OSError, exc:
            log.error("Could not start the engine; exception thrown: %s", exc)
            return 1

        try:
            for option in config.options(bot_section):
                if option.startswith("bot_"):
                    value = config.get(bot_section, option)
                    engine_ctl.setoption(option[4:], value)
                    log.info("Setting bot option %s = %s", option[4:], value)
            resps = engine_ctl.isready()
            for response in resps:
                log_response(response, "while sending bot options")

            try:
                bot_username = config.get(bot_section, "username")
                bot_password = config.get(bot_section, "password")
            except NoOptionError:
                try:
                    bot_username = config.get("global", "username")
                    bot_password = config.get("global", "password")
                except NoOptionError:
                    log.error("Could not find username/password in config.")
                    return 1
            bot_greeting = config.get(bot_section, "greeting")

            gameroom = GameRoom(config.get("global", "gameroom_url"))
            gameroom.login(bot_username, bot_password)
            side = options['side']
            if side == "g":
                side = "w"
            elif side == "s":
                side = "b"
            table = None
            if gameid_or_opponent == "":
                log.info("Starting a new game")
                if side == "":
                    side = 'b'
                timecontrol = config.get(bot_section, "timecontrol")
                rated = config.getboolean(bot_section, "rated")
                log.info("Will play on side %s, using timecontrol %s" %
                         (side, timecontrol))
                table = gameroom.newgame(side, timecontrol, rated)
            else:
                # look through my games for correct opponent and side
                games = gameroom.mygames()
                for game in games:
                    if (gameid_or_opponent == game['player'].lower()
                            or gameid_or_opponent == game['gid']):
                        if (side == "" or side == game['side']
                                and not already_playing(
                                    run_dir, game['gid'], game['side'])):
                            table = Table(gameroom, game)
                            log.info("Found in progress game")
                            break
                if table == None:
                    games = gameroom.opengames()
                    for game in games:
                        if (gameid_or_opponent == game['player'].lower()
                                or gameid_or_opponent == game['gid']):
                            if (side == "" or side == game['side']
                                    and not already_playing(
                                        run_dir, game['gid'], game['side'])):
                                table = Table(gameroom, game)
                                log.info("Found game to join")
                                break
                if table == None:
                    log.error("Could not find game against %s with side '%s'",
                              gameid_or_opponent, side)
                    engine_ctl.quit()
                    engine_ctl.cleanup()
                    return 1
            # Set the game to play in to current game id in case of a restart
            gameid_or_opponent = table.gid

            if options['against'] != "":
                joinmsg = "Joined game gid=%s side=%s; against %s" % (
                    table.gid, table.side, options['against'])
            else:
                joinmsg = "Created game gid=%s side=%s; waiting for opponent"\
                        % (table.gid, table.side)
            log.info(joinmsg)
            if console is None:
                print joinmsg
            # force the std streams to flush so the bot starter script used
            # on the arimaa.com server can pick up the join message
            sys.stdout.flush()
            sys.stderr.flush()

            if config.has_option(bot_section, "ponder"):
                table.ponder = config.getboolean(bot_section, "ponder")
                if table.ponder:
                    log.info("Set pondering on.")
                else:
                    log.info("Set pondering off.")
            else:
                table.ponder = False
            if config.has_option("global", "min_move_time"):
                table.min_move_time = config.getint("global", "min_move_time")
                log.info("Set minimum move time to %d seconds.",
                         table.min_move_time)
            else:
                table.min_move_time = 5
            if config.has_option("global", "min_time_left"):
                table.min_timeleft = config.getint("global", "min_time_left")
                log.info("Setting emergency stop time to %d seconds" %
                         table.min_timeleft)
            else:
                table.min_timeleft = 5
        except:
            shutdown_engine(engine_ctl)
            raise

        try:
            try:
                log.info("Joining game on %s side", table.side)
                table.reserveseat()
                table.sitdown()
                table.updatestate()
                engine_ctl.setoption("rated", table.state.get('rated', 1))
                try:
                    touch_run_file(run_dir,
                                   "%s%s.bot" % (table.gid, table.side))
                    time.sleep(1)  # Give the server a small break.
                    log.info("Starting play")
                    table.playgame(engine_ctl, bot_greeting,
                                   options['onemove'])
                finally:
                    log.info("Leaving game")
                    remove_run_file(run_dir,
                                    "%s%s.bot" % (table.gid, table.side))
                    table.leave()
                break
            finally:
                shutdown_engine(engine_ctl)
        except EngineCrashException, exc:
            bot_crashes += 1
            if bot_crashes >= 1000:
                log.error("Bot engine crashed 1000 times, giving up.")
                return 2
            log.error("Bot engine crashed (%s), restarting.", exc.args[0])
            time.sleep(1)
Example #8
0
pfile.close()

config = SafeConfigParser()
if config.read("analyze.cfg") != ["analyze.cfg"]:
    print "Could not open 'analyze.cfg'"
    sys.exit(1)

bot_section = config.get("global", "default_engine")
if config.has_option(bot_section, "communication_method"):
    com_method = config.get(bot_section, "communication_method").lower()
else:
    com_method = "stdio"
enginecmd = config.get(bot_section, "cmdline")

eng_com = aei.get_engine(com_method, enginecmd, log)
eng = aei.EngineController(eng_com)

for option in config.options(bot_section):
    if option.startswith("bot_"):
        value = config.get(bot_section, option)
        eng.setoption(option[4:], value)

eng.newgame()
if have_board:
    eng.setposition(pos)
else:
    pos = board.Position(board.Color.GOLD, 4, board.BLANK_BOARD)
    for move in move_list:
        move = move[3:]
        pos = pos.do_move_str(move)
Example #9
0
def main(args):
    """Main entry for script.

    Parses the command line. Reads 'gameroom.cfg' for the configuration.
    Starts the engine and gives it any initial configuration. Joins or creates
    the specified game. Then finally controls the engine passing it the game
    information and sending engine responses back to the server.

    """
    try:
        options = parseargs(args)
    except ValueError:
        print "Command not understood '%s'" % (" ".join(args[1:]))
        print
        print __doc__
        sys.exit(2)

    config = SafeConfigParser()
    try:
        config.readfp(open("gameroom.cfg", "rU"))
    except IOError:
        print "Could not open 'gameroom.cfg'"
        print "this file must be readable and contain the configuration"
        print "for connecting to the gameroom."
        sys.exit(1)

    aeilog = logging.getLogger("gameroom.aei")
    if config.has_section("Logging"):
        logdir = config.get("Logging", "directory")
        if not os.path.exists(logdir):
            print "Log directory '%s' not found, attempting to create it." % (logdir)
            os.makedirs(logdir)
        logfilename = "%s-%s.log" % (time.strftime("%Y%m%d-%H%M"), str(os.getpid()))
        logfilename = os.path.join(logdir, logfilename)
        if config.has_option("Logging", "level"):
            loglevel = str_loglevel(config.get("Logging", "level"))
        else:
            loglevel = logging.WARN

        logging.basicConfig(
            level=loglevel,
            filename=logfilename,
            datefmt="%Y-%m-%d %H:%M:%S",
            format="%(asctime)s %(levelname)s:%(name)s:%(message)s",
        )

        if config.has_option("Logging", "console") and config.getboolean("Logging", "console"):
            global console
            console = logging.StreamHandler()
            if config.has_option("Logging", "console_level"):
                conlevel = str_loglevel(config.get("Logging", "console_level"))
            else:
                conlevel = logging.INFO
            console.setLevel(conlevel)
            logging.getLogger("").addHandler(console)

        if config.has_option("Logging", "net_level"):
            netlevel = str_loglevel(config.get("Logging", "net_level"))
            netlog.setLevel(netlevel)

        if config.has_option("Logging", "engine_level"):
            enginelevel = str_loglevel(config.get("Logging", "engine_level"))
            enginelog.setLevel(enginelevel)

        if config.has_option("Logging", "aei_level"):
            aeilog.setLevel(str_loglevel(config.get("Logging", "aei_level")))

        positionlog.setLevel(logging.ERROR)
        if config.has_option("Logging", "log_position") and config.getboolean("Logging", "log_position"):
            positionlog.setLevel(logging.INFO)

    run_dir = config.get("global", "run_dir")
    if not os.path.exists(run_dir):
        log.warn("Run file directory '%s' not found, attempting to create it." % (run_dir))
        os.makedirs(run_dir)
    bot_count = how_many_bots(run_dir)
    if bot_count >= config.getint("global", "max_bots"):
        log.info(
            "Max number of bot limit %d reached, need to wait until some bots finish."
            % (config.getint("global", "max_bots"))
        )
        return

    bot_section = config.get("global", "default_engine")
    if config.has_option(bot_section, "communication_method"):
        com_method = config.get(bot_section, "communication_method").lower()
    else:
        com_method = "stdio"
    enginecmd = config.get(bot_section, "cmdline")

    gameid_or_opponent = options["against"]
    unknowns_caught = 0
    while True:
        try:
            engine_com = aei.get_engine(com_method, enginecmd, log=aeilog)
            engine_ctl = aei.EngineController(engine_com)
        except OSError, exc:
            log.error("Could not start the engine; exception thrown: %s", exc)
            sys.exit(1)

        try:
            for option in config.options(bot_section):
                if option.startswith("bot_"):
                    value = config.get(bot_section, option)
                    engine_ctl.setoption(option[4:], value)
                    log.info("Setting bot option %s = %s", option[4:], value)
            engine_ctl.isready()

            bot_username = config.get(bot_section, "username")
            bot_password = config.get(bot_section, "password")
            bot_greeting = config.get(bot_section, "greeting")

            gameroom = GameRoom(config.get("global", "gameroom_url"))
            gameroom.login(bot_username, bot_password)
            side = options["side"]
            if side == "g":
                side = "w"
            elif side == "s":
                side = "b"
            table = None
            if gameid_or_opponent == "":
                log.info("Starting a new game")
                if side == "":
                    side = "b"
                timecontrol = config.get(bot_section, "timecontrol")
                rated = config.getboolean(bot_section, "rated")
                log.info("Will play on side %s, using timecontrol %s" % (side, timecontrol))
                table = gameroom.newgame(side, timecontrol, rated)
            else:
                # look through my games for correct opponent and side
                games = gameroom.mygames()
                for game in games:
                    if gameid_or_opponent == game["player"].lower() or gameid_or_opponent == game["gid"]:
                        if (
                            side == ""
                            or side == game["side"]
                            and not already_playing(run_dir, game["gid"], game["side"])
                        ):
                            table = Table(gameroom, game)
                            log.info("Found in progress game")
                            break
                if table == None:
                    games = gameroom.opengames()
                    for game in games:
                        if gameid_or_opponent == game["player"].lower() or gameid_or_opponent == game["gid"]:
                            if (
                                side == ""
                                or side == game["side"]
                                and not already_playing(run_dir, game["gid"], game["side"])
                            ):
                                table = Table(gameroom, game)
                                log.info("Found game to join")
                                break
                if table == None:
                    log.error("Could not find game against %s with side '%s'", gameid_or_opponent, side)
                    engine_ctl.quit()
                    engine_ctl.cleanup()
                    sys.exit(1)
            # Set the game to play in to current game id in case of a restart
            gameid_or_opponent = table.gid

            if options["against"] != "":
                joinmsg = "Joined game gid=%s side=%s; against %s" % (table.gid, table.side, options["against"])
            else:
                joinmsg = "Created game gid=%s side=%s; waiting for opponent" % (table.gid, table.side)
            log.info(joinmsg)
            if console is None:
                print joinmsg
            # force the std streams to flush so the bot starter script used
            # on the arimaa.com server can pick up the join message
            sys.stdout.flush()
            sys.stderr.flush()

            if config.has_option(bot_section, "ponder"):
                table.ponder = config.getboolean(bot_section, "ponder")
                if table.ponder:
                    log.info("Set pondering on.")
                else:
                    log.info("Set pondering off.")
            else:
                table.ponder = False
            if config.has_option("global", "min_move_time"):
                table.min_move_time = config.getint("global", "min_move_time")
                log.info("Set minimum move time to %d seconds.", table.min_move_time)
            else:
                table.min_move_time = 5
            if config.has_option("global", "min_time_left"):
                table.min_timeleft = config.getint("global", "min_time_left")
                log.info("Setting emergency stop time to %d seconds" % table.min_timeleft)
            else:
                table.min_timeleft = 5
        except:
            shutdown_engine(engine_ctl)
            raise

        try:
            try:
                log.info("Joining game on %s side", table.side)
                table.reserveseat()
                table.sitdown()
                table.updatestate()
                engine_ctl.setoption("rated", table.state.get("rated", 1))
                try:
                    touch_run_file(run_dir, "%s%s.bot" % (table.gid, table.side))
                    time.sleep(1)  # Give the server a small break.
                    log.info("Starting play")
                    table.playgame(engine_ctl, bot_greeting, options["onemove"])
                finally:
                    log.info("Leaving game")
                    remove_run_file(run_dir, "%s%s.bot" % (table.gid, table.side))
                    table.leave()
                break
            finally:
                shutdown_engine(engine_ctl)
        except (KeyboardInterrupt, SystemExit):
            raise
        except EngineCrashException, exc:
            log.error("Bot engine crashed (%s), restarting.", exc.args[0])
            time.sleep(1)
Example #10
0
 def test_stdioengine(self):
     eng = aei.get_engine("stdio", "simple_engine")
     self.assertIsInstance(eng, aei.StdioEngine)
     self._check_engine(eng)
     eng = aei.get_engine("stdio", "simple_engine", "aei")
     self._check_engine(eng)
Example #11
0
def main(args=None):
    try:
        cfg = get_config(args)
    except SystemExit as exc:
        return exc.code

    with open(cfg.position_file, 'r') as pfile:
        plines = pfile.readlines()
    try:
        have_board, start = parse_start(plines, cfg.move_number)
    except ParseError:
        print "File %s does not appear to be a board or move list." % (
            cfg.position_file,
        )
        return 0

    if cfg.strict_checks:
        print "Enabling full legality checking on moves"

    if cfg.strict_setup is not None:
        if cfg.strict_setup:
            print "Enabling full legality checking on setup"
        else:
            print "Disabling full legality checking on setup"

    eng_com = aei.get_engine(cfg.com_method, cfg.enginecmd, "analyze.aei")
    try:
        eng = aei.EngineController(eng_com)
    except aei.EngineException as exc:
        print exc.message
        print "Bot probably did not start. Is the command line correct?"
        eng_com.cleanup()
        return 1
    try:
        for option, value in cfg.bot_options:
            eng.setoption(option, value)

        eng.newgame()
        if have_board:
            pos = start
            eng.setposition(pos)
        else:
            pos = board.Position(board.Color.GOLD, 4, board.BLANK_BOARD)
            for mnum, full_move in enumerate(start):
                move = full_move[3:]
                if mnum < 2 and cfg.strict_setup is not None:
                    do_checks = cfg.strict_setup
                else:
                    do_checks = cfg.strict_checks
                try:
                    pos = pos.do_move_str(move, do_checks)
                except board.IllegalMove as exc:
                    print "Illegal move found \"%s\", %s" % (full_move, exc)
                    return 1
                eng.makemove(move)
        print pos.board_to_str()

        for option, value in cfg.post_options:
            eng.setoption(option, value)

        if cfg.search_position:
            eng.go()

        while True:
            try:
                resp = eng.get_response(10)
                if resp.type == "info":
                    print resp.message
                elif resp.type == "log":
                    print "log: %s" % resp.message
                elif resp.type == "bestmove":
                    print "bestmove: %s" % resp.move
                    break
            except socket.timeout:
                if not cfg.search_position:
                    break

    finally:
        eng.quit()
        stop_waiting = time.time() + 20
        while time.time() < stop_waiting:
            try:
                resp = eng.get_response(1)
                if resp.type == "info":
                    print resp.message
                elif resp.type == "log":
                    print "log: %s" % (resp.message)
            except socket.timeout:
                try:
                    eng.quit()
                except IOError:
                    pass
            if not eng.is_running():
                break
        eng.cleanup()

    return 0
Example #12
0
 def test_stdioengine(self):
     eng = aei.get_engine("stdio", "simple_engine")
     self.assertIsInstance(eng, aei.StdioEngine)
     self._check_engine(eng)
     eng = aei.get_engine("stdio", "simple_engine", "aei")
     self._check_engine(eng)
Example #13
0
def run_game(options, config):
    run_dir = config.get("global", "run_dir")
    if not os.path.exists(run_dir):
        log.warn("Run file directory '%s' not found, attempting to create it."
                 % (run_dir))
        os.makedirs(run_dir)
    bot_count = how_many_bots(run_dir)
    if bot_count >= config.getint("global", "max_bots"):
        log.info(
            "Max number of bot limit %d reached, need to wait until some bots finish."
            % (config.getint("global", "max_bots")))
        return

    if options['bot']:
        bot_section = options['bot']
    else:
        bot_section = config.get("global", "default_engine")
    if config.has_option(bot_section, "communication_method"):
        com_method = config.get(bot_section, "communication_method").lower()
    else:
        com_method = "stdio"
    enginecmd = config.get(bot_section, "cmdline")

    gameid_or_opponent = options['against']
    unknowns_caught = 0
    bot_crashes = 0
    while True:
        try:
            engine_com = aei.get_engine(com_method, enginecmd,
                                        logname="gameroom.aei")
            engine_ctl = aei.EngineController(engine_com)
        except OSError, exc:
            log.error("Could not start the engine; exception thrown: %s", exc)
            return 1

        try:
            for option in config.options(bot_section):
                if option.startswith("bot_"):
                    value = config.get(bot_section, option)
                    engine_ctl.setoption(option[4:], value)
                    log.info("Setting bot option %s = %s", option[4:], value)
            resps = engine_ctl.isready()
            for response in resps:
                log_response(response, "while sending bot options")

            try:
                bot_username = config.get(bot_section, "username")
                bot_password = config.get(bot_section, "password")
            except NoOptionError:
                try:
                    bot_username = config.get("global", "username")
                    bot_password = config.get("global", "password")
                except NoOptionError:
                    log.error("Could not find username/password in config.")
                    return 1
            bot_greeting = config.get(bot_section, "greeting")

            gameroom = GameRoom(config.get("global", "gameroom_url"))
            gameroom.login(bot_username, bot_password)
            side = options['side']
            if side == "g":
                side = "w"
            elif side == "s":
                side = "b"
            table = None
            if gameid_or_opponent == "":
                log.info("Starting a new game")
                if side == "":
                    side = 'b'
                timecontrol = config.get(bot_section, "timecontrol")
                rated = config.getboolean(bot_section, "rated")
                log.info("Will play on side %s, using timecontrol %s" %
                         (side, timecontrol))
                table = gameroom.newgame(side, timecontrol, rated)
            else:
                # look through my games for correct opponent and side
                games = gameroom.mygames()
                for game in games:
                    if (gameid_or_opponent == game['player'].lower() or
                        gameid_or_opponent == game['gid']):
                        if (side == "" or
                            side == game['side'] and not already_playing(
                                run_dir, game['gid'], game['side'])):
                            table = Table(gameroom, game)
                            log.info("Found in progress game")
                            break
                if table == None:
                    games = gameroom.opengames()
                    for game in games:
                        if (gameid_or_opponent == game['player'].lower() or
                            gameid_or_opponent == game['gid']):
                            if (side == "" or
                                side == game['side'] and not already_playing(
                                    run_dir, game['gid'], game['side'])):
                                table = Table(gameroom, game)
                                log.info("Found game to join")
                                break
                if table == None:
                    log.error("Could not find game against %s with side '%s'",
                              gameid_or_opponent, side)
                    engine_ctl.quit()
                    engine_ctl.cleanup()
                    return 1
            # Set the game to play in to current game id in case of a restart
            gameid_or_opponent = table.gid

            if options['against'] != "":
                joinmsg = "Joined game gid=%s side=%s; against %s" % (
                    table.gid, table.side, options['against']
                )
            else:
                joinmsg = "Created game gid=%s side=%s; waiting for opponent"\
                        % (table.gid, table.side)
            log.info(joinmsg)
            if console is None:
                print joinmsg
            # force the std streams to flush so the bot starter script used
            # on the arimaa.com server can pick up the join message
            sys.stdout.flush()
            sys.stderr.flush()

            if config.has_option(bot_section, "ponder"):
                table.ponder = config.getboolean(bot_section, "ponder")
                if table.ponder:
                    log.info("Set pondering on.")
                else:
                    log.info("Set pondering off.")
            else:
                table.ponder = False
            if config.has_option("global", "min_move_time"):
                table.min_move_time = config.getint("global", "min_move_time")
                log.info("Set minimum move time to %d seconds.",
                         table.min_move_time)
            else:
                table.min_move_time = 5
            if config.has_option("global", "min_time_left"):
                table.min_timeleft = config.getint("global", "min_time_left")
                log.info("Setting emergency stop time to %d seconds" %
                         table.min_timeleft)
            else:
                table.min_timeleft = 5
        except:
            shutdown_engine(engine_ctl)
            raise

        try:
            try:
                log.info("Joining game on %s side", table.side)
                table.reserveseat()
                table.sitdown()
                table.updatestate()
                engine_ctl.setoption("rated", table.state.get('rated', 1))
                try:
                    touch_run_file(run_dir, "%s%s.bot" %
                                   (table.gid, table.side))
                    time.sleep(1)  # Give the server a small break.
                    log.info("Starting play")
                    table.playgame(engine_ctl, bot_greeting, options['onemove'])
                finally:
                    log.info("Leaving game")
                    remove_run_file(run_dir, "%s%s.bot" %
                                    (table.gid, table.side))
                    table.leave()
                break
            finally:
                shutdown_engine(engine_ctl)
        except EngineCrashException, exc:
            bot_crashes += 1
            if bot_crashes >= 1000:
                log.error("Bot engine crashed 1000 times, giving up.")
                return 2
            log.error("Bot engine crashed (%s), restarting.", exc.args[0])
            time.sleep(1)