Exemple #1
0
   def __init__(self):
      """Create all our pieces in their initial locations"""

      self.checked = False
      self.mated = False

      self.lastMove = None
      self.captured = []

      self.moveResultResaon = "Success"
      self.parsedAlgebraicMoveString = ""
      self.lastMoveString = ""

      rookFiles = "ah"
      knightFiles = "bg"
      bishopFiles = "cf"

      self.parser = AlgebraicParser()
      self.algebraicMoveClass = AlgebraicMove()
      self.parsedAlgebraicMoveClass = AlgebraicMove()
      self.updateMoveValues = False

      self.debug = Debug()

      self.pawns = [Pawn(self.color,file+self.color.pawnRank) for file in Util.files]
      self.rooks = [Rook(self.color,file+self.color.majorRank) for file in rookFiles]
      self.knights = [Knight(self.color,file+self.color.majorRank) for file in knightFiles]
      self.bishops = [Bishop(self.color,file+self.color.majorRank) for file in bishopFiles]
      self.queens = [Queen(self.color,"d"+self.color.majorRank)]
      self.king = King(self.color,"e"+self.color.majorRank)
      #This is a lookup table that is primarily used for captures and un-captures
      self.pieceMap = { "Pawn" : self.pawns,
                        "Rook" : self.rooks,
                        "Knight" : self.knights,
                        "Bishop" : self.bishops,
                        "Queen" : self.queens,
                        "King" : [self.king]}
Exemple #2
0
class Player(object):
   """Base player class"""

   def __init__(self):
      """Create all our pieces in their initial locations"""

      self.checked = False
      self.mated = False

      self.lastMove = None
      self.captured = []

      self.moveResultResaon = "Success"
      self.parsedAlgebraicMoveString = ""
      self.lastMoveString = ""

      rookFiles = "ah"
      knightFiles = "bg"
      bishopFiles = "cf"

      self.parser = AlgebraicParser()
      self.algebraicMoveClass = AlgebraicMove()
      self.parsedAlgebraicMoveClass = AlgebraicMove()
      self.updateMoveValues = False

      self.debug = Debug()

      self.pawns = [Pawn(self.color,file+self.color.pawnRank) for file in Util.files]
      self.rooks = [Rook(self.color,file+self.color.majorRank) for file in rookFiles]
      self.knights = [Knight(self.color,file+self.color.majorRank) for file in knightFiles]
      self.bishops = [Bishop(self.color,file+self.color.majorRank) for file in bishopFiles]
      self.queens = [Queen(self.color,"d"+self.color.majorRank)]
      self.king = King(self.color,"e"+self.color.majorRank)
      #This is a lookup table that is primarily used for captures and un-captures
      self.pieceMap = { "Pawn" : self.pawns,
                        "Rook" : self.rooks,
                        "Knight" : self.knights,
                        "Bishop" : self.bishops,
                        "Queen" : self.queens,
                        "King" : [self.king]}

   def setOpponent(self, player):
      self.otherPlayer = player

   def enableDebug(self, debugEnabled):
      self.debug.enableDebug(debugEnabled)

   def setDebugFileName(self, debugFileName):
      self.debug.setOutputFileName(debugFileName)

   def getAllPieces(self):
      """Return an array of all of my current pieces"""
      return self.pawns + self.rooks + self.knights + self.bishops + self.queens + [self.king]

   def mateCheck(self):
      mated = False
      if self.mated or self.otherPlayer.mated:
         self.moveResultReason = "The game is over."
         mated = True
      return mated

   def generatedAlgebraicMoveIsEqualToGiven(self):
      return self.parsedAlgebraicMoveClass == self.algebraicMoveClass

   def move(self, startCoord, endCoord, promotion=""):
      """Attempt to make a move and return whether the move was possible or not, if this returns false
         the reason for the failure will be in my moveResultReason member"""
      self.debug.startSection("move")
      self.debug.dprint("Two coordinate move attempted.")
      self.lastMoveString = ""
      if self.mateCheck():
         self.debug.dprint("Checkmate detected, game over.")
         return False
      self.updateMoveValues = True
      moveValid = self._movePiece(startCoord, endCoord, promotion)
      if moveValid:
         self.debug.dprint("Checking for check and checkmate.")
         self._postMoveChecks()
         self.algebraicMoveClass.valid = True
         self.parser.setAlgebraicMove(self.algebraicMoveClass)
         self.debug.dprint("Output Algebraic move class:\n", self.algebraicMoveClass)
         self.lastMoveString = self.parser.getAlgebraicMoveString()
         self.debug.dprint("Algebraic move string:", self.lastMoveString)
      self.debug.endSection()
      return moveValid

   def algebraicMove(self, move):
      """Take in a string in algebraic notation and attempt that move"""
      self.debug.startSection("algebraicMove")
      self.debug.dprint("Algebraic move attempted.")
      self.lastMoveString = ""
      if self.mateCheck():
         self.debug.dprint("Checkmate detected, game over.")
         return False
      moveValid = False
      self.parser.setAlgebraicMove(move)
      self.debug.dprint("Incoming Algebraic move string: ", move)
      if self.parser.valid == True:
         algebraicMove = self.parser.getAlgebraicMoveClass()
         #Save off this move class, we can use it as a comparison after the move
         self.parsedAlgebraicMoveClass = algebraicMove
         self.parsedAlgebraicMoveString = self.parser.getAlgebraicMoveString()
         self.debug.dprint("Parsed Algebraic move class:\n", self.parsedAlgebraicMoveClass)
         if algebraicMove.castle:
            promotionPiece = ""
            currentPieceLocation = self.king.position
            if algebraicMove.kingside:
               pieceDestination = self.color.kingsideKingFile + self.color.majorRank
            else:
               pieceDestination = self.color.queensideKingFile + self.color.majorRank
         else:
            potentialPieces = self.getPiecesThatCanMoveToLocation(algebraicMove.piece, algebraicMove.destination, algebraicMove.disambiguation)
            self.debug.dprint("Pieces that can move: ", potentialPieces)
            if len(potentialPieces) == 0:
               self.moveResultReason = "No pieces of that type may move to the selected location"
               self.debug.endSection()
               return moveValid
            elif len(potentialPieces) > 1:
               self.moveResultReason = "More than one piece may move based upon your selection"
               self.debug.endSection()
               return moveValid
            else:
                currentPieceLocation = potentialPieces[0].position
                pieceDestination = algebraicMove.destination
                promotionPiece = algebraicMove.promotion
         self.updateMoveValues = True
         moveValid = self._movePiece(currentPieceLocation, pieceDestination, promotionPiece)
         if moveValid:
            self.debug.dprint("Checking for check and checkmate.")
            self._postMoveChecks()
            self.algebraicMoveClass.valid = True
            self.parser.setAlgebraicMove(self.algebraicMoveClass)
            self.debug.dprint("Output Algebraic move class:\n", self.algebraicMoveClass)
            self.lastMoveString = self.parser.getAlgebraicMoveString()
            self.debug.dprint("Algebraic move string:", self.lastMoveString)

         self.debug.endSection()
         return moveValid
      else:
         self.debug.dprint("Invalid Algebraic move string.")
         self.moveResultReason = "Invalid algebraic notation given."
         self.debug.endSection()
         return False

   def getPiecesThatCanMoveToLocation(self, pieceType, location, disambiguation):
      """Return a list of my pieces that can move to given location, filtered by disambiguation"""
      self.debug.startSection("getPiecesThatCanMoveToLocation")
      self.debug.dprint("Finding piece to move.")
      def canPieceMoveToLocation(piece):
         moves = self.getValidMovesForPiece(piece)
         self.debug.dprint("Piece and it's moves:", piece.position, moves)
         result = True
         if (location not in moves):
            self.debug.dprint("Piece disqualified due to lack of ability to move.")
            result = False
         if disambiguation != "" and disambiguation not in piece.position:
            self.debug.dprint("Piece disqualified due to disambiguation.")
            result = False
         return result
      pieceList = list(filter(canPieceMoveToLocation, self.pieceMap[pieceType]))
      self.debug.endSection()
      return pieceList

   def getValidMovesForPieceAtCoord(self, coord):
      """Return a map of available moves for the piece at the coordinate, move mapped to move type"""
      self.debug.startSection("getValidMovesForPieceAtCoord")
      validMap = {}
      piece = getMyPieceAtLocation(coord)
      if piece:
         self.debug.dprint("Found piece for getting valid moves.")
         validMap = self.getValidMovesForPiece(piece)
      self.debug.endSection()
      return validMap

   def getValidMovesForPiece(self, piece):
      """Return a map of available moves for the piece, move mapped to move type"""
      self.debug.startSection("getValidMovesForPiece")
      self.debug.dprint("Get valid moves for: ", piece.position)
      validMap = {}
      vBoard = VerifyBoard(self.getAllPieces() + self.otherPlayer.getAllPieces())
      if piece and piece.color == self.color:
         validList = piece.getValidMoves(vBoard)
         self.debug.dprint("Valid moves from Piece: ", validList)
         for move in validList:
            validMap[move] = []
            if self._enemyPieceIsAtLocation(move, vBoard):
               self.debug.dprint("Set move as capture:", move)
               validMap[move].append(Util.MoveType.CAPTURE)
            else:
               validMap[move].append(Util.MoveType.NORMAL)
         #En Passant and promotion checking for Pawns
         if type(piece) == Pawn:
            self.debug.dprint("Pawn Specials.")
            capturables = piece.getCaptureCoords()
            for move in capturables:
               if move not in validMap and self.canPawnCaptureEnPassantAtCoord(piece, move):
                  if move not in validMap:
                      self.debug.dprint("Adding new move for pawn for En Passant: ", move)
                      validMap[move] = [];
                      validMap[move].append(Util.MoveType.CAPTURE);
                  self.debug.dprint("Set move as En Passant: ", move)
                  validMap[move].append(Util.MoveType.EN_PASSANT)
            for move in validMap:
               if self.color.promotionRank in move:
                  self.debug.dprint("Set move as Promotion: ", move)
                  validMap[move].append(Util.MoveType.PROMOTION)
         #Now check for Castle Moves
         elif type(piece) == King:
            self.debug.dprint("King Specials.")
            if not piece.moved and not self.checked:
               if self.kingsideCastleIsValid(piece):
                  move = self.color.kingsideKingFile + self.color.majorRank
                  self.debug.dprint("Set move as Kingside Castle: ", move)
                  validMap[move] = []
                  validMap[move].append(Util.MoveType.KINGSIDECASTLE)
               if self.queensideCastleIsValid(piece):
                  move = self.color.queensideKingFile + self.color.majorRank
                  self.debug.dprint("Set move as Queenside Castle: ", move)
                  validMap[move] = []
                  validMap[move].append(Util.MoveType.QUEENSIDECASTLE)
      self.debug.endSection()
      return validMap

   def kingsideCastleIsValid(self, king):
      castleDirection = Util.Castle.KINGSIDE
      return self.castleIsValid(king, castleDirection)

   def queensideCastleIsValid(self, king):
      castleDirection = Util.Castle.QUEENSIDE
      return self.castleIsValid(king, castleDirection)

   def castleIsValid(self, king, direction):
      self.debug.startSection("castleIsValid")
      self.debug.dprint("Checking "+direction+".")
      result = False
      rook = self.findCastlingRook(direction)
      if rook != None:
         self.debug.dprint("Found "+direction+" Rook.")
         if not rook.moved:
            self.debug.dprint(direction+" rook has not moved.")
            #Get the files for the squares between
            files = ""
            if direction == Util.Castle.QUEENSIDE:
               files = Util.files[Util.files.index(rook.position[0])+1:Util.files.index(king.position[0])]
            elif direction == Util.Castle.KINGSIDE:
               files = Util.files[Util.files.index(king.position[0])+1:Util.files.index(rook.position[0])]
            self.debug.dprint("Files to check for pieces: ", files)
            vBoard = VerifyBoard(self.getAllPieces() + self.otherPlayer.getAllPieces())
            if not any(None != vBoard.getPiece(file + self.color.majorRank) for file in files):
               self.debug.dprint("No pieces found in the way.")
               #A quirk of QUEENSIDE is that we do not need to check for file b, so get rid of it
               if direction == Util.Castle.QUEENSIDE:
                  files = files[files.index(self.color.queensideKingFile)-1:]
               #Assume we make it unless we find otherwise at this point
               result = True
               for file in files:
                  nextMove = file+king.position[1]
                  king.move(nextMove)
                  self.debug.dprint(self.color, "Player transferring control to other player to get pieces that can attack our King at: ", self.king.position)
                  if len(self.otherPlayer.getPiecesThatThreatenLocation(king.position)) != 0:
                     self.debug.dprint("Check found attempting to verify castle at:", nextMove)
                     king.undoLastMove()
                     result = False
                     break;
                  king.undoLastMove()
      self.debug.endSection()
      return result

   def findCastlingRook(self, castleDirection):
      foundRook = None
      for rook in self.rooks:
         if rook.castleOption == castleDirection:
            foundRook = rook
            break
      return foundRook

   def clearEnPassant(self):
      """The opponent has just made a move, if we still have EnPassant vulnerable Pawns they are not anymore"""
      [pawn.clearEnPassantVunerable() for pawn in self.pawns if pawn.isEnPassantVulnerable()]

   def canPawnCaptureEnPassantAtCoord(self, pawn, coord):
      """Determine if the destination coordinate is an En Passant capture for the given pawn"""
      if type(pawn) == Pawn:
         possibleEnemyPosition = coord[0] + pawn.position[1]
         vBoard = VerifyBoard(self.getAllPieces() + self.otherPlayer.getAllPieces())
         enemyPiece = vBoard.getPiece(possibleEnemyPosition)
         if type(enemyPiece) == Pawn and enemyPiece.color != pawn.color:
            if enemyPiece.isEnPassantVulnerable():
               return True
            else:
               return False
         else:
            return False
      return False

   def _generateLocator(self,coord):
      """Returns a function that only accepts pieces that are at the specificed coordinate"""
      return lambda piece: piece.position == coord

   def getMyPieceAtLocation(self, coord):
      """This returns my piece at the given location or None if I don't have a piece there"""
      return VerifyBoard(self.getAllPieces()).getPiece(coord)


   def _enemyPieceIsAtLocation(self,coord, vBoard):
      """This checks to see if there is an enemy piece at the position given"""
      result = False
      otherPiece = vBoard.getPiece(coord)
      if otherPiece != None and otherPiece.color != self.color:
         result = True
      return result

   def _movePiece(self, startCoord, endCoord, promotionPieceStr=""):
      """This checks a number of things, it makes sure that we do have a piece at the start location, it makes sure that the requested
         end location is in the physical move set of the peice, it captures an opponent piece at the end location if necessary, and it
         makes sure that the requested move does not expose or leave our king in check. If any of these problem areas arise, it leaves both
         players in their initial state."""
      self.debug.startSection("_movePiece")
      if self.updateMoveValues:
         self.algebraicMoveClass = AlgebraicMove()
         self.algebraicMoveClass.valid = False
         moveClass = self.algebraicMoveClass

      currPieces = filter(self._generateLocator(startCoord), self.getAllPieces())
      self.moveResultReason = "Success"
      previousCheckStatus = self.checked
      for piece in currPieces:
         self.debug.dprint("Found piece at location: ", piece)
         #This is a little weird at first glance
         #It is possible that filter could return more than one piece
         #so what we do is we move the first one found
         self.generateMovePiece(piece)
         validMoves = self.getValidMovesForPiece(piece)
         self.debug.dprint("Valid moves for piece: ", validMoves)
         if endCoord in validMoves:
            self.generateDisambiguation(piece, endCoord)
            self.generateDestination(endCoord)
            capturePiece = None
            promotionPiece = None
            castledRook = None
            if Util.MoveType.EN_PASSANT in validMoves[endCoord]:
               #We know that this is a pawn now
               self.debug.dprint("En Passant Capture move.")
               self.generateCapture(piece, True)
               capturePiece = self.capture(endCoord[0]+piece.position[1])
               self.debug.dprint("En Passant Captured piece: ", capturePiece)
            elif Util.MoveType.CAPTURE in validMoves[endCoord]:
               self.debug.dprint("Capture move.")
               self.generateCapture(piece, True)
               capturePiece = self.capture(endCoord)
               self.debug.dprint("Captured piece: ", capturePiece)
            elif Util.MoveType.KINGSIDECASTLE in validMoves[endCoord]:
               self.debug.dprint("Kingside Castle move.")
               self.generateCastle(Util.Castle.KINGSIDE)
               castledRook = self.findCastlingRook(Util.Castle.KINGSIDE)
               castledRook.move(self.color.kingsideRookMoveFile+self.color.majorRank)
            elif Util.MoveType.QUEENSIDECASTLE in validMoves[endCoord]:
               self.debug.dprint("Queenside Castle move.")
               self.generateCastle(Util.Castle.QUEENSIDE)
               castledRook = self.findCastlingRook(Util.Castle.QUEENSIDE)
               castledRook.move(self.color.queensideRookMoveFile+self.color.majorRank)
            piece.move(endCoord)
            self.moveResultReason = piece.moveResultReason
            #Go ahead and set the last move, minus any promotion piece, so that we can do an undo if promotion falls through
            self.lastMove = PlayerLastMove(piece, pieceCaptured = capturePiece, rookCastled = castledRook)
            if Util.MoveType.PROMOTION in validMoves[endCoord]:
               if promotionPieceStr not in Util.pieces or promotionPieceStr == "Pawn" or promotionPieceStr == "King":
                  self.debug.dprint("Invalid promotion move.")
                  self.undoLastMove()
                  self.moveResultReason = "No valid piece given to promote to."
                  self.debug.endSection()
                  return False
               self.debug.dprint("Valid promotion move.")
               self.generatePromotion(promotionPieceStr)
               promotionPiece = globals()[promotionPieceStr](self.color, endCoord)
               self.debug.dprint("Pawn: ", id(piece))
               pieceList = self.pieceMap[piece.piece]
               pieceList.remove(piece)
               self.debug.dprint("Pawn list: ", getIds(pieceList))
               self.debug.dprint("Promotion piece: ", promotionPieceStr, id(promotionPiece))
               promotionPieceList = self.pieceMap[promotionPiece.piece]
               promotionPieceList.append(promotionPiece)
               self.debug.dprint("Promotion piece list: ", getIds(promotionPieceList))
            self.lastMove = PlayerLastMove(piece, pieceCaptured = capturePiece, piecePromoted = promotionPiece, rookCastled = castledRook)
            self.debug.dprint("Last Move: ", self.lastMove)
            if self.verifyCheck():
               self.debug.dprint("That move placed us in check.")
               self.undoLastMove()
               if previousCheckStatus:
                  self.moveResultReason = "That move does not resolve the check!"
               else:
                  self.moveResultReason = "That move results in check!"
               self.debug.endSection()
               return False
            self.debug.endSection()
            return True
         else:
            self.moveResultReason = "The end square is not in the valid move range of this piece."
            pass
         self.debug.endSection()
         return False
      self.moveResultReason = "No piece found at that start square."
      self.debug.endSection()
      return False

   def _testMove(self, startCoord, endCoord):
      """We are just testing to see if a move is valid, we do not care if it affects the other player,
         and we want it to have no lasting impact on the board"""
      self.debug.startSection("_testMove")
      savedSetting = self.updateMoveValues
      self.updateMoveValues = False
      self.debug.dprint("Disabling algebraic move generation")
      testMoveValid = self._movePiece(startCoord, endCoord)
      if testMoveValid:
         self.debug.dprint("Move succeeded, undoing.")
         self.undoLastMove()
      self.updateMoveValues = savedSetting
      self.debug.dprint("Algebraic move generation restored to: ", self.updateMoveValues)
      self.debug.endSection()
      return testMoveValid

   def _postMoveChecks(self):
      """Run and checks after a move is completed successfully"""
      self.debug.startSection("_postMoveChecks")
      self.debug.dprint(self.color, "Player Post move checking, transfer control to other player to check and see if they are checked or mated.")
      self.otherPlayer.verifyCheck()
      self.otherPlayer.verifyMate()
      self.generateCheckMate(self.otherPlayer.checked, self.otherPlayer.mated)
      self.debug.dprint(self.color, "Player Post move checking, transfer control to other player to clear EnPassant Vulnerable Pawns.")
      self.otherPlayer.clearEnPassant()
      self.debug.endSection()

   def generateDisambiguation(self, piece, destination):
      """If required, based upon instance variable, generate the disambiguation string"""
      if self.updateMoveValues:
         #We need the file if that works, the rank if the file does not, and both if neither is sufficient
         pieces = self.getPiecesThatCanMoveToLocation(piece.piece, destination, "")
         pieces.remove(piece)
         if len(pieces) > 0:
            fileAndRank = piece.position
            otherPositions = []
            for otherPiece in pieces:
               otherPositions.append(otherPiece.position)
            if any(fileAndRank[0] not in position for position in otherPositions):
               self.algebraicMoveClass.disambiguation = fileAndRank[0]
            elif any(fileAndRank[1] not in position for position in otherPositions):
               self.algebraicMoveClass.disambiguation = fileAndRank[1]
            else:
               self.algebraicMoveClass.disambiguation = piece.position
         else:
            #This is the only piece that can move here, no disambiguation needed
            self.algebraicMoveClass.disambiguation = ""

   def generateMovePiece(self, piece):
      """If required, generate the piece string for the piece to be moved"""
      if self.updateMoveValues:
         self.algebraicMoveClass.piece = piece.piece

   def generateDestination(self, coord):
      """If required, generate the destination coordinate for the move"""
      if self.updateMoveValues:
         self.algebraicMoveClass.destination = coord

   def generateCapture(self, piece, captureHappened):
      """If required, generate the capture status for the move"""
      if self.updateMoveValues:
         self.algebraicMoveClass.capture = captureHappened
         if captureHappened and type(piece) == Pawn:
            #Pawns need to specify their file as disambiguation when capturing
            self.algebraicMoveClass.disambiguation = piece.position[0]

   def generateCheckMate(self, checkStatus, mateStatus):
      """If required, generate the check and mate status for the move"""
      if self.updateMoveValues:
         self.algebraicMoveClass.check = checkStatus
         self.algebraicMoveClass.mate = mateStatus

   def generatePromotion(self, promotion):
      """If required, generate the promotion piece for the move"""
      if self.updateMoveValues:
         if promotion in Util.pieces:
            self.algebraicMoveClass.promotion = promotion
         elif promotion in Util.invPieces:
            self.algebraicMoveClass.promotion = Util.invPieces[promotion]
         else:
            self.algebraicMoveClass.promotion = ""

   def generateCastle(self, direction):
      if self.updateMoveValues:
         self.algebraicMoveClass.castle = True
         self.algebraicMoveClass.kingside = direction == Util.Castle.KINGSIDE


   def undoLastMove(self):
      """Undo the previous move"""
      self.debug.startSection("undoLastMove")
      if self.lastMove != None:
         self.debug.dprint("Valid last move to undo detected: ", self.lastMove)
         self.lastMove.pieceMoved.undoLastMove()
         if self.lastMove.pieceCaptured != None:
            self.captured.remove(self.lastMove.pieceCaptured)
            self.otherPlayer.returnPiece(self.lastMove.pieceCaptured)
         if self.lastMove.piecePromoted != None:
            #We are undoing a promotion, special things need to happen
            pieceList = self.pieceMap[self.lastMove.pieceMoved.piece]
            pieceList.append(self.lastMove.pieceMoved)
            promotionPieceList = self.pieceMap[self.lastMove.piecePromoted.piece]
            promotionPieceList.remove(self.lastMove.piecePromoted)
         if self.lastMove.rookCastled != None:
            self.lastMove.rookCastled.undoLastMove()
         self.lastMove = None
         #It is almost guaranteed that we could undo back into a check position. Because of that, run
         #the verify to update our state properly
         self.verifyCheck()
         self.debug.dprint("Verifying/setting check status after undo: ", self.checked)
         self.debug.endSection()
         return True
      self.debug.endSection()
      return False

   def capture(self, coord):
      """Capture the piece from the other player at the given coordinate"""
      self.debug.startSection("capture")
      vBoard = VerifyBoard(self.getAllPieces()+self.otherPlayer.getAllPieces())
      capturePiece = vBoard.getPiece(coord)
      self.debug.dprint("Piece to capture: ", id(capturePiece))
      self.debug.dprint(self.color, "Player transferring control to other to get captured piece")
      self.otherPlayer.giveCapturedPiece(capturePiece)
      self.captured.append(capturePiece)
      self.debug.dprint("New capture list: ", getIds(self.captured))
      self.debug.endSection()
      return capturePiece

   def giveCapturedPiece(self, piece):
      """Remove the selected piece from our list and return it"""
      self.debug.startSection("capture")
      #I cannot simply use the all pieces API because that returns a new list
      # and I need to get these pieces where they live
      pieceList = self.pieceMap[piece.piece]
      self.debug.dprint("Piece list prior to giving: ", piece, getIds(pieceList))
      self.debug.dprint("Piece removed: ", id(piece))
      capturedPiece = pieceList.pop(pieceList.index(piece))
      self.debug.dprint("New piece list: ", getIds(pieceList))
      self.debug.endSection()
      return capturedPiece

   def returnPiece(self, piece):
      """Add the given piece to our lists"""
      #I cannot simply use the all pieces API because that returns a new list
      #and I need to get these pieces where they live"""
      self.pieceMap[piece.piece].append(piece)

   def getPiecesThatThreatenLocation(self, location):
      """Return a list of my pieces that can capture the piece at the given location"""
      def canPieceAttackLocation(piece):
         moves = self.getValidMovesForPiece(piece)
         if location in moves and Util.MoveType.CAPTURE in moves[location]:
            return True
      return list(filter(canPieceAttackLocation, self.getAllPieces()))

   def verifyCheck(self):
      """Check to see if I am checked, and update my flag as appropriate"""
      self.debug.startSection("verifyCheck")
      self.debug.dprint(self.color, "Player transferring control to other player to get pieces that can attack our King at: ", self.king.position)
      if len(self.otherPlayer.getPiecesThatThreatenLocation(self.king.position)) != 0:
         self.checked = True
      else:
         self.checked = False
         self.mated = False
      self.debug.dprint("Our checked status: ", self.checked)
      self.debug.endSection()
      return self.checked

   def verifyMate(self):
      """Check to see if I am mated, and update my flag as appropriate"""
      self.debug.startSection("verifyMate")
      if self.checked:
         #Get the attacking pieces to start off with"""
         self.debug.dprint(self.color, "Player transferring control to other player to get pieces that can attack our King at: ", self.king.position)
         attackingPieces = self.otherPlayer.getPiecesThatThreatenLocation(self.king.position)
         numberOfAttackers = len(attackingPieces)
         self.debug.dprint("Number of pieces attacking our King: ", numberOfAttackers)
         if numberOfAttackers == 0:
            self.checked = False
            self.mated = False
         else:
            #Assume mated unless proven otherwise"""
            self.mated = True
            #Always check to see if we can just move the king away"""
            kingCanMove = False
            self.debug.dprint("Getting all valid moves for the king and trying them.")
            kingMovements = self.getValidMovesForPiece(self.king)
            for move in kingMovements:
                  if self._testMove(self.king.position, move):
                     kingCanMove = True
                     self.mated = False
                     break

            if numberOfAttackers == 1 and not kingCanMove:
               #We only check other pieces to see if they can interfere if there is only one attacker,
               #I believe that there are no cases where two or more attacking pieces can be stopped by
               #anything other than moving the king
               self.debug.dprint("The king is stuck, try moving all other pieces into the path of the one attacker.")
               attacker = attackingPieces[0]
               vBoard = VerifyBoard(self.getAllPieces() + self.otherPlayer.getAllPieces())
               pathToKing = attacker.getPath(self.king.position, vBoard)

               #Now get all of my pieces minus the king, we have already taken care of his movements
               myPieces = self.getAllPieces()
               myPieces.pop() #here we use the fact that the king is added last as a quick way of removing him
               for piece in myPieces:
                  for coord in pathToKing:
                     if self._testMove(piece.position, coord):
                        self.mated = False
                        break
      else:
         self.debug.dprint("Not checked.")
         self.mated = False
      self.debug.dprint("Our mated status: ", self.mated)
      self.debug.endSection()
      return self.mated