pythontic-tac-toe

Unable to break the inner loop for the second loop to get executed


I am designing a tic-tac-toe game using pygame, but for some reason my inner while loop doesn't break and the second inner loop never gets executed.

def main():
    """Main game loop."""
    font = pygame.font.SysFont(None, 48)  # Font for messages
    while True:
        player = "X"  # Starting player
        game_board = Board()  # Create a new game board

        while True:
            for event in pygame.event.get():  # Event handling
                if event.type == pygame.QUIT:  # Check for quit event
                    pygame.quit()
                    sys.exit()

                if event.type == pygame.MOUSEBUTTONDOWN:  # Check for mouse click
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    row = mouse_y // CELL_SIZE
                    col = mouse_x // CELL_SIZE

                    # Check for valid input
                    if row in [0, 1, 2] and col in [0, 1, 2]:
                        if game_board.make_move(row, col, player):
                            click_sound.play()  # Play click sound
                            # Draw the player's symbol
                            draw_x(screen, row, col) if player == "X" else draw_o(screen, row, col)

                            # Check for a winner
                            winner = game_board.check_winner()
                            if winner is not None:
                                draw_winning_message(winner)  # Draw the winning message
                                pygame.display.flip()  # Update the display to show the message
                                win_sound.play()
                                winning_animation(winner)  # Call winning animation
                                break  # Exit the inner loop

                            # Check for a draw
                            if game_board.check_draw():
                                draw_sound.play()  # Play draw sound
                                draw_draw_message()  # Draw the draw message
                                pygame.display.flip()  # Update the display to show the message
                                draw_animation()  # Call draw animation
                                break  # Exit the inner loop

                            # Switch players
                            player = "O" if player == "X" else "X"

            # Clear the screen and redraw the grid
            screen.fill(BG_COLOR)
            draw_grid()
            game_board.display_symbols()  # Draw all symbols from the game board
            pygame.display.flip()  # Update the display

        # Now we are either breaking because of a win or a draw
        while True:  # Loop until a valid option is chosen
            screen.fill(BG_COLOR)  # Clear the screen
            game_board.display_symbols()  # Redraw symbols
            
            # Draw options for restarting or exiting
            draw_options()  # Draw the options on the screen
            draw_text("Press R to Restart or E to Exit", font, (255, 255, 255), screen, WIDTH // 2, HEIGHT - 50)
            pygame.display.flip()  # Update the display

            for event in pygame.event.get():  # Handle events
                if event.type == pygame.QUIT:  # Check for quit event
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:  # Check for key presses
                    if event.key == pygame.K_r:  # Restart the game
                        break  # Exit the loop to restart the game
                    elif event.key == pygame.K_e:  # Exit the game
                        pygame.quit()  # Ensure Pygame quits properly
                        sys.exit()

The break function itself seems to be working. I tried break at the end of the first inner loop and it worked, but when it is in the if function it doesn't work.


Solution

  • The break statement is used to break out of only the inner-most loop in Python (and most other languages).

    This is why the below code works:

    while True:
       for event in pygame.event.get():
           ...
    
       break
    

    But this doesn't

    while True:
       for event in pygame.event.get():
           ...
    
           break  # breaks out of only for loop
    

    I would restructure your code by defining another boolean variable to check whether you need to move on to the next piece of code or not.

    continue_loop = True
    
    while continue_loop:
       for event in pygame.event.get():
           if condition:
              ...
              continue_loop = False
              break
           
           ...