def get_input(self, piece_type, previous_board, board):
        """
        Get one input.

        :param piece_type: 1('X') or 2('O').
        :param previous_board: board int
        :param board: current board int
        :return: (row, column) coordinate of input.
        """
        board_int = GameBoard.encode_board(board)
        previous_board_int = GameBoard.encode_board(previous_board)
        self.previous_board = previous_board_int
        self.board = board_int
        self.piece_type = piece_type

        if piece_type == 1 and board_int == 0:
            return 2, 2

        if self.debug:
            print("=====player debug=====")
            print("{}'s move".format(self.piece_type))
        score, action = self._greedy(previous_board_int, board_int, "move")
        if self.debug:
            print(GameBoard.visualize_evaluation(board, piece_type))
            print("minmax player make action {} with score {}".format(
                action, score))
            print("=====player debug=====")
        return action
    def get_input(self, piece_type, previous_board, board):
        """
        Get one input.

        :param piece_type: 1('X') or 2('O').
        :param previous_board: board
        :param board: current board
        :return: (row, column) coordinate of input.
        """
        board_int = GameBoard.encode_board(board)
        previous_board_int = GameBoard.encode_board(previous_board)
        self.previous_board = previous_board_int
        self.board = board_int
        self.piece_type = piece_type

        # First piece
        if piece_type == 1 and board_int == 0:
            # TODO: write something to storage
            return 2, 2

        # self._setup_depth(board)

        if self.debug:
            print("=====player debug=====")
            print("{}'s move, d={}".format(self.piece_type, self.depth))
        score, action = self._max(previous_board_int, board_int, "move")
        if self.debug:
            print(GameBoard.visualize_evaluation(board_int, piece_type))
            print("minmax player make action {} with score {}".format(
                action, score))
            print("=====player debug=====")

        # TODO: write something to storage
        return action
    def _max(self, previous_board_int, board_int, previous_action):
        valid_moves = self._get_valid_moves(previous_board_int, board_int,
                                            self.piece_type)
        if not valid_moves:
            return 0, "pass"

        best_value = float("-inf")
        action = None
        for i, j in valid_moves:
            new_previous_board_int = board_int
            # impossible to be unsuccessful
            new_board_int, success = GameBoard.place_chess(
                previous_board_int, board_int, i, j, self.piece_type)
            score = self._minmax(False,
                                 new_previous_board_int,
                                 new_board_int,
                                 "move",
                                 self.depth - 1,
                                 float("-inf"),
                                 float("inf"),
                                 debug=False)
            if self.debug:
                print(
                    GameBoard.visualize_evaluation(board_int, self.piece_type))
                print("     {},{} with score {}".format(str(i), str(j), score))
            if score > best_value:
                best_value = score
                action = (i, j)
        return best_value, action
Example #4
0
    def test_get_board_piece(self):
        board = [[0, 1, 0, 0, 0], [0, 0, 2, 1, 0], [0, 0, 1, 0, 1],
                 [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]

        h = GameBoard.encode_board(board)
        self.assertEqual(GameBoard.get_board_piece(h, 0, 1), 1)
        self.assertEqual(GameBoard.get_board_piece(h, 4, 4), 2)
        self.assertEqual(GameBoard.get_board_piece(h, 1, 2), 2)
Example #5
0
 def test_compute_hash(self):
     board = [[0, 1, 0, 0, 0], [0, 0, 2, 1, 0], [0, 0, 1, 0, 1],
              [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]
     hash = GameBoard.encode_board(board)
     print("hash is: {}".format(hash))
     res = GameBoard.decode_board(hash)
     print(GameBoard.visualize_board_list(res))
     self.assertTrue(GameBoard.compare_board(board, res))
Example #6
0
 def test_standarize_board(self):
     board = [[0, 1, 1, 0, 0], [0, 1, 2, 1, 0], [0, 0, 1, 0, 1],
              [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]
     board_int = GameBoard.encode_board(board)
     new_board_int = GameBoard.standarize_board(board_int, WHITE)
     print(GameBoard.visualize_board(new_board_int))
     res_board = [[0, 2, 2, 0, 0], [0, 2, 1, 2, 0], [0, 0, 2, 0, 2],
                  [0, 0, 0, 0, 0], [0, 0, 2, 0, 1]]
     res_board_int = GameBoard.encode_board(res_board)
     self.assertEqual(new_board_int, res_board_int)
Example #7
0
 def test_evaluate3(self):
     # piece_type: 1('X')black or 2('O')white.
     piece_type = 1
     player = GreedyPlayer()
     board = [
         [0, 2, 0, 0, 0],
         [0, 0, 1, 1, 0],
         [0, 0, 1, 0, 0],
         [0, 0, 1, 0, 0],
         [0, 2, 0, 2, 2]
     ]
     board_int = GameBoard.encode_board(board)
     print(GameBoard.visualize_evaluation(board_int, piece_type))
 def test_evaluation(self):
     verbose = True
     q_table = FileHandler.read_q_table(path="../QLearner/QTable.pkl")
     my_player = QLearningPlayer(q_table=q_table, debug=False)
     previous_board = [[0, 0, 0, 0, 0], [0, 0, 0, 2, 0], [0, 0, 1, 0, 0],
                       [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
     previous_board_int = GameBoard.encode_board(previous_board)
     board = [[0, 0, 0, 0, 0], [0, 0, 1, 2, 0], [0, 0, 1, 0, 0],
              [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
     board_int = GameBoard.encode_board(board)
     valid_moves = GameBoard.get_valid_moves(previous_board_int, board_int,
                                             2)
     print(my_player._check_q_table(board_int, valid_moves))
     print(my_player.get_input(2, previous_board, board))
Example #9
0
 def test_evaluate2(self):
     # piece_type: 1('X')black or 2('O')white.
     piece_type = 1
     player = GreedyPlayer()
     board = [
         [0, 0, 0, 0, 0],
         [0, 0, 2, 1, 0],
         [0, 0, 1, 2, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]
     ]
     board_int = GameBoard.encode_board(board)
     print(GameBoard.visualize_evaluation(board_int, piece_type))
     move = (2, 2)
     print(GameBoard.evaluate_move(board_int, piece_type, move, debug=True))
Example #10
0
    def _greedy(self, previous_board_int, board_int, previous_action):
        valid_moves = self._get_valid_moves(previous_board_int, board_int,
                                            self.piece_type)
        if not valid_moves:
            # TODO: handle no valid move, or pass
            return 0, "PASS"

        # check q table
        check = self._check_q_table(board_int, valid_moves)
        if check:
            print("find")
            return check

        # check history table
        # encoded_board = board_int
        # check = self._check_encoded_state(encoded_board, self.piece_type)
        # if check:
        #     return check

        best_value, action = float("-inf"), None
        for move in valid_moves:
            value = GameBoard.evaluate_move(board_int,
                                            self.piece_type,
                                            move,
                                            params=self.params)
            if value > best_value:
                best_value, action = value, move
        if best_value < 0:
            return 0, "PASS"
        # write to history dictionary
        # self._store_encoded_state(encoded_board, self.piece_type, best_value, action)
        return best_value, action
    def _get_valid_moves(self, previous_board_int, board_int, piece_type):
        # state = self._encode_state(board)
        # if state in self.valid_moves:
        #     if piece_type in self.valid_moves[state]:
        #         return self.valid_moves[state][piece_type]

        moves = GameBoard.get_valid_moves(previous_board_int, board_int,
                                          piece_type)
        # self.valid_moves[state] = {piece_type: moves}
        return moves
Example #12
0
    def _check_q_table(self, board_int, valid_moves):
        # standarize board
        state = GameBoard.standarize_board(board_int, self.piece_type)
        # direct find
        if state in self.q_table:
            # print("find")
            return self._find_max(self.q_table[state], valid_moves)

        # transform and search
        for r in range(3):
            new_state = GameBoard.rotate_board(state)
            if new_state in self.q_table:
                q_values = deepcopy(self.q_table[new_state])
                # rotate the q values table back
                r_back_times = 4 - r
                for _ in range(r_back_times):
                    GameBoard.rotate(q_values)
                return self._find_max(q_values, valid_moves)

        return False
Example #13
0
    def test_new_board2(self):
        board = [[0, 1, 0, 0, 0], [0, 0, 2, 1, 0], [0, 0, 1, 0, 1],
                 [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]

        h = GameBoard.encode_board(board)
        new_b = [[0, 1, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 1, 0, 1],
                 [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]
        print(GameBoard.visualize_board_list(board))
        print(GameBoard.visualize_board_list(new_b))
        new_hash = GameBoard.new_board(h, 1, 2, 0)
        res = GameBoard.decode_board(new_hash)
        print(GameBoard.visualize_board_list(res))
        self.assertTrue(GameBoard.compare_board(res, new_b))
 def _setup_depth(self, board_int):
     """
     set up depth depending on number of moves
     """
     empty_space = GameBoard.count_empty(board_int)
     if empty_space <= 8:
         self.depth = 3
     elif 8 < empty_space <= 12:
         self.depth = 4
     elif 12 < empty_space <= 16:
         self.depth = 3
     elif 16 < empty_space <= 20:
         self.depth = 2
     else:
         self.depth = 2
Example #15
0
 def test_remove_died_pieces(self):
     board = [[0, 1, 1, 0, 0], [0, 1, 2, 1, 0], [0, 0, 1, 0, 1],
              [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]
     new_b = [[0, 1, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 1, 0, 1],
              [0, 0, 0, 0, 0], [0, 0, 1, 0, 2]]
     board_int = GameBoard.encode_board(board)
     pieces, board_int = GameBoard.remove_died_pieces(board_int, 2)
     print(pieces)
     print(GameBoard.visualize_board(board_int))
     self.assertEqual(
         GameBoard.compare_board(new_b, GameBoard.decode_board(board_int)),
         True)
     self.assertEqual(GameBoard.encode_board(new_b), board_int)
    def _greedy(self, previous_board_int, board_int, previous_action):
        # check history table
        encoded_board = board_int
        check = self._check_encoded_state(encoded_board, self.piece_type)
        if check:
            return check

        valid_moves = self._get_valid_moves(previous_board_int, board_int, self.piece_type)
        best_value, action = float("-inf"), None
        for move in valid_moves:
            value = GameBoard.evaluate_move(board_int, self.piece_type, move)
            if value > best_value:
                best_value, action = value, move

        if not valid_moves:
            # TODO: handle no valid move, or pass
            return 0, "PASS"

        # write to history dictionary
        self._store_encoded_state(encoded_board, self.piece_type, best_value, action)
        return best_value, action
Example #17
0
    def test_be_killed_score(self):
        piece_type = 2
        move = (2, 3)
        board = [[0, 0, 0, 0, 0], [0, 0, 2, 1, 0], [0, 0, 1, 0, 1],
                 [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
        board_int = GameBoard.encode_board(board)
        result = GameBoard.be_killed_score(board_int, piece_type, move)
        self.assertEqual(result, -1)

        piece_type = 2
        move = (4, 2)
        board = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 2, 0, 0],
                 [0, 0, 1, 1, 0], [0, 1, 0, 2, 0]]
        board_int = GameBoard.encode_board(board)
        result = GameBoard.be_killed_score(board_int, piece_type, move)
        self.assertEqual(result, -1)

        piece_type = 2
        move = (1, 1)
        board = [[0, 0, 0, 0, 0], [0, 0, 2, 1, 0], [0, 0, 1, 0, 1],
                 [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
        board_int = GameBoard.encode_board(board)
        result = GameBoard.be_killed_score(board_int, piece_type, move)
        self.assertEqual(result, 0)
Example #18
0
def read_stage2_log(path, win_table, lose_table, champion_only=True):
    with open(path, "r") as f:
        lines = f.readlines()
        i = 0
        previous_board_int = 0
        board_int = 0
        black_board_list = []
        white_board_list = []
        champion_black_board_list = []
        champion_white_board_list = []
        winner = None
        start_play = False
        champion_player = False

        while i < len(lines):
            line = lines[i].strip()
            if "ERROR" in line or "not found or invalid format" in line:
                break
            if "Invalid" in line:
                print("found invalid")
                break
            if "championship_player" in line:
                champion_player = True
            if "=====Round" in line:
                # new round
                # read who is black, who is white, may not use
                i += 1
                player_line = lines[i]
                player_line_list = player_line.strip().split(" ")

                # print(player_line_list)
                start_play = True
                i += 1

                # rest to default
                previous_board_int = 0
                board_int = 0
                black_board_list = []
                white_board_list = []
                winner = None
                continue

            if start_play:
                if "The winner is" in line:
                    # figure out winner
                    winner_str = line[-1]
                    if winner_str == "O":
                        # white wins
                        winner = WHITE
                        # print("white wins")
                    elif winner_str == "X":
                        winner = BLACK
                        # print("black wins")
                    else:
                        raise ValueError
                    # record board list
                    if winner == WHITE:
                        if champion_only:
                            win_table.extend(champion_white_board_list)
                            lose_table.extend(champion_black_board_list)
                        else:
                            win_table.extend(white_board_list)
                            lose_table.extend(black_board_list)
                    elif winner == BLACK:
                        if champion_only:
                            win_table.extend(champion_black_board_list)
                            lose_table.extend(champion_white_board_list)
                        else:
                            win_table.extend(black_board_list)
                            lose_table.extend(white_board_list)

                    winner = None
                    start_play = False
                    champion_player = False

                if ("Black" in line or "White" in line) and "PASS" not in line:
                    move_list = line.split(" ")[1].split(",")
                    move_i = int(move_list[0])
                    move_j = int(move_list[1])
                    # store state and move
                    if "Black" in line:
                        piece_type = BLACK
                        black_board_list.append([
                            GameBoard.standarize_board(board_int, piece_type),
                            (move_i, move_j)
                        ])
                        if champion_player:
                            champion_black_board_list.append([
                                GameBoard.standarize_board(
                                    board_int, piece_type), (move_i, move_j)
                            ])
                    else:
                        piece_type = WHITE
                        white_board_list.append([
                            GameBoard.standarize_board(board_int, piece_type),
                            (move_i, move_j)
                        ])
                        if champion_player:
                            champion_white_board_list.append([
                                GameBoard.standarize_board(
                                    board_int, piece_type), (move_i, move_j)
                            ])

                    temp_board_int, success = GameBoard.place_chess(
                        previous_board_int, board_int, move_i, move_j,
                        piece_type)
                    previous_board_int = board_int
                    d, board_int = GameBoard.remove_died_pieces(
                        temp_board_int, 3 - piece_type)
                    # print("piece{} i: {}, j: {}".format(piece_type, move_i, move_j))
                    # print(GameBoard.visualize_board(board_int))

            # read who wins
            i += 1
Example #19
0
 def test_detect_neighbor_all(self):
     print(GameBoard.detect_neighbor_all(0, 4, 4))
 def _get_valid_moves(self, previous_board_int, board_int, piece_type):
     moves = GameBoard.get_valid_moves(previous_board_int, board_int,
                                       piece_type)
     return moves
    def _minmax(self,
                is_max,
                previous_board_int,
                board_int,
                previous_action,
                depth,
                alpha,
                beta,
                debug=False):
        if is_max:
            piece_type = self.piece_type
        else:
            piece_type = 3 - self.piece_type

        # TODO: check if end of game (both don't have valid moves), return +inf or -inf

        # check history table
        encoded_board = board_int
        check = self._check_encoded_state(encoded_board, piece_type)
        if check:
            return check

        valid_moves = self._get_valid_moves(previous_board_int, board_int,
                                            piece_type)

        if not valid_moves:
            # TODO: handle no valid move
            return 0

        best_value = float("-inf") if is_max else float("inf")
        if depth < 1:
            for move in self._get_valid_moves(previous_board_int, board_int,
                                              self.piece_type):
                score = GameBoard.evaluate_move(board_int, self.piece_type,
                                                move)
                if is_max:
                    best_value = max(score, best_value)
                else:
                    best_value = min(score, best_value)

            if debug:
                print("     in {} end".format("max" if is_max else "min"))
                print(
                    GameBoard.visualize_evaluation(board_int, self.piece_type))
                print("     give {} with score {}".format(
                    "max" if is_max else "min", best_value))
            return best_value

        for i, j in valid_moves:
            new_previous_board_int = board_int
            # impossible to be unsuccessful
            new_board_int, success = GameBoard.place_chess(
                previous_board_int, board_int, i, j, piece_type)
            score = self._minmax(not is_max, new_previous_board_int,
                                 new_board_int, previous_action, depth - 1,
                                 alpha, beta)
            if is_max:
                best_value = max(score, best_value)
                alpha = max(alpha, best_value)

            else:
                best_value = min(score, best_value)
                beta = min(best_value, beta)

            if beta <= alpha:
                break

        if debug:
            print("     in {}".format("max" if is_max else "min"))
            print(GameBoard.visualize_evaluation(board_int, self.piece_type))
            print("     give {} with score {}".format(
                "max" if is_max else "min", best_value))

        # write to history dictionary
        self._store_encoded_state(encoded_board, piece_type, best_value)
        return best_value