title: Window freeze for single thread in while loop of Pygame
body: <p>I am writing a short program to display cards in a round. I suspect that it is the length of the code which prevents the final 'OK' submit on P3 (the last player's submission) from executing properly: at which point the program <em>sometimes</em> will evaluate the winner and clear the round, but most of the time instead will freeze.
  I have tried clock.tick(low fps), pygame.event.pump(), and pygame.event.clear(). Any leads would be much appreciated.</p>
  <pre><code># Round loop begins. Finish until all hands are empty.
              while not self.game.get_is_last_round():
  
                  player = self.game.get_player(self.game.get_player_turn())
                  hand = player.order_hand(player.get_hand(),
                                           self.game.get_round_level(),
                                           self.game.get_round_trump_suit())
                  ok_clicked_2 = False
  
                  pygame.event.pump()
                  for event in pygame.event.get():
                      if event.type == pygame.QUIT:
                          self.deal_running = False
                          self.is_running = False
                          pygame.display.quit()
                          pygame.quit()
                          sys.exit()
                      if event.type == pygame.MOUSEBUTTONDOWN:
                          play = player.get_play()
                          click = pygame.mouse.get_pressed(num_buttons=3)
                          pos = pygame.mouse.get_pos()
  
                          # Used DeMorgan's law to resolve error
                          ok_clicked_2 = (OK1_X &lt; pos[0] &lt; OK1_X + B_W) and (OK1_Y &lt; pos[1] &lt; OK1_Y + B_H) and click[0]
  
                          b1, card = self.check_hand(pos, player)
                          b2, play_card = self.check_play(pos, player)
                          if b1:
                              hand.remove(card)
                              play.append(card)
                              player.set_play(
                                  player.order_hand(play, self.game.get_round_level(),
                                                    self.game.get_round_trump_suit()))
                              player.set_hand(
                                  player.order_hand(hand, self.game.get_round_level(),
                                                    self.game.get_round_trump_suit()))
  
                          if b2:
                              play.remove(play_card)
                              hand.append(play_card)
                              player.set_play(
                                  player.order_hand(play, self.game.get_round_level(),
                                                    self.game.get_round_trump_suit()))
                              player.set_hand(player.order_hand(hand, self.game.get_round_level(),
                                                                self.game.get_round_trump_suit()))
                  clock.tick(100)
                  surface.blit(background, (0, 0))
  
                  if len(self.game.get_player(0).get_hand()) == 25:
                      self.game.set_is_first_round(True)
                  else:
                      self.game.set_is_first_round(False)
  
                  if len(self.game.get_player(0).get_hand()) == 0:
                      self.game.set_is_last_round(True)
                  else:
                      self.game.set_is_last_round(False)
  
                  if self.game.get_play_in_turn() != NUM_PLAYERS:
  
                      pygame.event.pump()
                      clock.tick(100)
  
                      if len(hand) &lt;= 1:
                          width = 0
                          x = (BG_WIDTH - CARD_WIDTH) // 2
                      elif len(hand) &gt;= 8:
                          width = (BG_WIDTH - SIDE_W - CARD_WIDTH) // (len(hand) - 1)
                          x = BG_WIDTH // 2 - (CARD_WIDTH + (width * (len(hand) - 1))) // 2
                      else:
                          width = CARD_WIDTH
                          x = (BG_WIDTH - (CARD_WIDTH * len(hand))) // 2
  
                      surface.blit(background, (0, 0))
  
                      self.blit_backs()
                      self.blit_round()
  
                      self.show_ok()
  
                      self.show_hand(x, ROW3h, width, hand)
                      self.show_hand(CARD_POSITIONS[0][0], CARD_POSITIONS[0][1], SLIM_WIDTH, play)
  
                      if ok_clicked_2:
                          for card in play:
                              hand.append(card)
  
                          player.set_hand(player.order_hand(hand, self.game.get_round_level(),
                                                            self.game.get_round_trump_suit()))
  
                          # If player is first to start a round, he/she has a different validity check.
                          # (Sets the pattern for the cycle)
  
                          if player.get_begins_cycle():
                              valid = self.game.check_validity(True)  # is_first
                          else:
                              valid = self.game.check_validity(False)  # Is not first to play in the round
  
                          if not valid:  # Clear holding if invalid
                              if (play == []) or (player.get_play() == []):
                                  print(&quot;\nYou must make a play.\n&quot;)
                              else:
                                  print(&quot;Invalid play. Try again.&quot;)
  
                                  if not player.get_begins_cycle():
                                      valid_plays = player.get_valid_plays(self.game.get_pattern(),
                                                                           self.game.get_round_trump_suit())
                                      print(&quot;Valid plays: \n&quot;)
  
                                      for temp_play_idx in range(len(valid_plays)):
                                          temp_play = valid_plays[temp_play_idx]
                                          print(&quot;[&quot;, end='')
                                          for temp_card_idx in range(len(temp_play)):
                                              valid_plays[temp_play_idx][temp_card_idx].show_card(&quot;&quot;, '')
                                              if temp_card_idx != len(temp_play) - 1:
                                                  print(&quot;, &quot;, end='')
                                          print(&quot;]&quot;)
  
                              # Clear the current player's selection and restore hand to its original content
                              cycle_order = self.game.get_cycle_order()
                              cycle = self.game.get_cycle()
                              for player_order in range(len(cycle_order)):
                                  if player == cycle_order[player_order]:
                                      cycle_order.remove(player)
                                      cycle.pop()
                              self.game.set_cycle_order(cycle_order)
                              self.game.set_cycle(cycle)
  
                          else:  # Valid play on submit
                              # Special case for HIGH_SUIT play, play lowest card if another player has greater
                              play = self.game.check_high_suit(play)
  
                              # If friend card played, establish and print teammates
                              # TODO: auto-designate friends if the last round
                              #  has been reached (friends buried in treasure case)
                              # TODO: determine whether friend is &quot;dead&quot;
                              self.game.check_for_friends()
  
                              cycle = self.game.get_cycle()
                              cycle.append(play)
                              self.game.set_cycle(cycle)
  
                              cycle_order = self.game.get_cycle_order()
                              cycle_order.append(player)
                              self.game.set_cycle_order(cycle_order)
  
                              # self.clear_positions()
  
                              for card in play:
                                  hand.remove(card)
  
                              player.set_hand(
                                  player.order_hand(hand, self.game.get_round_level(),
                                                    self.game.get_round_trump_suit()))
  
                              self.game.next_player_turn()
                              self.game.set_play_in_turn(self.game.get_play_in_turn() + 1)
                              print(self.game.get_play_in_turn())
  
                          play = []
  
                  else:
                      self.game.set_play_in_turn(0)
                      # Distribute any points in the round to round winner
                      self.update_cycle_points()
                      for p in self.game.get_players():
                          for card in p.get_play():
                              discard = self.game.get_discard()
                              discard.append(card)
                          p.set_play([])
  
                  pygame.event.clear()
                  clock.tick(100)
                  pygame.display.update()
  
  </code></pre>