def test_do_move(self): pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) fivesteps = [(8, 16), (16, 24), (24, 32), (32, 40), (9, 17)] self.assertRaises(board.IllegalMove, pos.do_move, fivesteps) jumpstep = [(8, 24), (24, 32)] self.assertRaises(board.IllegalMove, pos.do_move, jumpstep) pos.do_move(jumpstep, strict_checks=False) pos.do_move_str("Da2n Hb2n Cc2n Hb3s Cc3x") pos.do_move_str("Hb2n Hb3e Hc3w Hb3s") self.assertRaises(board.IllegalMove, pos.do_move_str, "Hb2n Hb3n Hb4n Hb5e Hc5e") pos = board.Position(board.Color.GOLD, 4, board.BLANK_BOARD) setup = "Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Rh1 Da2 Hb2 Cc2 Md2 Ee2 Cf2 Hg2 Dh2" pos.do_move_str(setup) partial_setup = "Ra1 Rb1 Cc2 Md2 Ee2" self.assertRaises(board.IllegalMove, pos.do_move_str, partial_setup) pos.do_move_str(partial_setup, strict_checks = False) mixed_steps = "Ra1 Rb1 Ra1n" self.assertRaises(board.IllegalMove, pos.do_move_str, mixed_steps, strict_checks=False) doubled_square = "Ra1 Rb1 Rc1 Ca1" self.assertRaises(board.IllegalMove, pos.do_move_str, doubled_square, strict_checks=False) opp = "Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Rh1 Da2 Hb2 Cc2 Md2 Ee2 Cf2 Hg2 dh2" self.assertRaises(board.IllegalMove, pos.do_move_str, opp) outside = "Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Rh1 Da2 Hb2 Cc2 Md2 Ee3 Cf2 Hg2 Dh2" self.assertRaises(board.IllegalMove, pos.do_move_str, outside) toomany = "Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Rh1 Da2 Hb2 Cc2 Md2 Ee2 Cf2 Hg2 Rh2" self.assertRaises(board.IllegalMove, pos.do_move_str, toomany)
def test_equality(self): gb = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) sb = board.Position(board.Color.SILVER, 4, board.BASIC_SETUP) self.assertNotEqual(gb, sb) self.assertNotEqual(gb, 1) b1 = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) modified_setup = list(board.BASIC_SETUP) modified_setup[0] ^= 0x0000000000000400 modified_setup[2] ^= 0x0000000000000400 b2 = board.Position(board.Color.GOLD, 4, modified_setup) self.assertNotEqual(b1, b2) b2 = b2.do_move([]) b1 = b1.do_move_str("Cc2n") self.assertEqual(b1, b2)
def test_piece_placement(self): pos = board.Position(board.Color.GOLD, 4, board.BLANK_BOARD) gpos = pos.place_piece(board.Piece.GDOG, 10) self.assertRaises(ValueError, gpos.place_piece, board.Piece.GDOG, 10) self.assertRaises(ValueError, gpos.remove_piece, 5) self.assertEqual(gpos.piece_at(1 << 10), board.Piece.GDOG) npos = gpos.remove_piece(10) self.assertEqual(pos, npos) self.assertEqual(npos.piece_at(1 << 10), board.Piece.EMPTY) pos = board.Position(board.Color.SILVER, 4, board.BLANK_BOARD) spos = pos.place_piece(board.Piece.SCAMEL, 56) self.assertRaises(ValueError, spos.place_piece, board.Piece.GDOG, 56) npos = spos.remove_piece(56) self.assertEqual(pos, npos) self.assertEqual(npos.piece_at(1 << 56), board.Piece.EMPTY)
def test_generate_moves(self): pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) moves = pos.get_moves() self.assertEqual(len(moves), 3353) moves, nodes = pos.get_moves_nodes() self.assertEqual(len(moves), 3353) self.assertEqual(nodes, 16440)
def test_sanity_checks(self): pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) pos.check_hash() pos.check_boards() bb = list(pos.bitBoards) bb[3] ^= 0x400 pos.bitBoards = tuple(bb) self.assertRaises(RuntimeError, pos.check_boards) bb[3] ^= 0x400 bb[2] ^= 0x400 pos.bitBoards = tuple(bb) self.assertRaises(RuntimeError, pos.check_boards) self.assertRaises(RuntimeError, pos.check_hash) placement = list(pos.placement) placement[0] ^= 0x400 pos.placement = placement self.assertRaises(RuntimeError, pos.check_boards) placement[1] ^= 0x400 pos.placement = placement self.assertRaises(RuntimeError, pos.check_boards) placement[1] ^= 0x400 pos.placement = placement bb[0] ^= 0x400 pos.bitBoards = tuple(bb) pos.check_boards() self.assertRaises(RuntimeError, pos.check_hash) pos._zhash ^= board.ZOBRIST_KEYS[2][10] pos.check_hash()
def test_controller_protocol1(self): eng = MockEngine(protocol1) ctl = EngineController(eng) self.assertEqual(ctl.ident["name"], "Mock") self.assertEqual(ctl.ident["author"], "Janzert") self.assertEqual(ctl.protocol_version, 1) self.assertEqual(ctl.is_running(), True) resp = ctl.get_response() self.assertIsInstance(resp, EngineResponse) self.assertEqual(resp.type, "log") self.assertEqual(resp.message, eng.expected[eng.event - 1][1].lstrip("log ")) ctl.setoption("depth", 4) ctl.newgame() pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) ctl.setposition(pos) ctl.go() ctl.stop() resp = ctl.get_response() self.assertEqual(resp.type, "info") self.assertEqual(resp.message, eng.expected[eng.event - 1][1].lstrip("info ")) resp = ctl.get_response() self.assertEqual(resp.type, "bestmove") self.assertEqual(resp.move, eng.expected[eng.event - 1][1].lstrip("bestmove ")) ctl.makemove("Hb2n Ed2n") ctl.go("ponder") ctl.quit() ctl.cleanup()
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_controller_protocol0(self): eng = MockEngine(protocol0) ctl = EngineController(eng) self.assertEqual(ctl.ident["name"], "Mock0") self.assertEqual(ctl.ident["author"], "Janzert") self.assertEqual(ctl.protocol_version, 0) ctl.newgame() pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) ctl.setposition(pos) ctl.cleanup()
def test_protocol_versions(self): eng = MockEngine(protocol0) ctl = EngineController(eng) self.assertEqual(ctl.ident["name"], "Mock0") self.assertEqual(ctl.ident["author"], "Janzert") self.assertEqual(ctl.protocol_version, 0) ctl.newgame() pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) ctl.setposition(pos) ctl.cleanup() # bad protocol version eng = MockEngine(bad_protocol) eng.log = MockLog() ctl = EngineController(eng) self.assertIn("Unrecognized protocol version", eng.log.warning) pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) ctl.newgame() ctl.setposition(pos) ctl.go() ctl.stop() ctl.quit()
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_controller(self): eng = MockEngine(protocol1) ctl = EngineController(eng) self.assertEqual(ctl.ident["name"], "Mock") self.assertEqual(ctl.ident["author"], "Janzert") self.assertEqual(ctl.protocol_version, 1) self.assertEqual(ctl.is_running(), True) self.assertRaises(socket.timeout, ctl.get_response) resp = ctl.get_response() self.assertIsInstance(resp, EngineResponse) self.assertEqual(resp.type, "log") self.assertEqual(resp.message, eng.expected[eng.event - 1][1].lstrip("log ")) ctl.setoption("depth", 4) ctl.newgame() pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) ctl.setposition(pos) ctl.go() ctl.stop() resp = ctl.get_response() self.assertEqual(resp.type, "info") self.assertEqual(resp.message, eng.expected[eng.event - 1][1].lstrip("info ")) resp = ctl.get_response() self.assertEqual(resp.type, "bestmove") self.assertEqual(resp.move, eng.expected[eng.event - 1][1].lstrip("bestmove ")) ctl.makemove("Hb2n Ed2n") ctl.go("ponder") ctl.quit() ctl.cleanup() # bad response to isready eng = MockEngine(bad_isready_response) ctl = EngineController(eng) ctl.newgame() self.assertRaises(EngineException, ctl.isready) # timeout waiting for aeiok eng = MockEngine(aeiok_timeout) self.assertRaises(EngineException, EngineController, eng) # IOError sending aei eng = MockEngine(aei_send_error) self.assertRaises(EngineException, EngineController, eng)
def test_to_string(self): pos = board.Position(board.Color.GOLD, 4, board.BASIC_SETUP) self.assertEqual(pos.board_to_str(), BASIC_SETUP_LONG) nodots = BASIC_SETUP_LONG.replace(".", " ") self.assertEqual(pos.board_to_str(format="long", dots=False), nodots) self.assertEqual(pos.board_to_str(format="short"), BASIC_SETUP_SHORT) self.assertRaises(ValueError, pos.board_to_str, "invalidformat") self.assertEqual(pos.to_placing_move(), BASIC_SETUP_PLACING) oldcolor = list(BASIC_SETUP_PLACING) oldcolor[0] = 'w' + oldcolor[0][1:] oldcolor[1] = 'b' + oldcolor[1][1:] oldcolor = tuple(oldcolor) self.assertEqual(pos.to_placing_move(old_colors=True), oldcolor) self.assertEqual(pos.steps_to_str([(10, 18), (12, 20)]), "Cc2n Cc3x Ee2n") self.assertEqual(pos.steps_to_str([(11, 19), (10, 18), (19, 27)]), "Md2n Cc2n Md3n Cc3x") # try to move empty square self.assertRaises(ValueError, pos.steps_to_str, [(18, 19)]) # make irregular, non-orthogonal step self.assertEqual(pos.steps_to_str([(10, 26)]), "Cc2,c4")
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
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)
elif com_method == "stdio": eng_com = StdioEngine(enginecmd, log=log) else: raise ValueError("Unrecognized communication method: %s" % (com_method, )) eng = 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) 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"])