Exemple #1
0
    def remove_moves_that_give_opponent_a_winning_move_in_two_moves(
            self, board, potential_moves):
        new_moves = []
        for col in potential_moves:
            row = utils.find_first_empty_row(board, col)
            if row == None:
                continue
            # If we play here
            board[row][col] = self.mark
            # If we are at the top of the board, it can't hurt
            if row == 0:
                # Reset board
                board[row][col] = None
                new_moves.append(col)
                continue
            # If opponent plays above us:
            board[row - 1][col] = self.other_player
            # can the opponent have two winning moves?
            winning_moves = self.count_winning_moves(
                board, self.other_player,
                "remove_moves_that_give_opponent_a_winning_move_in_two_moves")
            if winning_moves > 1:
                # If so, skip this move
                # Reset board
                board[row][col] = None
                board[row - 1][col] = None
                continue
            if winning_moves == 1:
                # If there is one winning move, and we block it, does that give opponent a winning move?
                opponent_win_col = self.check_for_opponent_winning_move(
                    board,
                    "remove_moves_that_give_opponent_a_winning_move_in_two_moves"
                )
                opponent_win_row = utils.find_first_empty_row(
                    board, opponent_win_col)
                board[opponent_win_row][opponent_win_col] = self.mark
                opponent_second_win = self.check_for_opponent_winning_move(
                    board,
                    "remove_moves_that_give_opponent_a_winning_move_in_two_moves second_move"
                )
                if opponent_second_win != None:
                    # The opponent can win, skip this move
                    board[opponent_win_row][opponent_win_col] = None
                    board[row][col] = None
                    board[row - 1][col] = None
                    continue

            # If we've made it this far, the move is safe
            new_moves.append(col)
            # Reset board and continue to next col
            board[row][col] = None
            board[row - 1][col] = None

        log.info(
            "remove_moves_that_give_opponent_a_winning_move_in_two_moves: player {} keeps moves: {}"
            .format(self.mark, new_moves))
        return new_moves
Exemple #2
0
 def check_for_move_that_blocks_opponent_in_two_moves(self, board):
     block_it = None
     for col in range(0, constants.num_cols):
         row = utils.find_first_empty_row(board, col)
         if row == None:
             continue
         # If we play here
         board[row][col] = self.mark
         # Can the opponent win?
         opponent_win = self.check_for_opponent_winning_move(
             board, "check_for_move_that_blocks_opponent_in_two_moves")
         # Reset board
         board[row][col] = None
         # If the opponent can win, skip this move
         if opponent_win != None:
             continue
         # If opponent plays here
         board[row][col] = self.other_player
         # can the opponent have two winning moves?
         winning_moves = self.count_winning_moves(
             board, self.other_player,
             "check_for_move_that_blocks_opponent_in_two_moves")
         if winning_moves > 1:
             block_it = col
         if winning_moves == 1:
             # If there is one winning move, and we block it, does that give opponent a winning move?
             opponent_win_col = self.check_for_opponent_winning_move(
                 board, "check_for_move_that_blocks_opponent_in_two_moves")
             opponent_win_row = utils.find_first_empty_row(
                 board, opponent_win_col)
             board[opponent_win_row][opponent_win_col] = self.mark
             opponent_second_win = self.check_for_opponent_winning_move(
                 board,
                 "check_for_move_that_blocks_opponent_in_two_moves second_move"
             )
             if opponent_second_win != None:
                 # The opponent can win, block this move
                 block_it = col
                 board[opponent_win_row][opponent_win_col] = None
         # reset move for next col
         board[row][col] = None
         if block_it is not None:
             log.info(
                 "check_for_move_that_blocks_opponent_in_two_moves: player {} finds move in column {} that prevents the computer from winning in two moves"
                 .format(self.mark, col))
             break
     return block_it
Exemple #3
0
 def remove_full_columns(self, board, potential_moves):
     new_moves = []
     for col in potential_moves:
         row = utils.find_first_empty_row(board, col)
         if row == None:
             continue
         else:
             new_moves.append(col)
     log.info("remove_full_columns: player {} keeps moves {}".format(
         self.mark, new_moves))
     return new_moves
Exemple #4
0
 def check_for_move_that_wins_in_two_moves(self, board):
     best_move = None
     for col in range(0, constants.num_cols):
         row = utils.find_first_empty_row(board, col)
         if row == None:
             continue
         # If we play here
         board[row][col] = self.mark
         opponent_win = self.check_for_opponent_winning_move(
             board, "check_for_move_that_wins_in_two_moves")
         # If the opponent can win, skip this move
         if opponent_win != None:
             board[row][col] = None
             continue
         # Otherwise count how many winning moves there are for me
         winning_moves = self.count_winning_moves(
             board, self.mark, "check_for_move_that_wins_in_two_moves")
         if winning_moves > 1:
             best_move = col
         elif winning_moves == 1:
             # If there is one winning move, and opponent blocks it, does that give us a winning move?
             win_col = self.check_for_winning_move(
                 board, "check_for_move_that_wins_in_two_moves")
             win_row = utils.find_first_empty_row(board, win_col)
             board[win_row][win_col] = self.other_player
             second_win = self.check_for_winning_move(
                 board, "check_for_move_that_wins_in_two_moves second_move")
             if second_win != None:
                 # This will guarantee victory, play it!
                 best_move = col
                 board[win_row][win_col] = None
         # reset move for next col
         board[row][col] = None
         if best_move is not None:
             log.info(
                 "check_for_move_that_wins_in_two_moves: player {} finds move in column {} that allows them to win in two moves"
                 .format(self.mark, col))
             break
     return best_move
Exemple #5
0
 def check_for_move_that_wins_eventually(self, board):
     winning_move = None
     for col in range(0, constants.num_cols):
         row = utils.find_first_empty_row(board, col)
         if row == None:
             continue
         if self.check_for_iterative_winning_move(board, row, col):
             winning_move = col
             break
     if winning_move is not None:
         log.info(
             "check_for_move_that_wins_eventually: player {} finds move in column {} that allows them to win eventually"
             .format(self.mark, col))
     return winning_move
Exemple #6
0
    def check_for_iterative_winning_move(self, board, row, col):
        forced_win = False
        i = 0
        win_cols = []
        win_rows = []
        move_cols = []
        move_rows = []
        while forced_win == False:
            # If we play here
            board[row][col] = self.mark
            move_rows.append(row)
            move_cols.append(col)
            opponent_win = self.check_for_opponent_winning_move(
                board, "check_for_iterative_winning_move-{}".format(i))
            # If the opponent can win, skip this move
            if opponent_win != None:
                break
            win_col = self.check_for_winning_move(
                board, "check_for_iterative_winning_move-{}".format(i))
            if win_col == None:
                # No winning moves, break
                break
            # If there is a winning move, and opponent blocks it, does that still give us a winning move?
            win_row = utils.find_first_empty_row(board, win_col)
            win_cols.append(win_col)
            win_rows.append(win_row)
            board[win_row][win_col] = self.other_player
            second_win = self.check_for_winning_move(
                board,
                "check_for_iterative_winning_move-{} second_move".format(i))
            if second_win != None:
                # Yes, there is a winning move
                force_win = True
                break
            else:
                # If there is no winning move, play above the opponent and check again
                row = win_row - 1
                if row < 0:
                    break
                col = win_col
            i += 1

        # Clean up
        for i in range(0, len(win_cols)):
            board[win_rows[i]][win_cols[i]] = None

        for i in range(0, len(move_cols)):
            board[move_rows[i]][move_cols[i]] = None

        return forced_win
Exemple #7
0
 def remove_moves_that_give_opponent_an_immediate_winning_move(
         self, board, potential_moves):
     new_moves = []
     for col in potential_moves:
         row = utils.find_first_empty_row(board, col)
         if row == None:
             # Should not happen, but keeping this just in case
             continue
         if self.other_could_win_after_this_move(board, col, row):
             continue
         else:
             new_moves.append(col)
     log.info(
         "remove_moves_that_give_opponent_an_immediate_winning_move: player {} keeps moves: {}"
         .format(self.mark, new_moves))
     return new_moves
Exemple #8
0
    def count_winning_moves(self, board, mark, caller=None):
        caller_str = ""
        if caller != None:
            caller_str = " (for {})".format(caller)

        winning_moves = 0
        winning_move_cols = []
        for col in range(0, constants.num_cols):
            row = utils.find_first_empty_row(board, col)
            if row == None:
                continue
            if utils.check_for_winner(board, col, row, mark):
                winning_moves += 1
                winning_move_cols.append(col)
        log.info(
            "count_winning_moves{}: player {} has {} winning moves in columns {}"
            .format(caller_str, mark, winning_moves, winning_move_cols))
        return winning_moves
Exemple #9
0
    def check_for_opponent_winning_move(self, board, caller=None):
        caller_str = ""
        if caller != None:
            caller_str = " (for {})".format(caller)

        move = None
        for col in range(0, constants.num_cols):
            row = utils.find_first_empty_row(board, col)
            if row == None:
                continue
            if utils.check_for_winner(board, col, row, self.other_player):
                log.info(
                    "check_for_opponent_winning_move{}: player {} finds opponents winning move in column {}"
                    .format(caller_str, self.mark, col))
                move = col
                break

        log.debug("check_for_opponent_winning_move returning {}".format(move))
        return move