def test_generate_steps(self): move, pos = board.parse_long_pos(CHECK_TRAP_STEP) single_steps = pos.get_single_steps() step_tuples = [s for s, b in single_steps] step_tuples.sort() expected_single = [ (1, 9), (2, 10), (3, 11), (4, 12), (5, 13), (6, 7), (8, 9), (8, 16), (14, 13), (14, 15), (14, 22), (17, 9), (17, 16), (17, 18), (17, 25), (23, 22), (23, 31), (28, 20), (28, 27), (29, 21), (29, 30), (34, 26), (34, 33), (34, 35), (34, 42), (37, 45), (54, 46), (54, 62) ] self.assertEqual(step_tuples, expected_single) self.assertEqual(single_steps[0][1].color, board.Color.GOLD) pos = board.Position(board.Color.SILVER, 1, board.BASIC_SETUP) single_steps = pos.get_single_steps() step_tuples = [s for s, b in single_steps] step_tuples.sort() expected_steps = [ (48, 40), (49, 41), (50, 42), (51, 43), (52, 44), (53, 45), (54, 46), (55, 47) ] self.assertEqual(step_tuples, expected_steps) self.assertEqual(single_steps[0][1].color, board.Color.GOLD) move, pos = board.parse_long_pos(CHECK_TRAP_STEP) all_steps = pos.get_steps() step_tuples = [s for s, b in all_steps] step_tuples.sort() expected_trap = [ (1, 9), (2, 10), (3, 11), (4, 12), (5, 13), (6, 7), (8, 9), (8, 16), (14, 13), (14, 15), (14, 22), (17, 9), (17, 16), (17, 18), (17, 25), (23, 22), (23, 31), (28, 20), (28, 27), (29, 21), (29, 30), (34, 26), (34, 33), (34, 35), (34, 42), (36, 35), (36, 44), (37, 45), (38, 30), (38, 39), (38, 46), (53, 45), (53, 52), (54, 46), (54, 62), (55, 47) ] self.assertEqual(step_tuples, expected_trap) in_push = pos.do_step((53, 45)) all_steps = in_push.get_steps() self.assertEqual(all_steps[0][0], (54, 53)) pull_pos = pos.do_step((54, 46)) all_steps = pull_pos.get_steps() step_tuples = [s for s, b in all_steps] step_tuples.sort() expected_pull = [ (1, 9), (2, 10), (3, 11), (4, 12), (5, 13), (6, 7), (8, 9), (8, 16), (14, 13), (14, 15), (14, 22), (17, 9), (17, 16), (17, 18), (17, 25), (23, 22), (23, 31), (28, 20), (28, 27), (29, 21), (29, 30), (34, 26), (34, 33), (34, 35), (34, 42), (36, 35), (36, 44), (37, 45), (38, 30), (38, 39), (46, 45), (46, 47), (46, 54), (53, 54), (55, 54) ] self.assertEqual(step_tuples, expected_pull)
def test_end_checks(self): pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) self.assertEqual(pos.is_goal(), False) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), False) move, pos = board.parse_long_pos(GOLD_GOAL_POS) self.assertEqual(pos.is_goal(), 1) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), 1) pos = pos.do_move([]) self.assertEqual(pos.is_goal(), 1) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), 1) move, pos = board.parse_long_pos(SILVER_GOAL_POS) self.assertEqual(pos.is_goal(), -1) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), -1) pos = pos.do_move([]) self.assertEqual(pos.is_goal(), -1) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), -1) move, pos = board.parse_long_pos(DOUBLE_GOAL_POS) self.assertEqual(pos.is_goal(), -1) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), -1) pos = pos.do_move([]) self.assertEqual(pos.is_goal(), 1) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), 1) move, pos = board.parse_long_pos(GOLD_RABBIT_LOSS) self.assertEqual(pos.is_goal(), False) self.assertEqual(pos.is_rabbit_loss(), -1) self.assertEqual(pos.is_end_state(), -1) pos = pos.do_move([]) self.assertEqual(pos.is_rabbit_loss(), -1) self.assertEqual(pos.is_end_state(), -1) move, pos = board.parse_long_pos(SILVER_RABBIT_LOSS) self.assertEqual(pos.is_goal(), False) self.assertEqual(pos.is_rabbit_loss(), 1) self.assertEqual(pos.is_end_state(), 1) pos = pos.do_move([]) self.assertEqual(pos.is_rabbit_loss(), 1) self.assertEqual(pos.is_end_state(), 1) move, pos = board.parse_long_pos(DOUBLE_RABBIT_LOSS) self.assertEqual(pos.is_goal(), False) self.assertEqual(pos.is_rabbit_loss(), -1) self.assertEqual(pos.is_end_state(), -1) pos = pos.do_move([]) self.assertEqual(pos.is_rabbit_loss(), 1) self.assertEqual(pos.is_end_state(), 1) move, pos = board.parse_long_pos(DOUBLE_IMMOBILIZATION_POS) self.assertEqual(pos.is_goal(), False) self.assertEqual(pos.is_rabbit_loss(), False) self.assertEqual(pos.is_end_state(), -1) pos = pos.do_move([]) self.assertEqual(pos.is_end_state(), 1)
def test_check_step(self): move, pos = board.parse_long_pos(CHECK_STEP_POS) # move from empty square result = pos.check_step((16, 24)) self.assertEqual(bool(result), False) self.assertIn("from an empty square", str(result)) # move to full square result = pos.check_step((0, 8)) self.assertEqual(bool(result), False) self.assertIn("to a non-empty square", str(result)) # move to non-adjacent square result = pos.check_step((8, 17)) self.assertEqual(bool(result), False) self.assertIn("to non-adjacent square", str(result)) # move a frozen piece result = pos.check_step((41, 40)) self.assertEqual(bool(result), False) self.assertIn("frozen piece", str(result)) # move a rabbit backward result = pos.check_step((23, 15)) self.assertEqual(bool(result), False) self.assertIn("rabbit back", str(result)) # start a push result = pos.check_step((36, 35)) self.assertEqual(bool(result), True) push_pos = pos.do_step((36, 35)) # correct finish result = push_pos.check_step((28, 36)) self.assertEqual(bool(result), True) # push with weak piece result = push_pos.check_step((37, 36)) self.assertEqual(bool(result), False) self.assertIn("too weak", str(result)) # skip push finish result = push_pos.check_step((8, 16)) self.assertEqual(bool(result), False) self.assertIn("neglect finishing", str(result)) # push another piece while in push result = push_pos.check_step((38, 30)) self.assertEqual(bool(result), False) self.assertIn("already in push", str(result)) # push without anyone to push result = pos.check_step((45, 46)) self.assertEqual(bool(result), False) self.assertIn("no pusher", str(result)) # start push on last step ls_pos = pos.do_step((8, 16)).do_step((16, 24)).do_step((24, 32)) result = ls_pos.check_step((36, 35)) self.assertEqual(bool(result), False) self.assertIn("last step", str(result))
def parse_start(start_lines, stop_move=None): start_lines = [l.strip() for l in start_lines] start_lines = [l for l in start_lines if l] while start_lines and not start_lines[0][0].isdigit(): del start_lines[0] if not start_lines: raise ParseError("No board or moves") if len(start_lines) < 2 or start_lines[1][0] != '+': have_board = False start = [] while start_lines and start_lines[0][0].isdigit(): move = start_lines.pop(0) if stop_move and move.startswith(stop_move): break start.append(move) else: movenum, start = board.parse_long_pos(start_lines) have_board = True return have_board, start
def test_parsing(self): self.assertRaises(ValueError, board.parse_move, " ") directional_move = [(0,8), (8, 9), (9, 1), (1, 0)] self.assertEqual(board.parse_move("Ea1n Ea2e Eb2s Eb1w"), directional_move) self.assertEqual(board.parse_move("Eb2w Cc3x Ea2n"), [(9, 8), (8, 16)]) self.assertRaises(ValueError, board.parse_move, "Ed4d") self.assertRaises(ValueError, board.parse_move, "Ea1") module_pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) basic_setup = ["1g"] + BASIC_SETUP_LONG.splitlines() parsed_move, parsed_pos = board.parse_long_pos(basic_setup) self.assertEqual(parsed_move, 1) self.assertEqual(parsed_pos, module_pos) module_pos = board.Position(board.Color.SILVER, 4, board.BASIC_SETUP) silver_setup = ["Extra", "start", "12s"] + BASIC_SETUP_LONG.splitlines() parsed_move, parsed_pos = board.parse_long_pos(silver_setup) self.assertEqual(parsed_move, 12) self.assertEqual(parsed_pos, module_pos) bad_side = ["1f"] + BASIC_SETUP_LONG.splitlines() self.assertRaises(ValueError, board.parse_long_pos, bad_side) partial_move = ["1g Ra2n"] + BASIC_SETUP_LONG.splitlines() self.assertRaises(NotImplementedError, board.parse_long_pos, partial_move) extra_separation = ["1g", ""] + BASIC_SETUP_LONG.splitlines() self.assertRaises(ValueError, board.parse_long_pos, extra_separation) bad_rank = ["1g"] + BASIC_SETUP_LONG.splitlines() bad_rank[4] = "5| . . x . . x . . |" self.assertRaises(ValueError, board.parse_long_pos, bad_rank) bad_piece = ["1g"] + BASIC_SETUP_LONG.splitlines() bad_piece[3] = "7| d h c f m c h d |" self.assertRaises(ValueError, board.parse_long_pos, bad_piece) extra_moves = ["1g"] + BASIC_SETUP_LONG.splitlines() extra_moves += [ "1g Ee2n Md2n", "1s Ed7s Me7s", "# stop parsing", "2g Ee3s" ] parsed_move, parsed_pos = board.parse_long_pos(extra_moves) self.assertEqual(parsed_move, 2) self.assertEqual(parsed_pos.color, board.Color.GOLD) extra_move_board = [ "2g", " +-----------------+", "8| r r r r r r r r |", "7| d h c c h d |", "6| . . x e m x . . |", "5| . . . . . . . . |", "4| . . . . . . . . |", "3| . . x M E x . . |", "2| D H C C H D |", "1| R R R R R R R R |", " +-----------------+", " a b c d e f g h " ] extra_move_num, extra_move_pos = board.parse_long_pos(extra_move_board) self.assertEqual(parsed_pos, extra_move_pos) self.assertRaises(ValueError, board.parse_short_pos, 3, 4, BASIC_SETUP_SHORT) self.assertRaises(ValueError, board.parse_short_pos, board.Color.GOLD, 5, BASIC_SETUP_SHORT) self.assertRaises(ValueError, board.parse_short_pos, board.Color.GOLD, -1, BASIC_SETUP_SHORT) module_pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) parsed_pos = board.parse_short_pos(board.Color.GOLD, 4, BASIC_SETUP_SHORT) self.assertEqual(parsed_pos, module_pos) bad_piece = BASIC_SETUP_SHORT[:15] + "f" + BASIC_SETUP_SHORT[16:] short_args = (board.Color.GOLD, 4, bad_piece) self.assertRaises(ValueError, board.parse_short_pos, *short_args)
def test_get_rnd_step_move(self): random.seed(1003) move_num, position = board.parse_long_pos(INDUCE_NULL_MOVE_POS) for i in range(100): position.get_rnd_step_move()
print "File %s does not appear to be a board or move list." % (sys.argv[1],) sys.exit() if len(plines) < 2 or plines[1][0] != '+': have_board = False if len(sys.argv) > 2: stop_move = sys.argv[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) 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")
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()
sys.argv[1], ) sys.exit() if len(plines) < 2 or plines[1][0] != '+': have_board = False if len(sys.argv) > 2: stop_move = sys.argv[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) 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")