Search code examples
pythonpygamegame-developmentchessminimax

Script becomes unresponsive during work, but continues to work after that and ends correctly


I'm implementing chess on Python (not the best choice however) using pygame. To find moves, I use the standard pair minimax + alpha pruning, minimax is a recursive search tree so program most of the time will do this part.

def minimax(self, depth, alpha, beta, is_maxing_white):
    # recursive tree exit condition

    # if board in cache
    if self.hash_board(depth, is_maxing_white) in self.board_caches:
        return self.board_caches[self.hash_board(depth, is_maxing_white)]

    # reached the desired depth
    if depth == 0:
        #return self.quiesce(alpha, beta)
        return self.evaluation()

    # if checkmate or stalemate
    if not [*self.board.get_all_ligal_moves(self.side)]:
        self.board_caches[self.hash_board(
            depth, is_maxing_white)] = self.evaluation()
        return self.board_caches[self.hash_board(depth, is_maxing_white)]

    best_score = -float("inf") if is_maxing_white else float("inf")
    for move in self.board.get_all_ligal_moves(self.side):
        self.board.push(move, self.side)

        local_score = self.minimax(depth - 1, alpha, beta, not is_maxing_white)

        self.board_caches[self.hash_board(
            depth - 1, not is_maxing_white)] = local_score

        if is_maxing_white:
            best_score = max(best_score, local_score)
            alpha = max(alpha, best_score)
        else:
            best_score = min(best_score, local_score)
            beta = min(beta, best_score)

        self.board.pop()

        if beta <= alpha:
            print ("pruning")
            break

    return best_score

The script returns the correct evaluation values and generally works but in moments when it does not answer any input can crash it. In which direction I should think and is it possible to somehow disable not responsible behavior?

Windows 10, python 3.7, pygame 1.9


Solution

  • When a pygame program fails to call pygame.event.get() or pygame.event.pump() for a long time, the operating system thinks that the program is crashed.

    There are important things that must be dealt with internally in the event queue. The main window may need to be repainted or respond to the system. If you fail to make a call to the event queue for too long, the system may decide your program has locked up.

    From https://www.pygame.org/docs/ref/event.html#pygame.event.pump

    If you make sure to call pygame.event.pump() occasionally in the minimax function, the OS won't think your program has crashed. So you'll be able to click on the window without getting "This window is not responding" or anything.

    Hopefully this gets your problem, and it isn't something else.