Example #1
0
    def test_hash(self):
        # Pick two random DIFFERENT boards.
        board1 = bd.Board(f"{GAMES_PATH}test_minimax_09.cor")
        board2 = bd.Board(f"{GAMES_PATH}test_quiesce_02.cor")
        # Get and compare their hash values.
        hash1 = board1.hash
        hash2 = board2.hash
        self.assertNotEqual(hash1, hash2)

        # Create a new board from a previous position.
        board3 = bd.Board(f"{GAMES_PATH}test_minimax_09.cor")
        hash3 = board3.hash
        self.assertEqual(hash1, hash3)
    def test_calculate_knight_moves(self):
        knight_moves = ut.knight_moves
        board = bd.Board()
        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_calculate_knight_moves.txt"

        with open(output_file, "w") as f:
            for position in range(bd.N_POSITIONS):
                print("\nKnight moves from position: {}".format(position),
                      file=f)
                moves = knight_moves[position]
                for direction in moves:
                    board.clear_board()
                    board.include_new_piece(bd.KNIGHT, bd.WHITE, position)
                    trace = 1
                    for position_2 in direction:
                        board.include_new_piece(trace,
                                                bd.WHITE,
                                                position_2,
                                                tracing=True)
                        trace += 1
                    board.print_char(out_file=f)

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #3
0
    def test_count_knight_pseudomoves(self):
        # file_list = glob.glob(GAMES_PATH + "position_01.cor")
        file_list = ["position_01.cor", "empty.cor"]
        file_list.sort()
        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_count_knight_pseudomoves.txt"

        with open(output_file, "w") as f:
            # Loop over all board states stored.
            for file_name in file_list:
                # Remove rel. path.
                # file_name = full_file_name[len(GAMES_PATH):]
                # Board to put pieces on.
                board = bd.Board(GAMES_PATH + file_name)
                print("Testing of position {}:".format(file_name), file=f)
                board.print_char(out_file=f)

                # Loop over each position on that board.
                for position in range(bd.N_POSITIONS):
                    if board.board1d[position] is None:
                        # Test function from that free position.
                        moves_count = gp.count_knight_pseudomoves(
                            board, position, board.turn)
                        print("Knight mobility from position {}: {}".format(
                            ut.coord_2_algebraic[position], moves_count),
                              file=f)

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #4
0
def loop_negamax(case_idx):

    test_cases = {
        # MAX DEPTH = 4
        "4.01": (("test_minimax_10b.cor", ), gp.PLY4_SEARCH_PARAMS),
        "4.02": (("test_minimax_01.cor", "test_minimax_02.cor",
                  "test_minimax_06.cor"), gp.PLY4_SEARCH_PARAMS),
        "4.03": (("test_minimax_07.cor", "test_minimax_08.cor",
                  "test_minimax_09.cor"), gp.PLY4_SEARCH_PARAMS),
        "4.04": (("test_minimax_11.cor", ), gp.PLY4_SEARCH_PARAMS),
        # MAX DEPTH = 5
        "5.01": (("test_minimax_11.cor", ), gp.PLY5_SEARCH_PARAMS)
    }

    test_boards, test_params = test_cases[case_idx]
    iterations = 1

    for board_name in test_boards:
        board = bd.Board(GAMES_PATH + board_name)  # The board to play on.
        game_trace = gp.Gametrace(board)  # Tracking repetitions.
        transp_table = gp.Transposition_table() \
            if test_params["transposition_table"] else None
        killer_list = gp.Killer_Moves() \
            if test_params["killer_moves"] else None
        for _ in range(iterations):
            _, _, _, _ = gp.negamax(board,
                                    0,
                                    -np.Infinity,
                                    np.Infinity,
                                    params=test_params,
                                    t_table=transp_table,
                                    trace=game_trace,
                                    killer_list=killer_list)
Example #5
0
    def test_eval_princes_and_soldiers_end(self):
        # Testcases:
        endgame_test_cases = (("test_minimax_09.cor", 9993.0,
                               None), ("endgame_01.cor", None, 9989.0),
                              ("endgame_06.cor", None,
                               9989.0), ("endgame_07.cor", None,
                                         None), ("endgame_08.cor", None, None),
                              ("endgame_09.cor", None,
                               None), ("endgame_10.cor", None,
                                       None), ("endgame_11.cor", None, None),
                              ("endgame_12.cor", None,
                               None), ("endgame_13.cor", None,
                                       None), ("endgame_14.cor", None, None),
                              ("endgame_15.cor", None,
                               None), ("endgame_16.cor", -9982.0, 9983.0),
                              ("endgame_17.cor", None,
                               9981.0), ("endgame_18.cor", None, 9983.0))

        # Loop over test cases.
        for test_case in endgame_test_cases:
            file_name, exp_result_w, exp_result_b = test_case
            board = bd.Board(GAMES_PATH + file_name)
            test_depth = 4  # Arbitrary value for tests.

            # Run tests per case.
            board.turn = bd.WHITE
            result_w = gp.eval_princes_and_soldiers_end(board, test_depth)
            board.turn = bd.BLACK
            result_b = gp.eval_princes_and_soldiers_end(board, test_depth)

            # Check results.
            self.assertEqual((result_w, result_b),
                             (exp_result_w, exp_result_b),
                             f"Error in position {file_name}")
Example #6
0
    def test_knights_mobility(self):
        # file_list = glob.glob(GAMES_PATH + "position1.cor")
        file_list = [
            "strategy_01.cor", "strategy_02.cor", "game_record_23F2020.cor",
            "game_record_23F2020b.cor"
        ]
        file_list.sort()

        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_knights_mobility.txt"

        with open(output_file, "w") as f:
            # Loop over all board states stored.
            for file_name in file_list:
                # Remove rel. path.
                # file_name = full_file_name[len(GAMES_PATH):]
                # Board to put pieces on.
                board = bd.Board(GAMES_PATH + file_name)
                print("Testing of position {}:".format(file_name), file=f)
                board.print_char(out_file=f)

                # Test function.
                moves_count_white = gp.knights_mobility(board, bd.WHITE)
                moves_count_black = gp.knights_mobility(board, bd.BLACK)
                print("Knights mobility [WHITE]: {}".format(moves_count_white),
                      file=f)
                print("Knights mobility [BLACK]: {}".format(moves_count_black),
                      file=f)

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #7
0
    def test_evaluate_terminal(self):
        test_cases = (("position_01.cor", (None, None, False, 0),
                       (None, None, False,
                        0)), ("position_02.cor", (None, None, False, 0),
                              (None, None, False,
                               0)), ("position_03.cor", (None, None, False, 0),
                                     (None, None, False, 0)),
                      ("position_04.cor", (None, None, False, 0),
                       (None, None, False,
                        0)), ("position_05.cor", (None, None, False, 0),
                              (None, None, False, 0)),
                      ("position_06.cor", (None, 10000.0, True, 1),
                       (None, -10000.0, True,
                        1)), ("position_07.cor", (None, 10000.0, True, 2),
                              (None, -10000.0, True,
                               2)), ("position_08.cor", (None, 0, True, 3),
                                     (None, 0, True, 3)),
                      ("position_09.cor", (None, None, False, 0),
                       (None, None, False,
                        0)), ("position_10.cor", (None, None, False, 0),
                              (None, None, False,
                               0)), ("position_11.cor", (None, None, False, 0),
                                     (None, None, False, 0)))

        for test in test_cases:
            file_name, exp_1, exp_2 = test

            # Test 1
            board = bd.Board(GAMES_PATH + file_name)
            # Evaluate from original moving side.
            exp_best_move, exp_eval, exp_game_end, exp_game_status = exp_1
            best_move, eval, game_end, game_status = gp.evaluate_terminal(
                board, depth=0)
            # Check results.
            self.assertEqual(
                (best_move, eval, game_end, game_status),
                (exp_best_move, exp_eval, exp_game_end, exp_game_status),
                "Error in position {}, {} to move: "
                "expected {}, received {}".format(
                    file_name, board.turn,
                    (best_move, eval, game_end, game_status),
                    (exp_best_move, exp_eval, exp_game_end, exp_game_status)))

            # Test 2
            board.flip_turn()
            # Evaluate from original moving side.
            exp_best_move, exp_eval, exp_game_end, exp_game_status = exp_2
            best_move, eval, game_end, game_status = gp.evaluate_terminal(
                board, depth=0)
            # Check results.
            self.assertEqual(
                (best_move, eval, game_end, game_status),
                (exp_best_move, exp_eval, exp_game_end, exp_game_status),
                "Error in position {}, {} to move: "
                "expected {}, received {}".format(
                    file_name, board.turn,
                    (best_move, eval, game_end, game_status),
                    (exp_best_move, exp_eval, exp_game_end, exp_game_status)))
Example #8
0
    def test_endgame_prediction(self):
        # Testcases:
        endgame_test_cases = (
            ("endgame_01.cor", None, 9989.0),
            ("endgame_02.cor", -9988.0, 9989.0),
            ("endgame_03.cor", -9988.0, -9988.0),
            ("endgame_04.cor", 9987.0, 9989.0),
            ("endgame_05.cor", 9987.0, -9986.0),
            ("endgame_06.cor", None, 9989.0),
            ("endgame_07.cor", None, None),
            ("endgame_08.cor", None, None),
            ("endgame_09.cor", None, None),
            ("endgame_10.cor", None, None),
            ("endgame_11.cor", None, None),
            ("endgame_12.cor", None, None),
            ("endgame_13.cor", None, None),
            ("endgame_14.cor", None, None),
            ("endgame_15.cor", None, None),
            ("endgame_16.cor", -9982.0, 9983.0),
            ("endgame_17.cor", None, 9981.0),
            ("endgame_18.cor", None, 9983.0),
            ("endgame_19.cor", None, None),
            ("endgame_20.cor", 9985.0, None),
            ("position_11.cor", None, 9989.0),
            ("test_quiesce_01.cor", 9987.0, None),
            ("test_quiesce_02.cor", 9985.0, None),
            ("test_quiesce_03.cor", 9987.0, None),
            ("test_quiesce_05.cor", None, None),
            ("test_quiesce_06.cor", None, None),
            ("test_quiesce_07.cor", 9987.0, None),
            ("test_quiesce_08.cor", 9987.0, None),  # No black Prince
            ("test_minimax_03.cor", 9985.0, None),
            ("test_minimax_06.cor", 9995.0, None),
            ("test_minimax_07.cor", None, None),  # No black Prince
            ("test_minimax_08.cor", None, None),
            ("test_minimax_09.cor", 9993.0, None),
            ("test_minimax_10.cor", 9987.0, None),
            ("test_make_pseudomove_03.cor", None, None),  # No black Prince
            ("test_make_pseudomove_05.cor", None, None),  # No black Prince
            ("test_make_pseudomove_07.cor", None, None),
            ("test_make_pseudomove_11.cor", None, None))

        # Loop over test cases.
        for test_case in endgame_test_cases:
            file_name, exp_result_w, exp_result_b = test_case
            board = bd.Board(GAMES_PATH + file_name)
            test_depth = 4  # Arbitrary value for tests.

            # Run tests per case.
            board.set_turn(bd.WHITE)
            result_w = gp.endgame_prediction(board, test_depth)
            board.set_turn(bd.BLACK)
            result_b = gp.endgame_prediction(board, test_depth)

            # Check results.
            self.assertEqual((result_w, result_b),
                             (exp_result_w, exp_result_b),
                             f"Error in position {file_name}")
Example #9
0
def loop_pre_evaluate_pseudomoves():

    test_cases = ("test_captures_00.cor", "game_record_23F2020.cor",
                  "test_make_pseudomove_01.cor", "test_minimax_13.cor")
    iterations = 1000

    for test_board in test_cases:
        board = bd.Board(GAMES_PATH + test_board)
        for color in [bd.WHITE, bd.BLACK]:
            board.set_turn(color)
            moves, _ = gp.generate_pseudomoves(board)
            for _ in range(iterations):
                _ = gp.pre_evaluate_pseudomoves(board, moves)
Example #10
0
    def test_position_attacked(self):
        file_list = glob.glob(GAMES_PATH + "position_01.cor")
        file_list.sort()
        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_position_attacked.txt"

        with open(output_file, "w") as f:
            for full_file_name in file_list:
                # Loop over all board states stored.
                # Remove rel. path.
                file_name = full_file_name[len(GAMES_PATH):]
                for position in range(bd.N_POSITIONS):
                    # Loop over each position on that board.
                    # Board to put pieces on.
                    board = bd.Board(GAMES_PATH + file_name)
                    # Tracing board.
                    display_board = bd.Board(GAMES_PATH + "empty.cor")
                    if board.board1d[position] is None:
                        # Test function from that free position.
                        print("\nKnight attacks from position {}".format(
                            position),
                              file=f)
                        board.include_new_piece(bd.KNIGHT, board.turn,
                                                position)
                        for position_2 in range(bd.N_POSITIONS):
                            if gp.position_attacked(board, position_2,
                                                    board.turn):
                                display_board.include_new_piece(bd.TRACE,
                                                                board.turn,
                                                                position_2,
                                                                tracing=True)
                        board.print_char(out_file=f)
                        print("Positions attacked...", file=f)
                        display_board.print_char(out_file=f)

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #11
0
    def test_eval_player_without_knights(self):
        """
        Evaluate a given position in which:
        - one player has no Knights
        - the other player some Knight
        """
        # Test cases: position, expected resul (if two values,
        # sides are flipped for a second test on the position).
        test_cases = (
            ("position_11.cor", 9989.0),
            ("test_minimax_08.cor", None),
            ("test_quiesce_01.cor", None),
            ("test_quiesce_02.cor", None, 9985.0),  # Test both sides
            ("test_quiesce_03.cor", None, 9987.0),  # Test both sides
            ("test_quiesce_05.cor", None),
            ("test_quiesce_06.cor", None),
            ("test_quiesce_07.cor", None),
            ("test_quiesce_08.cor", None, 9987.0),  # Test both sides
            ("test_minimax_03.cor", None, 9985.0),  # Test both sides
            ("test_minimax_06.cor", 9995.0),
            ("test_minimax_07.cor", None),
            ("test_minimax_10.cor", None, 9987.0),
            ("endgame_19.cor", None),
            ("test_make_pseudomove_03.cor", None),
            ("test_make_pseudomove_05.cor", None, None),
            ("test_make_pseudomove_07.cor", None, None),
            ("test_make_pseudomove_11.cor", None, None))
        # Loop over test cases:
        for test in test_cases:
            file_name, exp_results = test[0], test[1:]
            board = bd.Board(GAMES_PATH + file_name)
            player_side = board.turn
            opponent_side = bd.WHITE if player_side == bd.BLACK else bd.BLACK
            test_depth = 4  # Arbitrary value for tests.

            # Obtain and check results.
            res_1 = gp.eval_player_without_knights(board, test_depth)
            self.assertEqual(
                res_1, exp_results[0],
                f"Error in position {file_name} with {board.turn} to move.")

            # If it's a two sides test, run second test.
            if len(exp_results) == 2:
                board.turn = opponent_side
                res_2 = gp.eval_player_without_knights(board, test_depth)
                self.assertEqual(
                    res_2, exp_results[1],
                    f"Error in position {file_name} with {board.turn} to move."
                )
Example #12
0
 def test_prince_has_moves(self):
     # Test cases: position, expected result.
     test_cases = (
         ("position_11.cor", True, True),
         ("endgame_19.cor", True, None),  # No blank Prince
         ("endgame_20.cor", True, False),
         ("test_quiesce_01.cor", True, False),
         ("test_quiesce_02.cor", True, False),
         ("test_quiesce_03.cor", True, True),
         ("test_quiesce_05.cor", True, False),
         ("test_quiesce_06.cor", True, False),
         ("test_quiesce_07.cor", True, True),
         ("test_quiesce_08.cor", True, None),  # No black Prince
         ("test_minimax_03.cor", True, False),
         ("test_minimax_06.cor", True, True),
         ("test_minimax_07.cor", True, None),  # No blank Prince
         ("test_minimax_08.cor", True, True),
         ("test_minimax_10.cor", True, True),
         ("test_make_pseudomove_03.cor", True, None),  # No blank Prince
         ("test_make_pseudomove_05.cor", True, None),  # No blank Prince
         ("test_make_pseudomove_07.cor", True, True),
         ("test_make_pseudomove_11.cor", True, True))
     # Loop over test cases:
     for test in test_cases:
         file_name, exp_res_w, exp_res_b = test
         board = bd.Board(GAMES_PATH + file_name)
         # White test.
         board.turn = bd.WHITE
         if board.prince[board.turn] is not None:
             # Prince present for player.
             has_moves_w = gp.prince_has_moves(board, board.turn)
             self.assertEqual(
                 has_moves_w, exp_res_w,
                 f"Error in position {file_name} with {board.turn} to move."
             )
         # Black test.
         board.turn = bd.BLACK
         if board.prince[board.turn] is not None:
             # Prince present for player.
             has_moves_b = gp.prince_has_moves(board, board.turn)
             self.assertEqual(
                 has_moves_b, exp_res_b,
                 f"Error in position {file_name} with {board.turn} to move."
             )
Example #13
0
    def test_make_pseudomove(self):
        """
        Check is_dynamic flag for moves in different positions.
        """

        test_cases = (("endgame_00.cor", [[45,
                                           20]]), ("endgame_01.cor", [[38,
                                                                       44]]),
                      ("endgame_02.cor", [[39,
                                           38]]), ("endgame_06.cor", [[35, 34],
                                                                      [35, 36],
                                                                      [38,
                                                                       44]]))

        for test in test_cases:
            file_name, exp_moves = test
            board = bd.Board(GAMES_PATH + file_name)
            moves, _ = gp.generate_pseudomoves(board)
            dynamic_moves = []
            non_dynamic_moves = []
            # Try all pseudomoves in the position.
            for move in moves:
                coord1, coord2 = move
                # Make the move and check results.
                is_legal, is_dynamic, result, game_end, game_status, \
                    captured_piece, leaving_piece, old_hash, \
                    opponent_in_check = \
                    gp.make_pseudomove(
                        board, coord1, coord2,
                        depth=0, params=gp.DEFAULT_SEARCH_PARAMS,
                        check_dynamic=True
                    )
                # Keep if it's dynamic.
                if is_legal and is_dynamic:
                    dynamic_moves.append(move)

                # Now 'unmake' the move and check against 'board_orig'.
                board.unmake_move(coord1, coord2, captured_piece,
                                  leaving_piece, old_hash)
            # Check found dynamic moves vs expected.
            exp_moves.sort()
            dynamic_moves.sort()
            self.assertEqual(exp_moves, dynamic_moves,
                             "Error in position {}".format(file_name))
    def test_calculate_soldier_moves(self):
        soldier_moves = ut.soldier_moves
        board = bd.Board()
        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_calculate_soldier_moves.txt"

        with open(output_file, "w") as f:
            for side in [bd.WHITE, bd.BLACK]:
                for position in range(bd.N_POSITIONS):
                    moves = soldier_moves[side][position]
                    board.clear_board()
                    board.include_new_piece(bd.SOLDIER, side, position)
                    if moves == []:
                        # Soldier on Prince's throne.
                        n_moves = 0
                    else:
                        if type(moves[0]) == int:
                            # Simple list out of kingdom.
                            for position_2 in moves:
                                board.include_new_piece(bd.TRACE,
                                                        side,
                                                        position_2,
                                                        tracing=True)
                            n_moves = len(moves)
                        else:
                            # List of lists within the kingdom.
                            moves_set = set()
                            for moves_list in moves:
                                moves_set = moves_set.union(moves_list)
                            for position_2 in moves_set:
                                board.include_new_piece(bd.TRACE,
                                                        side,
                                                        position_2,
                                                        tracing=True)
                            n_moves = len(moves_set)
                    print("{} Soldier: {} moves from position {}".format(
                        bd.color_name[side], n_moves, position),
                          file=f)
                    board.print_char(out_file=f)

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #15
0
    def test_eval_princes_end(self):
        # Testcases:
        p_vs_p_test_cases = (("endgame_02.cor", 4, -9988.0,
                              9989.0), ("endgame_03.cor", 4, -9988.0, -9988.0),
                             ("endgame_04.cor", 4, 9987.0,
                              9989.0), ("endgame_05.cor", 4, 9987.0, -9986.0))

        # Loop over cases.
        for test_case in p_vs_p_test_cases:
            file_name, test_depth, exp_result_w, exp_result_b = test_case
            board = bd.Board(GAMES_PATH + file_name)

            # Run 2 tests per case.
            board.turn = bd.WHITE
            result_w = gp.eval_princes_end(board, test_depth)
            board.turn = bd.BLACK
            result_b = gp.eval_princes_end(board, test_depth)

            # Check results.
            self.assertEqual((result_w, result_b),
                             (exp_result_w, exp_result_b),
                             f"Error in position {file_name}")
Example #16
0
    def test_soldiers_advance_reward(self):
        test_cases = (("test_quiesce_01.cor", 0.1,
                       0), ("test_quiesce_02.cor", 0.1,
                            0), ("test_quiesce_03.cor", 0.1,
                                 0), ("test_quiesce_05.cor", 0.1,
                                      0), ("test_quiesce_06.cor", 0.1,
                                           0), ("test_quiesce_07.cor", 0.1, 0),
                      ("test_quiesce_08.cor", 0.1,
                       0.1), ("test_minimax_01.cor", 0.1,
                              0), ("test_minimax_02.cor", 0.1,
                                   0), ("test_minimax_03.cor", 0.1,
                                        0), ("test_minimax_05.cor", 0, 0),
                      ("test_minimax_06.cor", 0.4,
                       0), ("test_minimax_07.cor", 0,
                            0.4), ("test_minimax_08.cor", 0.3,
                                   0), ("test_minimax_09.cor", 0,
                                        0.55), ("test_minimax_10.cor", 0.1, 0),
                      ("test_minimax_11.cor", 0,
                       0), ("test_minimax_13.cor", 0,
                            0), ("test_make_pseudomove_01.cor", 0.2,
                                 0.30000000000000004),
                      ("test_make_pseudomove_04.cor", 0.1,
                       0), ("test_make_pseudomove_07.cor", 0.1,
                            0), ("test_make_pseudomove_12.cor", 0.2, 0.1),
                      ("endgame_00.cor", 0.30000000000000004,
                       0.7), ("endgame_01.cor", 0.7999999999999999,
                              0.44999999999999996), ("endgame_02.cor", 0, 0))

        for test in test_cases:
            file_name, exp_w, exp_b = test
            board = bd.Board(GAMES_PATH + file_name)
            board.set_turn(bd.WHITE)
            res_w = gp.soldiers_advance_reward(board, bd.WHITE)
            board.set_turn(bd.BLACK)
            res_b = gp.soldiers_advance_reward(board, bd.BLACK)

            self.assertEqual((res_w, res_b), (exp_w, exp_b),
                             "Error in position {}".format(file_name))
Example #17
0
    def test_soldiers_lag(self):
        test_cases = (("test_quiesce_01.cor", 0,
                       6), ("test_quiesce_02.cor", 0,
                            0), ("test_quiesce_03.cor", 0,
                                 4), ("test_quiesce_05.cor", 0,
                                      4), ("test_quiesce_06.cor", 0,
                                           0), ("test_quiesce_07.cor", 0, 0),
                      ("test_quiesce_08.cor", 0,
                       0), ("test_minimax_01.cor", 0,
                            10), ("test_minimax_02.cor", 0,
                                  0), ("test_minimax_03.cor", 0,
                                       0), ("test_minimax_05.cor", 0,
                                            0), ("test_minimax_06.cor", 0, 1),
                      ("test_minimax_07.cor", 0,
                       0), ("test_minimax_08.cor", 0,
                            0), ("test_minimax_09.cor", 0,
                                 0), ("test_minimax_10.cor", 0,
                                      0), ("test_minimax_11.cor", 0,
                                           0), ("test_minimax_13.cor", 0, 0),
                      ("test_make_pseudomove_01.cor", 0,
                       2), ("test_make_pseudomove_04.cor", 4,
                            0), ("test_make_pseudomove_07.cor", 0,
                                 8), ("test_make_pseudomove_12.cor", 0, 2),
                      ("endgame_00.cor", 0, 0), ("endgame_01.cor", 0,
                                                 0), ("endgame_02.cor", 0, 0))

        for test in test_cases:
            file_name, exp_w, exp_b = test
            board = bd.Board(GAMES_PATH + file_name)
            board.set_turn(bd.WHITE)
            res_w = gp.soldiers_lag(board, bd.WHITE)
            board.set_turn(bd.BLACK)
            res_b = gp.soldiers_lag(board, bd.BLACK)

            self.assertEqual((res_w, res_b), (exp_w, exp_b),
                             "Error in position {}".format(file_name))
Example #18
0
def loop_generate_pseudomoves():

    test_cases = (
        "test_minimax_01.cor",
        "test_minimax_02.cor",
        "test_minimax_03.cor",
        "test_minimax_04.cor",
        "test_minimax_05.cor",
        "test_minimax_06.cor",
        "test_minimax_07.cor",
        "test_minimax_08.cor",
        "test_minimax_09.cor",
        "test_minimax_10.cor",
        "test_minimax_10b.cor",
        "test_minimax_11.cor",
    )
    iterations = 10000

    for test_board in test_cases:
        board = bd.Board(GAMES_PATH + test_board)
        for color in [bd.WHITE, bd.BLACK]:
            board.set_turn(color)
            for _ in range(iterations):
                _, _ = gp.generate_pseudomoves(board)
Example #19
0
def loop_position_attacked():

    test_cases = (
        "test_minimax_01.cor",
        "test_minimax_02.cor",
        "test_minimax_03.cor",
        "test_minimax_04.cor",
        "test_minimax_05.cor",
        "test_minimax_06.cor",
        "test_minimax_07.cor",
        "test_minimax_08.cor",
        "test_minimax_09.cor",
        "test_minimax_10.cor",
        "test_minimax_10b.cor",
        "test_minimax_11.cor",
    )
    iterations = 100

    for test_board in test_cases:
        board = bd.Board(GAMES_PATH + test_board)
        for coord in range(board.n_positions):
            for color in [bd.WHITE, bd.BLACK]:
                for _ in range(iterations):
                    _ = gp.position_attacked(board, coord, color)
    def test_calculate_kingdoms(self):
        kingdoms = ut.calculate_kingdoms(bd.N_POSITIONS)
        board = bd.Board()
        board.clear_board()
        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_calculate_kingdoms.txt"

        with open(output_file, "w") as f:
            positions = np.argwhere(kingdoms[0]).flatten()
            for position in positions:
                board.include_new_piece(bd.WHITE,
                                        bd.WHITE,
                                        position,
                                        tracing=True)
            positions = np.argwhere(kingdoms[1]).flatten()
            for position in positions:
                board.include_new_piece(bd.BLACK,
                                        bd.BLACK,
                                        position,
                                        tracing=True)
            board.print_char(out_file=f)

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #21
0
    def test_make_unmake_pseudomove(self):
        # Definition of test cases to run:
        # - File to load.
        # - move to try...
        # - expected return from make_pseudomove():
        #   new_board [IGNORED], is_legal, is_dynamic,
        #   result, game_end, game_status
        """
            Types of game node status:
            ON_GOING = 0
            VICTORY_CROWNING = 1
            VICTORY_NO_PIECES_LEFT = 2
            DRAW_NO_PRINCES_LEFT = 3
            DRAW_STALEMATE = 4
            DRAW_THREE_REPETITIONS = 5
        """

        test_cases = [
            # BOARD to test: test_make_pseudomove_01
            # Test:
            # move_to_make,
            # is_legal, is_dynamic, result, game_end, game_status
            [
                "test_make_pseudomove_01.cor", "c8b7", True, False, None,
                False, 0, False
            ],
            [
                "test_make_pseudomove_01.cor", "c8c3", True, True, None, False,
                0, None
            ],
            [
                "test_make_pseudomove_01.cor", "c8a8", True, True, None, False,
                0, True
            ],
            [
                "test_make_pseudomove_01.cor", "e3e2", False, None, None, None,
                None, None
            ],
            # BOARD to test: test_make_pseudomove_02.cor
            [
                "test_make_pseudomove_02.cor", "b2e1", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_02.cor", "a5a4", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_02.cor", "a5a6", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_02.cor", "b5b4", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_02.cor", "b5a6", True, False, None,
                False, 0, False
            ],
            # BOARD to test: test_make_pseudomove_03.cor
            [
                "test_make_pseudomove_03.cor", "a7b5", True, True, 9999.0,
                True, 2, None
            ],
            [
                "test_make_pseudomove_03.cor", "c5b6", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_03.cor", "f1g1", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_03.cor", "c5c4", True, False, None,
                False, 0, None
            ],
            [
                "test_make_pseudomove_03.cor", "f1f2", True, True, None, False,
                0, None
            ],
            # BOARD to test: test_make_pseudomove_04.cor
            [
                "test_make_pseudomove_04.cor", "b1a1", True, True, None, False,
                0, None
            ],
            # BOARD to test: test_make_pseudomove_05.cor
            [
                "test_make_pseudomove_05.cor", "a3a1", True, True, None, False,
                0, None
            ],
            # BOARD to test: test_make_pseudomove_06.cor
            [
                "test_make_pseudomove_06.cor", "a3a1", False, None, None, None,
                None, None
            ],
            # BOARD to test: test_make_pseudomove_07.cor
            [
                "test_make_pseudomove_07.cor", "a3a1", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_07.cor", "a12a13", True, True, 9999.0,
                True, 1, None
            ],
            # BOARD to test: test_make_pseudomove_11.cor
            [
                "test_make_pseudomove_11.cor", "a12a13", False, None, None,
                None, None, None
            ],
            [
                "test_make_pseudomove_11.cor", "a3a1", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_11.cor", "a12b11", True, False, None,
                False, 0, False
            ],
            [
                "test_make_pseudomove_11.cor", "b9a10", True, False, None,
                False, 0, False
            ],
            # BOARD to test: test_make_pseudomove_12.cor
            [
                "test_make_pseudomove_12.cor", "b2e1", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_12.cor", "a5a4", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_12.cor", "a5a6", False, None, None, None,
                None, None
            ],
            [
                "test_make_pseudomove_12.cor", "a5++", True, True, None, False,
                0, None
            ]
        ]

        # Go through all test cases, each on one board.
        for test_case in test_cases:
            file_name, test_move, res1, res2, res3, res4, res5, res6 = \
                test_case
            board = bd.Board(GAMES_PATH + file_name)
            # Reference for unmake tests.
            board_orig = bd.Board(GAMES_PATH + file_name)
            # Parse move.
            coord1, coord2, is_correct = \
                ut.algebraic_move_2_coords(test_move)
            assert is_correct, "Error parsing move {}".format(test_move)

            # Make the move and check results.
            is_legal, is_dynamic, result, game_end, game_status, \
                captured_piece, leaving_piece, old_hash, opponent_in_check = \
                gp.make_pseudomove(
                    board, coord1, coord2,
                    depth=0, params=gp.DEFAULT_SEARCH_PARAMS,
                    check_dynamic=True
                )

            self.assertTrue((res1, res2, res3, res4, res5,
                             res6) == (is_legal, is_dynamic, result, game_end,
                                       game_status, opponent_in_check),
                            "ERROR in position {}, move: {}:\n"
                            "Expected: {}, {}, {}, {}, {}, {}\n"
                            "Received: {}, {}, {}, {}, {}, {}".format(
                                file_name, test_move, res1, res2, res3, res4,
                                res5, res6, is_legal, is_dynamic, result,
                                game_end, game_status, opponent_in_check))

            # Now 'unmake' the move and check against 'board_orig'.
            board.unmake_move(coord1, coord2, captured_piece, leaving_piece,
                              old_hash)
            # Check .turn, .hash
            self.assertEqual(
                (board.turn, board.hash), (board_orig.turn, board_orig.hash),
                "ERROR in position {}, after 'unmaking' move: {}:\n"
                "Expected: {}, {}\n"
                "Received: {}, {}".format(file_name, test_move, board.turn,
                                          board.hash, board_orig.turn,
                                          board_orig.hash))
            # Check .piece_count
            self.assertTrue(
                (board.piece_count == board_orig.piece_count).all(),
                "ERROR in position {}, after 'unmaking' move: {}:\n"
                ".piece_count differs".format(file_name, test_move))
            # Check .boardcode
            self.assertTrue(
                (board.boardcode == board_orig.boardcode).all(),
                "ERROR in position {}, after 'unmaking' move: {}:\n"
                ".boardcode differs.".format(file_name, test_move))
            # Check .board1d, all coordinates.
            self.assertTrue(
                (board.board1d == board_orig.board1d).all(),
                "ERROR in position {}, after 'unmaking' move: {}:\n"
                ".board1d differs.".format(file_name, test_move))
            # Check .prince for both colors.
            if board.prince[bd.WHITE] is None:
                white_prince_data_0 = (None, None, None, None, None)
            else:
                white_prince_data_0 = (
                    board.prince[bd.WHITE].type,
                    board.prince[bd.WHITE].color,
                    board.prince[bd.WHITE].coord,
                    board.prince[bd.WHITE].code,
                    board.prince[bd.WHITE].tracing,
                )
            if board_orig.prince[bd.WHITE] is None:
                white_prince_data_1 = (None, None, None, None, None)
            else:
                white_prince_data_1 = (
                    board_orig.prince[bd.WHITE].type,
                    board_orig.prince[bd.WHITE].color,
                    board_orig.prince[bd.WHITE].coord,
                    board_orig.prince[bd.WHITE].code,
                    board_orig.prince[bd.WHITE].tracing,
                )
            if board.prince[bd.BLACK] is None:
                black_prince_data_0 = (None, None, None, None, None)
            else:
                black_prince_data_0 = (
                    board.prince[bd.BLACK].type,
                    board.prince[bd.BLACK].color,
                    board.prince[bd.BLACK].coord,
                    board.prince[bd.BLACK].code,
                    board.prince[bd.BLACK].tracing,
                )
            if board_orig.prince[bd.BLACK] is None:
                black_prince_data_1 = (None, None, None, None, None)
            else:
                black_prince_data_1 = (
                    board_orig.prince[bd.BLACK].type,
                    board_orig.prince[bd.BLACK].color,
                    board_orig.prince[bd.BLACK].coord,
                    board_orig.prince[bd.BLACK].code,
                    board_orig.prince[bd.BLACK].tracing,
                )
            self.assertEqual((white_prince_data_0, black_prince_data_0),
                             (white_prince_data_1, black_prince_data_1),
                             "ERROR in position {}, after 'unmaking' move {}: "
                             ".prince differs".format(file_name, test_move))
Example #22
0
    def test_pre_evaluate_pseudomoves(self):

        # Test cases.
        test_cases = (
            (
                # Case: No killer moves.
                "test_captures_00.cor",
                [
                    [1, 2],  # s x K
                    [41, 44],  # k x S (not defended)
                    [28, 29],  # s x S (defended)
                    [1, 0],
                    [1, 13],
                    [1, 14],
                    [26, 16],
                    [26, 25],
                    [26, 27],
                    [28, 18],
                    [28, 27],
                    [41, 13],
                    [41, 14],
                    [41, 24],
                    [41, 25],
                    [41, 33],
                    [41, 34],
                    [41, 36],
                    [41, 40],
                    [41, 42],
                    [41, 43],
                    [41, 45],
                    [41, 46],
                    [41, 48],
                    [41, 37]  # K x s (defended)
                ],
                [None, None]),
            (
                # Case: 1 killer move.
                "test_captures_00.cor",
                [
                    [1, 2],  # s x K
                    [41, 44],  # k x S (not defended)
                    [28, 29],  # s x S (defended)
                    [41, 24],  # Killer move
                    [1, 0],
                    [1, 13],
                    [1, 14],
                    [26, 16],
                    [26, 25],
                    [26, 27],
                    [28, 18],
                    [28, 27],
                    [41, 13],
                    [41, 14],
                    [41, 25],
                    [41, 33],
                    [41, 34],
                    [41, 36],
                    [41, 40],
                    [41, 42],
                    [41, 43],
                    [41, 45],
                    [41, 46],
                    [41, 48],
                    [41, 37]  # K x s (defended)
                ],
                [[41, 24], [None, None]]),
            (
                # Case: No moves, no killer moves.
                "test_minimax_02.cor",
                [],
                [None, None]),
            (
                # Case: Endgame.
                "endgame_07.cor",
                [[47, 46], [33, 34], [5, 17], [5, 4], [5, 6], [25, 24],
                 [25, 26], [47, 43]],
                [None, None]),
            (
                # Case: Endgame.
                "endgame_08.cor",
                [[45, 46], [36, 42], [36, 35], [36, 37], [45, 41]],
                [None, None]))

        # Loop over all test cases.
        for test in test_cases:
            file_name, expected_moves, killer_moves = test

            # Generate and sort moves.
            board = bd.Board(GAMES_PATH + file_name)
            moves, moves_count = gp.generate_pseudomoves(board)
            moves = gp.pre_evaluate_pseudomoves(board, moves, killer_moves)

            # Check results.
            self.assertTrue(
                np.array_equal(moves, np.array(expected_moves)),
                "Error found in position {} with killer moves {}".format(
                    file_name, killer_moves))
Example #23
0
    def test_negamax(self):
        # Definition of test cases to run:
        # - File to load.
        # - move to try...
        # - expected return from mini_max():
        #   best_move, result, game_end, game_status

        TEST_SEARCH_PARAMS_4 = gp.PLY4_SEARCH_PARAMS
        # Go through all test cases, each on one board.
        # - Position to play
        # - Move/list of moves, result, end, status
        test_cases = (("test_minimax_01.cor", None, 10000, True,
                       1), ("test_minimax_02.cor", None, -10000, True,
                            2), ("test_minimax_03.cor", None, 0, True,
                                 4), ("test_minimax_04.cor", None, 0, True, 3),
                      ("test_minimax_05.cor", None, -10000, True,
                       2), ("test_minimax_06.cor", [46, 48], 9999.0, False, 0),
                      ("test_minimax_07.cor", [19, 40], 9999.0, False,
                       0), ("test_minimax_08.cor", [[32, 46],
                                                    [32,
                                                     48]], 9998.0, False, 0),
                      ("test_minimax_09.cor", [41,
                                               45], 1.541666666666667, False,
                       0), ("test_minimax_10.cor", [[33, 25], [26, 27],
                                                    [26, 16]], -9990, False,
                            0), ("test_minimax_10b.cor", [28,
                                                          26], 9994, False, 0))

        params = TEST_SEARCH_PARAMS_4
        output_file = OUTPUT_PATH + OUTPUT_FILE
        with open(output_file, "w") as f:
            print("")  # To clean up the screen traces.
            for test in test_cases:
                file_name, exp_move, exp_result, exp_end, exp_status = test
                # The board to put pieces on.
                board = bd.Board(GAMES_PATH + file_name)
                # The game trace.
                game_trace = gp.Gametrace(board)
                transp_table = gp.Transposition_table() \
                    if params["transposition_table"] else None
                killer_list = gp.Killer_Moves() \
                    if params["killer_moves"] else None

                print("Testing position {}: ".format(file_name), end="")
                print("Analysis of position {}: ".format(file_name), file=f)
                board.print_char(out_file=f)

                # Call to negamax.
                t_start = time.time()
                best_move, result, game_end, game_status = gp.negamax(
                    board,
                    0,
                    -np.Infinity,
                    np.Infinity,
                    params=params,
                    t_table=transp_table,
                    trace=game_trace,
                    killer_list=killer_list)
                t_end = time.time()
                print("{}".format(datetime.timedelta(seconds=t_end - t_start)))

                # Display results.
                ut.display_results(best_move, result, game_end, game_status, f)

                # And check vs. expected.
                if exp_move is not None and type(exp_move[0]) == list:
                    self.assertTrue(
                        best_move in exp_move,
                        "Position: {}. Expected: {}; received: {}".format(
                            file_name, exp_move, best_move))
                else:
                    self.assertEqual(best_move, exp_move,
                                     "Position: {}".format(file_name))
                self.assertEqual((result, game_end, game_status),
                                 (exp_result, exp_end, exp_status),
                                 "Position: {}".format(file_name))
Example #24
0
    def test_generate_pseudomoves(self):
        file_list = (
            "position_01.cor",
            "position_02.cor",
            "position_03.cor",
            "position_04.cor",
            "position_05.cor",
            "position_06.cor",
            "position_07.cor",
            "position_08.cor",
            "position_09.cor",
            "position_10.cor",
        )

        output_file = OUTPUT_PATH + OUTPUT_FILE
        expected_output_file = \
            OUTPUT_PATH + "output_generate_pseudomoves.txt"

        with open(output_file, "w") as f:
            for file_name in file_list:
                # Loop over all board states stored.
                # Actual board to put pieces on.
                board = bd.Board(GAMES_PATH + file_name)
                print("Loading game position {} ...".format(file_name), file=f)
                # Tracing board.
                display_board = bd.Board(GAMES_PATH + "empty.cor")

                for turn in [bd.WHITE, bd.BLACK]:
                    # Try board for both sides.
                    board.set_turn(turn)
                    display_board.set_turn(turn)
                    print("\nPseudo-moves for position: {}".format(file_name),
                          file=f)
                    board.print_char(out_file=f)
                    # Generate pseudomoves to test.
                    moves, moves_count = gp.generate_pseudomoves(board)
                    moves_count_check = 0
                    # Loop over all pieces in the board.
                    for p_i in board.pieces[turn]:
                        coord1 = p_i.coord
                        display_board.include_new_piece(
                            p_i.type, p_i.color, p_i.coord)
                        # Spot the piece's moves in moves generated.
                        for move_pair in moves:
                            if move_pair[0] == coord1:
                                moves_count_check += 1
                                display_board.include_new_piece(bd.TRACE,
                                                                p_i.color,
                                                                move_pair[1],
                                                                tracing=True)
                        # Display moves of the piece.
                        print("piece = {} {} at {}: {} moves:".format(
                            bd.color_name[p_i.color], bd.piece_name[p_i.type],
                            p_i.coord, moves_count),
                              file=f)
                        display_board.print_char(out_file=f)
                        display_board.clear_board()

                    # Check total move counts for that side.
                    self.assertEqual(
                        moves_count, moves_count_check,
                        "Error found in moves from {}.".format(
                            bd.color_name[turn]))

        self.assertTrue(filecmp.cmp(output_file, expected_output_file))
Example #25
0
    def test_quiesce(self):
        # Definition of test cases to run:
        # - File to load.
        # - move to try...
        # - expected return from mini_max():
        #   best_move, result, game_end, game_status

        TEST_SEARCH_PARAMS_4 = gp.PLY4_SEARCH_PARAMS

        # Go through all test cases, each on one board.
        # WARNING: float values from 'result' are very sensitive to
        # depth search parameters in TEST_SEARCH_PARAMS_4.
        # Test case:
        # - Position to play.
        # - Search parameters.
        # - Move / list of moves, result, end, status.
        test_cases = (
            ("endgame_09.cor", None, 1.43, False, 0),
            ("test_quiesce_01.cor", None, -13.246666666666666, False, 0),
            ("test_quiesce_02.cor", None, 0, True, 4),
            ("test_quiesce_03.cor", None, -14.146666666666665, False, 0),
            ("test_quiesce_05.cor", [33, None], -115.60333333333332, False, 0),
            ("test_quiesce_06.cor", [35, 34], -13.541666666666666, False, 0),
            ("test_quiesce_07.cor", [33, 34], -9991.0, False, 0),
            ("test_quiesce_08.cor", None, -114.09666666666668, False, 0),
            #  Taken from negamax() unit tests.
            ("test_minimax_01.cor", None, 9996.0, True, 1),
            ("test_minimax_02.cor", None, -9996.0, True, 2),
            ("test_minimax_03.cor", None, 0, True, 4),
            ("test_minimax_04.cor", None, 0, True, 3),
            ("test_minimax_05.cor", None, -9996, True, 2),
            ("test_minimax_06.cor", None, 9995.0, False, 0),
            ("test_minimax_07.cor", [19, 40], 9995.0, False, 0),
            ("test_minimax_08.cor", [[32, 46], [32, 48]], 9994.0, False, 0),
            ("test_minimax_09.cor", [41, 45], 0.908333333333333, False, 0),
            ("test_minimax_10.cor", None, -12.946666666666665, False, 0),
            ("test_minimax_10b.cor", None, 9987.0, False, 0))

        params = TEST_SEARCH_PARAMS_4
        output_file = OUTPUT_PATH + OUTPUT_FILE
        with open(output_file, "w") as f:
            for test in test_cases:
                file_name, exp_move, exp_result, exp_end, exp_status = test
                # The board to put pieces on.
                board = bd.Board(GAMES_PATH + file_name)
                # The game trace, indexing first board appropriately.
                game_trace = gp.Gametrace(board)
                game_trace.current_board_ply = params["max_depth"] - 1
                # Transposition table and killer_list.
                transp_table = gp.Transposition_table() \
                    if params["transposition_table"] else None
                killer_list = gp.Killer_Moves() \
                    if params["killer_moves"] else None

                print("\nAnalysis of position {}:".format(file_name), file=f)
                board.print_char(out_file=f)

                # Call to quiesce() with depth 'max_depth".
                best_move, result, game_end, game_status = gp.quiesce(
                    board,
                    params["max_depth"],
                    -np.Infinity,
                    np.Infinity,
                    params=params,
                    t_table=transp_table,
                    trace=game_trace,
                    killer_list=killer_list)

                # Display results.
                ut.display_results(best_move, result, game_end, game_status, f)

                # And check vs. expected.
                # Move:
                if exp_move is not None and type(exp_move[0]) == list:
                    self.assertTrue(
                        best_move in exp_move,
                        "Position: {}; {} not in {}".format(
                            file_name, best_move, exp_move))
                else:
                    self.assertEqual(
                        best_move, exp_move, "Position: {}; {} != {}".format(
                            file_name, best_move, exp_move))
                # evaluation:
                self.assertAlmostEqual((result), (exp_result),
                                       places=4,
                                       msg="Position: {}; {} != {}".format(
                                           file_name, result, exp_result))
                # game_end, game_status:
                self.assertEqual(
                    (game_end, game_status), (exp_end, exp_status),
                    "Position: {}; {} != {}".format(file_name,
                                                    (game_end, game_status),
                                                    (exp_end, exp_status)))