По какой-то причине он не запускает код Черной пешки. Почему он это делает?
Я использую Pycharm 2020 community в качестве IDE. Я использую pygame 1.9.6 для игры в шахматы. Я использую Python 3.7.4.
Когда я пытаюсь сделать правильный ход пешкой после того, как белые делают ход пешкой, ничего не происходит. Я даже делаю трюк, когда вы ставите отпечаток("здесь"), чтобы увидеть, достигает ли код, но это не так. Положим, если я делаю 3+ пешечных хода, то я нажимаю отменить все, нажав "u" 3 раза, а затем он говорит "здесь" после этого, но когда я иду, чтобы сделать ход черной пешки, ничего не происходит или сначала белая пешка движется, а затем черная ничего не делает. Я не знаю, почему мой код не достигает его.
Код:
import pygame as p from Chess import ChessEngine WIDTH = HEIGHT = 512 # 400 is another option DIMENSION = 8 # dimensions of a chess board are 8x8 SQ_SIZE = HEIGHT // DIMENSION MAX_FPS = 15 # for animations later on IMAGES = {} ''' Initialize a global dictionary of images. This will be called exactly once in the main ''' class GameState: def __init__(self): # board is an 8x8 2d list, each element of lest has 2 character. # The first character represents the color of the piece, "b" or "w" # The second character represents the type of the piece, "K", "Q", "R", "B", "N", or "p" # "--" - represents an empty space with no piece. self.board = [ ["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"], ["bp", "bp", "bp", "bp", "bp", "bp", "bp", "bp"], ["--", "--", "--", "--", "--", "--", "--", "--"], ["--", "--", "--", "--", "--", "--", "--", "--"], ["--", "--", "--", "--", "--", "--", "--", "--"], ["--", "--", "--", "--", "bp", "--", "--", "--"], ["wp", "wp", "wp", "wp", "wp", "wp", "wp", "wp"], ["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]] self.moveFunctions = {'p': self.getPawnMoves, 'R': self.getRookMoves, 'N': self.getKnightMoves, 'B': self.getBishopMoves, 'Q': self.getQueenMoves, 'K': self.getKingMoves} self.whiteToMove = True self.moveLog = [] ''' Takes a Move as a parameter and executes it (this will not work for castling, pawn promotion, and en passant ''' def makeMove(self, move): self.board[move.startRow][move.startCol] = "--" self.board[move.endRow][move.endCol] = move.pieceMoved self.moveLog.append(move) # log the move so we can undo it later self.whiteToMove = not self.whiteToMove # swap players ''' Undo the last move ''' def undoMove(self): if len(self.moveLog) != 0: # make sure there is a move to undo move = self.moveLog.pop() self.board[move.startRow][move.startCol] = move.pieceMoved self.board[move.endRow][move.endCol] = move.pieceCaptured self.whiteToMove = not self.whiteToMove # switch turns back ''' All moves considering checks ''' def getValidMoves(self): return self.getAllPossibleMoves() # for now will not worry about checks ''' All moves without considering checks ''' def getAllPossibleMoves(self): moves = [] for r in range(len(self.board)): # number of rows for c in range(len(self.board[r])): # number of cols in given row turn = self.board[r][c][0] if (turn == 'w' and self.whiteToMove) or (turn == 'b' and not self.whiteToMove): piece = self.board[r][c][1] self.moveFunctions[piece](r, c, moves) # calls the appropriate move function based on piece type return moves ''' Get all the pawn moves for the pawn located at row, col and add these moves to the list ''' def getPawnMoves(self, r, c, moves): if self.whiteToMove: # white pawn moves if self.board[r-1][c] == "--": # 1 square pawn advance moves.append(Move((r, c), (r-1, c), self.board)) if r == 6 and self.board[r-2][c] == "--": # 2 square pawn move moves.append(Move((r, c), (r-2, c), self.board)) if c-1 >= 0: # capture to the left if self.board[r-1][c-1][0] == 'b': # enemy piece to capture moves.append(Move((r, c), (r-1, c-1), self.board)) if c+1 <= 7: # capture to the right if self.board[r-1][c+1][0] == 'b': # enemy piece to capture moves.append(Move((r, c), (r-1, c+1), self.board)) else: # black pawn moves if self.board[r + 1][c] == "--": # 1 square move print("here1") moves.append(Move((r, c), (r + 1, c), self.board)) if r == 1 and self.board[r + 2][c] == "--": # 2 square moves moves.append(Move((r, c), (r + 2, c), self.board)) # captures if c-1 >= 0: # capture to left if self.board[r + 1][c - 1][0] == 'w': moves.append(Move((r, c), (r + 1, c - 1), self.board)) if c+1 <= 7: # capture to right if self.board[r + 1][c + 1][0] == 'w': moves.append(Move((r, c), (r + 1, c + 1), self.board)) # add pawn promotions later ''' Get all the rook moves for the rook located at row, col and add these moves to the list ''' def getRookMoves(self, r, c, moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) # up, left, down, right enemyColor = "b" if self.whiteToMove else "w" for d in directions: for i in range(1, 0): endRow = r + d[0] * i endCol = c + d[1] * i if 0 <= endRow < 8 and 0 <= endCol < 8: # on board endPiece = self.board[endRow][endCol] if endPiece == "--": # empty space valid moves.append(Move((r, c), (endRow, endCol), self.board)) elif endPiece[0] == enemyColor: # enemy piece valid moves.append(Move((r, c), (endRow, endCol), self.board)) break else: # friendly piece invalid break else: # off board break ''' Get all the knight moves for the knight located at row, col and add these moves to the list ''' def getKnightMoves(self, r, c, moves): knightMoves = ((-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)) allyColor = 'w' if self.whiteToMove else "b" for m in knightMoves: endRow = r + m[0] endCol = c + m[0] if 0 <= endRow < 8 and 0 <= endCol < 8: endPiece = self.board[endRow][endCol] if endPiece[0] != allyColor: # not an ally piece (empty or enemy piece) moves.append(Move((r, c), (endRow, endCol), self.board)) ''' Get all the bishop moves for the bishop located at row, col and add these moves to the list ''' def getBishopMoves(self, r, c, moves): directions = ((-1, -1), (-1, 1), (1, -1), (1, 1)) enemyColor = "b" if self.whiteToMove else "w" for d in directions: for i in range(1, 8): # bishop can move max of 7 squares endRow = r + d[0] * i endCol = c + d[1] * i if 0 <= endRow < 8 and 0 <= endCol < 8: # is it on board endPiece = self.board[endRow][endCol] if endPiece == "--": # empty space valid moves.append(Move((r, c), (endRow, endCol), self.board)) elif endPiece[0] == enemyColor: # enemy piece valid moves.append(Move((r, c), (endRow, endCol), self.board)) break else: # friendly piece invalid break else: # off board break ''' Get all the queen moves for the queen located at row, col and add these moves to the list ''' def getQueenMoves(self, r, c, moves): self.getRookMoves(r, c, moves) self.getBishopMoves(r, c, moves) ''' Get all the king moves for the king located at row, col and add these moves to the list ''' def getKingMoves(self, r, c, moves): kingMoves = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)) allyColor = "w" if self.whiteToMove else "b" for i in range(8): endRow = r + kingMoves[i][0] endCol = c + kingMoves[i][1] if 0 <= endRow < 8 and 0 <= endCol <8: endPiece = self.board[endRow][endCol] if endPiece[0] != allyColor: # not an ally piece (empty or enemy piece) moves.append(Move((r, c), (endRow, endCol), self.board)) class Move: # maps key to values # key : value ranksToRows = {"1": 7, "2": 6, "3": 5, "4": 4, "5": 3, "6": 2, "7": 1, "8": 0} rowsToRanks = {v: k for k, v in ranksToRows.items()} filesToCols = {"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7} colsToFiles = {v: k for k, v in filesToCols.items()} def __init__(self, startSq, endSq, board): self.startRow = startSq[0] self.startCol = startSq[1] self.endRow = endSq[0] self.endCol = endSq[1] self.pieceMoved = board[self.startRow][self.startCol] self.pieceCaptured = board[self.endRow][self.endCol] self.moveID = self.startRow * 1000 + self.startCol * 100 + self.endRow * 10 + self.endCol ''' Overriding the equals method ''' def __eq__(self, other): if isinstance(other, Move): return self.moveID == other.moveID return False def getChessNotation(self): # you can add to make this like real chess notation return self.getRankFile(self.startRow, self.startCol) + self.getRankFile(self.endRow, self.endCol) def getRankFile(self, r, c): return self.colsToFiles[c] + self.rowsToRanks[r] def loadImages(): pieces = ['wp', 'wR', 'wN', 'wB', 'wK', 'wQ', 'bp', 'bR', 'bN', 'bB', 'bK', 'bQ'] for piece in pieces: IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQ_SIZE, SQ_SIZE)) # Note: we can access an image saving "IMAGES"['wp'] ''' The main driver for our code. This will handle user input and updating the graphics. ''' def main(): p.init() screen = p.display.set_mode((WIDTH, HEIGHT)) clock = p.time.Clock() screen.fill(p.Color("white")) gs = ChessEngine.GameState() validMoves = gs.getValidMoves() moveMade = False # flag variable for when a move is made loadImages() # only do this once, before the while loop running = True sqSelected = () # no square is selected, keep track of the last click of the user (tuple: (row, col)) playerClicks = [] # keep track of player clicks (two tuples [6,4), (4,4)] while running: for e in p.event.get(): if e.type == p.QUIT: running = False # mouse handler elif e.type == p.MOUSEBUTTONDOWN: location = p.mouse.get_pos() # (x, y) location of mouse col = location[0]//SQ_SIZE row = location[1]//SQ_SIZE if sqSelected == (row, col): # the user clicked the same square twice sqSelected = () # deselect playerClicks = [] # clear player clicks else: sqSelected = (row, col) playerClicks.append(sqSelected) # append for both 1st and 2nd clicks if len(playerClicks) == 2: # after 2nd click move = ChessEngine.Move(playerClicks[0], playerClicks[1], gs.board) print(move.getChessNotation()) if move in validMoves: gs.makeMove(move) makeMove = True sqSelected = () # reset user clicks playerClicks = [] else: playerClicks = [sqSelected] # key handler elif e.type == p.KEYDOWN: if e.key == p.K_u: # undo when 'u' is pressed gs.undoMove() moveMade = True if moveMade: validMoves = gs.getValidMoves() moveMade = False drawGameState(screen, gs) clock.tick(MAX_FPS) p.display.flip() ''' Responsible for all the graphics within a current game state. ''' def drawGameState(screen, gs): drawBoard(screen) # draw squares on the board # add in piece highlighting or move suggestions (later) drawPieces(screen, gs.board) # draw pieces on top of those squares ''' Draw the squares on the board. The top left square is always light. ''' def drawBoard(screen): colors = [p.Color("white"), p.Color("grey")] for r in range(DIMENSION): for c in range(DIMENSION): color = colors[((r+c) % 2)] p.draw.rect(screen, color, p.Rect(c * SQ_SIZE, r * SQ_SIZE, SQ_SIZE, SQ_SIZE)) ''' Draw the pieces on the board using the current GameState.board ''' def drawPieces(screen, board): for r in range(DIMENSION): for c in range(DIMENSION): piece = board[r][c] if piece != "--": # not empty square screen.blit(IMAGES[piece], p.Rect(c * SQ_SIZE, r * SQ_SIZE, SQ_SIZE, SQ_SIZE)) if __name__ == "__main__": main()
Что я уже пробовал:
Я попытался изменить утверждение else в ходах Черной пешки на elif not self.whiteToMove:
но ничего. Я нашел, где код достигает, он достигает во всех местах, таких как getValidMoves, undoMove, getAllPossibleMoves. Я пытался проверить, не ошибся ли мой код, но не могу найти, что именно. Я просто не знаю, почему это работает. Я честно перепробовал все, что мог придумать. Мне просто нужна помощь, может быть, со слепыми пятнами.