Пример #1
0
 def _get_heuristic(self) -> int:
     if not self.check_terminal_state():
         return 0
     if self.check_win(get_other_player(self.next_player)):
         return 30
     if self.check_win(self.next_player):
         return -30
     return 15
Пример #2
0
    def _get_manhattan_distance_to_cell(self, cell: (int, int)) -> int:
        """
        :return: Summary manhattan distance from cell to every opponent's cell
        """
        opponent_cells = [ind for ind, val in enumerate(self.board) if val == get_other_player(self.next_player)]

        if len(opponent_cells) == 0:
            return 0

        manh_sum = 0
        for ind in opponent_cells:
            indices_2d = get_2d_indices(ind)
            manh_sum += abs(indices_2d[0] - cell[0]) + abs(indices_2d[1] - cell[1])
        return manh_sum
Пример #3
0
    def _simple_alg(self):
        """
        Simple algorithm, based on If's
        :return: new State and Move to get new State
        """
        # If can win -> do it
        for children, move in self._get_childrens():
            if children.check_win(self.next_player)[0]:
                return children, get_2d_indices(move)

        # If can lose -> block it
        possible_moves = self.get_empty_indices()
        for ind in possible_moves:
            opp_state = self.make_move(get_2d_indices(ind), get_other_player(self.next_player))
            if opp_state.check_win(get_other_player(self.next_player))[0]:
                block_state = self.make_move(get_2d_indices(ind))
                return block_state, get_2d_indices(ind)

        # Check tricky opponent's combination (opposite corners used)
        cnt_xs = len([val for val in self.board if val == 1])
        if cnt_xs == 2 and self.ai_num == 2 and (
                self.board[0] == self.board[8] == 1 or self.board[2] == self.board[6] == 1):
            move = get_2d_indices(random.choice(self._moves_others))
            return self.make_move(move), move

        # Sort corner cells by decreasing distance to opponent's cells if ai_num == 1.
        # Else sort by increasing distance.
        reverse = True if self.ai_num == 1 else False
        self._moves_corners = list(sorted(self._moves_corners,
                                          key=lambda index: self._get_manhattan_distance_to_cell(get_2d_indices(index)),
                                          reverse=reverse))
        # Choosing best possible move
        resorted_moves = [move for move in self._best_moves() if move in possible_moves]
        if len(resorted_moves) == 0:
            return self, None
        return self.make_move(get_2d_indices(resorted_moves[0])), get_2d_indices(resorted_moves[0])
Пример #4
0
    def make_move(self, cell: (int, int), num_player=None):
        """
        :param cell: The cell to place player's label
        :param num_player: Player who needs to make a move
        :return: The new state if move is allowed, otherwise old state.
        """
        if num_player is None:
            num_player = self.next_player

        index_1d = get_1d_index(cell[0], cell[1])
        if self.board[index_1d] == 0:
            new_board = self.board.copy()
            new_board[index_1d] = num_player
            return State(new_board, get_other_player(num_player), ai_num=self.ai_num)
        else:
            return self
Пример #5
0
    def _check_terminal_state(self):
        """
        Update color of cells if terminal state
        """
        if self.state.check_terminal_state():
            is_win, cell1, cell2, cell3 = self.state.check_win(self.state.ai_num)
            if is_win:
                self._set_cells_win(get_2d_indices(cell1), get_2d_indices(cell2),
                                    get_2d_indices(cell3), Interface._cell_color_ai_win)

            is_win, cell1, cell2, cell3 = self.state.check_win(get_other_player(self.state.ai_num))
            if is_win:
                self._set_cells_win(get_2d_indices(cell1), get_2d_indices(cell2),
                                    get_2d_indices(cell3), Interface._cell_color_human_win)

            if self.state.check_draw():
                for cell in self.cells:
                    cell.configure(bg=Interface._cell_color_draw)

            self.end_game = True
Пример #6
0
def check_game_over(board, valid_move, player_turn, turns):
    if not valid_move:
        print(player_turn + ' player wins.  Illegal move.')
        return True

    if board.king_in_check(player_turn):
        available_moves = find_available_moves(board, player_turn)
        if not available_moves:
            print(utils.get_other_player(player_turn) + ' player wins.  Checkmate.')
            return True
        else:
            print(player_turn + ' player is in check!')
            print('Available moves: ')
            for move in available_moves:
                print(move)

    if turns >= const.MAX_MOVES * 2:
        print('Tie game.  Too many moves.')
        return True

    return False
Пример #7
0
    def can_drop_piece(self, player_turn, piece, pos):
        ''' Return True if drop is possible. '''
        piece_name = str(piece)
        if len(piece_name) > 1:
            piece_name = piece_name[1]

        # Cannot place Pawn in promotion zone or in same row as another Pawn.
        if piece_name.lower() == 'p':
            if ((player_turn == 'UPPER' and utils.get_coords(pos)[1] == 0) or \
                (player_turn == 'lower' and utils.get_coords(pos)[1] == const.BOARD_SIZE - 1)):
                return False

            x, y = utils.get_coords(pos)
            for j in range(const.BOARD_SIZE):
                if isinstance(self.board[x][j],
                              Pawn) and self.board[x][j].team == player_turn:
                    return False

            board_obj = deepcopy(self)
            board_obj.drop_piece(player_turn, piece_name, pos)
            other_player = utils.get_other_player(player_turn)
            if board_obj.king_in_check(
                    other_player) and not find_available_moves(
                        board_obj, other_player):
                return False

        # Only drop pieces in empty spaces
        if self.get_piece_at_pos(pos) == '__' or self.get_piece_at_pos(
                pos).team == player_turn:
            if player_turn == 'UPPER':
                for i in range(len(self.upper_captures)):
                    if self.upper_captures[i].lower() == piece_name.lower():
                        return True

            elif player_turn == 'lower':
                for i in range(len(self.lower_captures)):
                    if self.lower_captures[i] == piece_name:
                        return True
        return False