title: Python Checkers Multiple Jumps not Working Properly
body: <p>I am implementing the last feature of my Python Checkers Game, which is to require the user to make multiple jumps. For captures, I do the following:</p>
  
  <pre><code>1 Check if the move is valid:
  2     self.validatedMove = True (The move that has been made is valid.)
  3     self.capture() (Captures the piece given a correct user move)
  4     How would I implement multiple jumps? I have tried researching for captures
        and then calling the capture function until there are no more captures left.
  </code></pre>
  
  <p>But it ends up being stuck in an infinite loop!                </p>
  
  <pre><code>#when Red piece is not a king and piece can jump right      
  if (self.turn == 'Red' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'right'):
  if (self.newPosition[0] == self.position[0] + 2 and self.newPosition[1] == self.position[1] + 2):
      self.validatedMove = True
      self.capture()
  
      #Stuck in an infinite loop
      while (len(captureDirections) &gt; 0):
          self.captureDirections = []
          self.search_capture()
          self.capture()
  </code></pre>
  
  <p>Here is the full code:</p>
  
  <pre><code>from tkinter import *
  
  class CheckerSquare(Canvas):
  
      def __init__(self, master, row, column, color):
  
          Canvas.__init__(self, master, width=50, height=50, bg=color)
          self.grid(row=row, column=column)
  
          self.position = (row, column)
          self.color = None
          self.isKing = False
  
          self.bind('&lt;Button&gt;', master.place_piece)
  
      def get_position(self):
  
          return self.position
  
      def get_color(self):
  
          return self.color
  
      def create_piece(self, color):
  
          self.create_oval(10,10,44,44,fill=color, outline=color) 
          self.color = color  
  
      def create_king(self):
  
          self.isKing = True
          self.create_text(10, 15, text="*", font=("Garamond", 14), fill="#80FF80")
  
      def is_king(self):
  
          return self.isKing
  
  class CheckerGame(Frame):
  
      def __init__(self, master):
  
          Frame.__init__(self, master, bg='White') 
          self.grid()
  
          self.squares = {}
  
          self.turn = 'Red'
  
          self.clicks = 0
          self.position = ()
          self.newPosition = ()
          self.jump = False
          self.validatedMove = False
  
          self.captureDirection = None
          self.captureDirections = []
  
          self.over = False
  
          self.turnIcon = CheckerSquare(self, 9, 2, "#B8B8B8")
          self.turnIcon.grid()
          self.turnIcon.create_piece(self.turn)
  
          self.turnLabel = Label(self, text = "Turn: ", font = ('Courier New', 8), bg='White')
          self.turnLabel.grid(row=9, column=1)
  
          self.directionLabel = Label(self, text="", font = ('Courier New', 8), bg='White')
          self.directionLabel.grid(row=9, column=4, columnspan=4, sticky=W)
  
          # Create the checker squares on the board
          for row in range(8): 
             for col in range(8):
                  if (row % 2 == 0 and col % 2 == 0 or row % 2 == 1 and col % 2 == 1):
                      self.squares[(row,col)] = CheckerSquare(self, row, col, 'blanched almond')
                  else:
                      self.squares[(row,col)] = CheckerSquare(self, row, col, 'dark green')
  
          # Draw the red pieces
          for i in range(3):
              for n in range(4):
                  if (i % 2 == 0):
                      self.squares[(i, 2*n+1)].create_piece('Red')
                  else:
                      self.squares[(i,2*n)].create_piece('Red')
  
          # Draw the white pieces
          for i in range(5, 8):
              for n in range(4):
                  if (i % 2 == 0): 
                      self.squares[(i,2*n+1)].create_piece('White')
                  else:
                      self.squares[(i,2*n)].create_piece('White')
  
      def winnerCheck(self):
          #Detects winner if all pieces on red or white are gone
          redPieces = 0
          whitePieces = 0
  
          for row in range(8):
              for column in range(8):
                  squareColor = self.squares[row, column].get_color()
                  if (squareColor == 'Red'):
                      redPieces += 1
                  if (squareColor == 'White'):
                      whitePieces += 1
  
          if (redPieces == 0 and self.turn == 'Red'): #No red pieces left - white wins
              self.over = True
              self.directionLabel["text"] = 'Game Over - White Wins!'
  
          if (whitePieces == 0 and self.turn == 'White'): #No white pieces left - red wins
              self.over = True
              self.directionLabel["text"] = 'Game Over - Red Wins!'
  
      def update(self, turn):
          self.squares[self.position].create_piece('dark green') #clears previous square
          self.squares[self.position].color = None #updates color
          self.squares[self.newPosition].create_piece(turn) #updates piece position
          self.validatedMove = True #move is valid
  
      def capture(self):
  
              if (len(self.captureDirections) == 1):
  
                  if (self.squares[self.position].get_color() == 'Red' and self.captureDirection == 'right'):
                      self.update('Red')
                      self.squares[self.position[0]+1, self.position[1]+1] = CheckerSquare(self, self.position[0]+1, self.position[1]+1, 'dark green')
                      self.squares[self.position[0]+1, self.position[1]+1].color = None
  
                  if (self.squares[self.position].get_color() == 'Red' and self.captureDirection == 'left'):
                      self.update('Red')
                      self.squares[self.position[0]+1, self.position[1]-1] = CheckerSquare(self, self.position[0]+1, self.position[1]-1, 'dark green')
                      self.squares[self.position[0]+1, self.position[1]-1].color = None
  
                  if (self.squares[self.position].get_color() == 'White' and self.captureDirection == 'right'):
                      self.update('White')
                      self.squares[self.position[0]-1, self.position[1]+1] = CheckerSquare(self, self.position[0]-1, self.position[1]+1, 'dark green')
                      self.squares[self.position[0]-1, self.position[1]+1].color = None
  
                  if (self.squares[self.position].get_color() == 'White' and self.captureDirection == 'left'):
                      self.update('White')
                      self.squares[self.position[0]-1, self.position[1]-1] = CheckerSquare(self, self.position[0]-1, self.position[1]-1, 'dark green')
                      self.squares[self.position[0]-1, self.position[1]-1].color = None
  
              if (len(self.captureDirections) == 2 and self.squares[self.position].is_king() == False):
  
                  if (self.squares[self.position].get_color() == 'White'):
                      self.update('White')
                      if (self.position[0]&gt;0 and self.position[1]&lt;7 and self.squares[self.position[0]-1, self.position[1]+1].get_color() == 'Red'):
                          self.squares[self.position[0]-1, self.position[1]+1] = CheckerSquare(self, self.position[0]-1, self.position[1]+1, 'dark green')
                          self.squares[self.position[0]-1, self.position[1]+1].color = None
  
                      if (self.position[0]&gt;0 and self.position[1]&gt;0 and self.squares[self.position[0]-1, self.position[1]-1].get_color() == 'Red'):
                          self.squares[self.position[0]-1, self.position[1]-1] = CheckerSquare(self, self.position[0]-1, self.position[1]-1, 'dark green')
                          self.squares[self.position[0]-1, self.position[1]-1].color = None
  
                  if (self.squares[self.position].get_color() == 'Red'):
                      self.update('Red')
                      if (self.position[0]&lt;7 and self.position[1]&lt;7 and self.squares[self.position[0]+1, self.position[1]+1].get_color() == 'White'):
                          self.squares[self.position[0]+1, self.position[1]+1] = CheckerSquare(self, self.position[0]+1, self.position[1]+1, 'dark green')
                          self.squares[self.position[0]+1, self.position[1]+1].color = None
  
                      if (self.position[0]&lt;7 and self.position[1]&gt;0 and self.squares[self.position[0]+1, self.position[1]-1].get_color() == 'White'):
                          self.squares[self.position[0]+1, self.position[1]-1] = CheckerSquare(self, self.position[0]+1, self.position[1]-1, 'dark green')
                          self.squares[self.position[0]+1, self.position[1]-1].color = None
  
              if (self.squares[self.position].is_king() == True):
  
                  if (len(self.captureDirections) == 1):
  
                      if (self.squares[self.position].get_color() == 'White' and self.captureDirections[0] == 'backward right'):
                          self.update('White')
                          self.squares[self.position] = CheckerSquare(self, self.position[0], self.position[1], 'dark green')
                          self.squares[self.position[0]+1, self.position[1]+1] = CheckerSquare(self, self.position[0]+1, self.position[1]+1, 'dark green')
                          self.squares[self.position[0]+1, self.position[1]+1].color = None
                          self.squares[self.newPosition].create_king()
  
                      if (self.squares[self.position].get_color() == 'White' and self.captureDirections[0] == 'backward left'):
                          self.update('White')
                          self.squares[self.position] = CheckerSquare(self, self.position[0], self.position[1], 'dark green')
                          self.squares[self.position[0]+1, self.position[1]-1] = CheckerSquare(self, self.position[0]+1, self.position[1]-1, 'dark green')
                          self.squares[self.position[0]+1, self.position[1]-1].color = None
                          self.squares[self.newPosition].create_king()
  
                      if (self.squares[self.position].get_color() == 'Red' and self.captureDirections[0] == 'backward right'):
                          self.update('Red')
                          self.squares[self.position] = CheckerSquare(self, self.position[0], self.position[1], 'dark green')
                          self.squares[self.position[0]-1, self.position[1]+1] = CheckerSquare(self, self.position[0]-1, self.position[1]+1, 'dark green')
                          self.squares[self.position[0]-1, self.position[1]+1].color = None
                          self.squares[self.newPosition].create_king()
  
                      if (self.squares[self.position].get_color() == 'Red' and self.captureDirections[0] == 'backward left'):
                          self.update('Red')
                          self.squares[self.position] = CheckerSquare(self, self.position[0], self.position[1], 'dark green')
                          self.squares[self.position[0]-1, self.position[1]-1] = CheckerSquare(self, self.position[0]-1, self.position[1]-1, 'dark green')
                          self.squares[self.position[0]-1, self.position[1]-1].color = None
                          self.squares[self.newPosition].create_king()
  
              self.jump = False
  
      def search_capture(self):
          #Capture
          for row in range(8):
              for col in range(8):
                  squareColor = self.squares[(row, col)].get_color()
  
                  #Left Capture - Red
                  if (self.turn == 'Red' and col &gt;= 2 and row &lt;= 5 and squareColor == 'Red' and self.squares[(row + 1, col - 1)].get_color() == 'White' and \
                      self.squares[(row + 2, col - 2)].get_color() == None):
                      self.captureDirection = 'left'
                      self.captureDirections.append('left')
                      self.jump = True
  
                  #Right Capture - Red
                  if (self.turn == 'Red' and col &lt;= 5 and row &lt;= 5 and squareColor == 'Red' and self.squares[(row + 1, col + 1)].get_color() == 'White' and \
                      self.squares[(row + 2, col + 2)].get_color() == None):
                      self.captureDirection = 'right'
                      self.captureDirections.append('right')
                      self.jump = True
  
                  #Capture for Left - White 
                  if self.turn == 'White' and col &gt;= 2 and row &gt;= 2 and squareColor == 'White' and self.squares[(row - 1, col - 1)].get_color() == 'Red' and \
                      self.squares[(row - 2, col - 2)].get_color() == None:
                      self.captureDirection = 'left'
                      self.captureDirections.append('left')
                      self.jump = True
  
                  #Right Capture - White
                  if (self.turn == 'White' and col &lt;= 5 and row &gt;= 2 and squareColor == 'White' and self.squares[(row - 1, col + 1)].get_color() == 'Red' and \
                      self.squares[(row - 2, col + 2)].get_color() == None):
                      self.captureDirection = 'right'
                      self.captureDirections.append('right')
                      self.jump = True
  
                  if (self.squares[(row, col)].is_king() == True):
  
                      #Backwards Left Capture - Red King
                      if self.turn == 'Red' and col &gt;= 2 and row &gt;= 2 and squareColor == 'Red' and self.squares[(row - 1, col - 1)].get_color() == 'White' and \
                          self.squares[(row - 2, col - 2)].get_color() == None:
                          self.captureDirection = 'backward left'
                          self.captureDirections.append('backward left')
                          self.jump = True
  
                      #Backwards Right Capture - Red King
                      if (self.turn == 'Red' and col &lt;= 5 and row &gt;= 2 and squareColor == 'Red' and self.squares[(row - 1, col + 1)].get_color() == 'White' and \
                          self.squares[(row - 2, col + 2)].get_color() == None):
                          self.captureDirection = 'backward right'
                          self.captureDirections.append('backward right')
                          self.jump = True
  
                      #Backwards Left Capture - White King
                      if (self.turn == 'White' and col &gt;= 2 and row &lt;= 5 and squareColor == 'White' and self.squares[(row + 1, col - 1)].get_color() == 'Red' and \
                          self.squares[(row + 2, col - 2)].get_color() == None):
                          self.captureDirection = 'backward left'
                          self.captureDirections.append('backward left')
                          self.jump = True
  
                      #Backwards Right Capture - White King
                      if (self.turn == 'White' and col &lt;= 5 and row &lt;= 5 and squareColor == 'White' and self.squares[(row + 1, col + 1)].get_color() == 'Red' and \
                          self.squares[(row + 2, col + 2)].get_color() == None):
                          self.captureDirection = 'backward right'
                          self.captureDirections.append('backward right')
                          self.jump = True
  
      def place_piece(self, event):
          if (self.over == False):           
              self.validatedMove = False
              #Program needs to check the current move
  
              #Adds to number of clicks
              self.clicks += 1
  
              #First stage of click (selecting a piece)
              if (self.clicks % 2 == 1):
                  self.captureDirections = []
  
                  if event.widget.get_color() == 'Red' or event.widget.get_color() == 'White':
                      self.position = event.widget.get_position() #retrieve position of selected piece
  
                      if (self.turn == self.squares[self.position].get_color()):
                          self.squares[self.position]['highlightbackground'] = 'black' #outline
                      else:
                          self.directionLabel['text'] = "It is " + self.turn + "'s turn!"
  
                      self.search_capture()      
  
              else: #second stage of click (moves piece to selected position)
                  self.newPosition = event.widget.get_position()
  
                  self.squares[self.position]['highlightbackground'] = 'White' #clears outline
  
                  #when Red piece is not a king and the piece cannot jump
                  if (self.turn == 'Red' and self.jump == False):
                      if (self.newPosition[0] == self.position[0] + 1 and self.newPosition[1] == self.position[1] + 1 and self.squares[self.newPosition].get_color() == None \
                          or self.newPosition[0] == self.position[0] + 1 and self.newPosition[1] == self.position[1] - 1 and self.squares[self.newPosition].get_color()  == None):
                          self.update('Red')
                          self.directionLabel['text'] = "" #clears error message
                          self.validatedMove = True
                      else: 
                          self.directionLabel['text'] = "Invalid Move!" #error message
  
                  #when White piece is not a king and piece cannot jump
                  if (self.turn == 'White' and self.jump == False):
                      if (self.newPosition[0] == self.position[0] - 1 and self.newPosition[1] == self.position[1] + 1 and self.squares[self.newPosition].get_color() == None \
                          or self.newPosition[0] == self.position[0] - 1 and self.newPosition[1] == self.position[1] - 1 and self.squares[self.newPosition].get_color() == None):
                          self.update('White')
                          self.directionLabel['text'] = "" #clears error message
                          self.validatedMove = True
                      else:
                          self.directionLabel['text'] = "Invalid Move!" #error message
  
                  #when Red piece is not a king and piece can jump right      
                  if (self.turn == 'Red' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'right'):
                      if (self.newPosition[0] == self.position[0] + 2 and self.newPosition[1] == self.position[1] + 2):
                          self.validatedMove = True
                          self.capture()
  
                          while (len(captureDirections) &gt; 0):
                              self.captureDirections = []
                              self.search_capture()
                              self.capture()
  
                  #when Red piece is not a king and piece can jump left
                  if (self.turn == 'Red' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'left'):
                      if (self.newPosition[0] == self.position[0] + 2 and self.newPosition[1] == self.position[1] - 2):
                          self.validatedMove = True
                          self.capture()
  
                  #when White piece is not a king and piece can jump right
                  if (self.turn == 'White' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'right'):
                      if (self.newPosition[0] == self.position[0] - 2 and self.newPosition[1] == self.position[1] + 2):
                          self.validatedMove = True
                          self.capture()
  
                  #when White piece is not a king and piece can jump left
                  if (self.turn == 'White' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'left'):
                      if (self.newPosition[0] == self.position[0] - 2 and self.newPosition[1] == self.position[1] - 2):
                          self.validatedMove = True
                          self.capture()
  
                  #when White piece is not a king and can capture both directions
                  if (self.turn == 'White' and self.jump == True and len(self.captureDirections) == 2):
                      if (self.newPosition[0] == self.position[0] - 2 and self.newPosition[1] == self.position[1] + 2 or self.newPosition[1] == self.position[1] - 2):
                          self.validatedMove = True
                          self.capture()
  
                  #when Red piece is not a king and can capture both directions
                  if (self.turn == 'Red' and self.jump == True and len(self.captureDirections) == 2):
                      if (self.newPosition[0] == self.position[0] + 2 and self.newPosition[1] == self.position[1] + 2 or self.newPosition[1] == self.position[1] - 2):
                          self.validatedMove = True
                          self.capture()
  
                  if (self.squares[self.position].is_king() == True):
  
                      #when Red piece is a king and the piece cannot jump
                      if (self.turn == 'Red' and self.jump == False):
                          if (self.newPosition[0] == self.position[0] - 1 and self.newPosition[1] == self.position[1] + 1 and self.squares[self.newPosition].get_color() == None \
                              or self.newPosition[0] == self.position[0] - 1 and self.newPosition[1] == self.position[1] - 1 and self.squares[self.newPosition].get_color() == None):
                              self.update('Red')
                              self.squares[self.position] = CheckerSquare(self, self.position[0], self.position[1], 'dark green')
                              self.squares[self.newPosition].create_king()
                              self.directionLabel['text'] = "" #clears error message
                              self.validatedMove = True
                          else:
                              self.directionLabel['text'] = "Invalid Move!" #error message
  
                      #when White piece is a king and the piece cannot jump
                      if (self.turn == 'White' and self.jump == False):
                          if (self.newPosition[0] == self.position[0] + 1 and self.newPosition[1] == self.position[1] + 1 and self.squares[self.newPosition].get_color() == None \
                              or self.newPosition[0] == self.position[0] + 1 and self.newPosition[1] == self.position[1] - 1 and self.squares[self.newPosition].get_color()  == None):
                              self.update('White')
                              self.squares[self.position] = CheckerSquare(self, self.position[0], self.position[1], 'dark green')
                              self.squares[self.newPosition].create_king()
                              self.directionLabel['text'] = "" #clears error message
                              self.validatedMove = True
                          else:
                              self.directionLabel['text'] = "Invalid Move!" #error message
  
                      #when Red piece is a king and the piece can jump backward left
                      if (self.turn == 'Red' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'backward left'):
                          self.capture()
                          self.validatedMove = True
  
                      #when Red piece is a king and the piece can jump backward right
                      if (self.turn == 'Red' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'backward right'):
                          self.capture()
                          self.validatedMove = True
  
                      #when White piece is a king and the piece can jump backward left
                      if (self.turn == 'White' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'backward left'):
                          self.capture()
                          self.validatedMove = True
  
                      #when White piece is a king and the piece can jump backward right
                      if (self.turn == 'White' and self.jump == True and len(self.captureDirections) == 1 and self.captureDirection == 'backward right'):
                          self.capture()
                          self.validatedMove = True
  
                  #Checks for king
                  if (self.turn == 'Red' and self.validatedMove == True and self.newPosition[0] == 7):
                      self.squares[self.newPosition].create_king()
  
                  if (self.turn == 'White' and self.validatedMove == True and self.newPosition[0] == 0):
                      self.squares[self.newPosition].create_king()
  
                  #changes turn
                  if (self.validatedMove == True):
                      if (self.turn == 'Red'):
                          self.turn = 'White'
  
                      elif (self.turn == 'White'):
                          self.turn = 'Red'
  
                  #updates player turn icon
                  self.turnIcon.create_piece(self.turn)
  
                  self.winnerCheck() #Checks for winner
  
  def play_checkers():
      root = Tk() 
      root.title('Python Checkers')
      CG = CheckerGame(root) 
      CG.mainloop()
  
  play_checkers() 
  </code></pre>