Я создал шахматную партию по учебнику YouTube, и она не работает должным образом. Происходят действительно странные ошибки, я проверял код тысячу раз и не нашел решения.
Я в основном подозреваю, что ошибка находится внутри board. py функцию in_check, потому что это место, где мы вычисляем все ходы, и как только я закомментировал функцию in_check, она заработала без ошибок. Я нашел несколько ошибок в этой игре, и одна из них заключается в том, что иногда дружественные фигуры могут фактически захватывать друг друга, этого никогда не происходит в начале игры, но это происходит после того, как один из королей поставил шах, и если, например, фигура закреплена (если она движется, король будет под шахом), то другие фигуры, ходы которых были ограничены, чтобы они могли защитить короля, у них все равно будут свои ходы и они могут фактически захватить закрепленную дружественную фигуру . Другая похожая ситуация заключается в том, что, например, если левый конь защищает короля, он будет работать нормально, как и ожидалось, но другой конь начнет действовать странно и двигаться свободно независимо от ситуации с королем. Он также может захватить не другие дружественные фигуры, но другой конь!
Вот несколько скриншотов, чтобы было понятно:
Вы можете видеть, что ходы ферзя не ограничены, потому что король не находится под шахом, я использовал слоном, чтобы преградить путь белому слону, и последний возможный ход ферзя все еще активен, где находится черный слон.
Ранее я также использовал перемещенного коня, чтобы защитить короля, и сделал ход его в другое место, и другой конь, как вы видите, может каким-то образом захватить перемещенного коня.
Поскольку предыдущий ход этого коня был ограничен тем местом, где он может защитить короля, этот ход все еще активен и может захватить дружественного слона, хотя в кодах коню запрещено добавлять поля с дружественными фигурами в качестве допустимых ходов.
Итак, я публикую классы, которые Я подозреваю, что один из них содержит эту ошибку, так что, возможно, вы, ребята, сможете мне с ней помочь: settings.py
from copy import deepcopy
from settings import *
from square import Square
from move import Move
from sound import Sound
from piece import *
from itertools import permutations, product
class Board:
def __init__(self):
self.squares, self.lastMove = [[None for row in range(ROWS)] for col in range(COLS)], None
self._create()
teams = {'white', 'black'}
for team in teams: self._add_pieces(team)
def move(self, piece: Piece, move: Move, testing: bool = False):
initial = move.initial
final = move.final
en_passant_empty = self.squares[final.row][final.col].isEmpty()
self.squares[initial.row][initial.col].piece = None
self.squares[final.row][final.col].piece = piece
diff = final.col - initial.col
if isinstance(piece, Pawn):
if en_passant_empty and diff != 0:
self.squares[initial.row][initial.col + diff].piece = None
self.squares[final.row][final.col].piece = piece
if not testing: Sound('assets/Audios/capture.wav').play()
else: self.check_promotion(piece, final)
if isinstance(piece, King):
if not testing and abs(initial.col - final.col) == 2:
rook = piece.left_rook if diff < 0 else piece.right_rook
self.move(rook, rook.moves[-1])
Sound('assets/Audios/castling.mp3').play()
if isinstance(piece, Knight) and piece.color == 'black':print(' '+piece.name+' move '+str(move)+'\n')
piece.moved = True
piece.clear_moves()
self.lastMove = move
def valid_move(self, piece: Piece, move: Move): return move in piece.moves
def check_promotion(self, piece: Piece, final: Square):
if PROMOTION and (final.row == 0 or final.row == 7):
if TO_LOST_PIECES:
pass
elif TO_QUEEN: self.squares[final.row][final.col].piece = Queen(piece.color)
else: return
Sound('assets/Audios/promotion.mp3').play()
def en_passant_on(self, piece: Piece):
if not PAWN_EN_PASSANT or not isinstance(piece, Pawn) or not piece.en: return
for row in range(ROWS):
for col in range(COLS):
if isinstance(self.squares[row][col].piece, Pawn): self.squares[row][col].piece.en_passant = False
piece.en_passant = True
def in_check(self, piece: Piece, move: Move):
if not INSTANT_CHECKMATE:
virtual_piece = deepcopy(piece)
virtual_board = deepcopy(self)
virtual_board.move(virtual_piece, move, True)
for row in range(ROWS):
for col in range(COLS):
if virtual_board.squares[row][col].has_enemy_piece(piece.color):
p = virtual_board.squares[row][col].piece
virtual_board.calculate_moves(p, row, col, False)
for m in p.moves:
c = None
if m.final.piece != None:
c = m.final.piece.color
print(m.final.has_enemy_piece(c))
if isinstance(m.final.piece, King): return True
return False
def calculate_moves(self, piece: Piece, row: int, col: int, virtual: bool = True):
def all_combos(tpl: tuple, add = False):
tmp = set()
per = set(permutations(tpl))
sign_variations = set(product(*[(x, -x) for x in tpl]))
for variation in sign_variations: tmp.update(permutations(variation))
if add:
res = []
for Row, Col in tmp: res.append((row+Row, col+Col))
return set(res)
return tmp
def pawn_moves():
if isinstance(piece, Pawn):
steps = 1 if piece.moved else 2
piece.en = True if steps == 2 else False
start, end = row + piece.dir, row + (piece.dir * (1 + steps))
for move_row in range(start, end, piece.dir):
if Square.in_range(move_row) and self.squares[move_row][col].isEmpty():
initial, final = Square(row, col), Square(move_row, col)
move = Move(initial, final)
if virtual:
if not self.in_check(piece, move):
piece.add_move(move)
else:
piece.add_move(move)
else: break
move_row, move_cols = row + piece.dir, [col-1, col+1]
for move_col in move_cols:
if Square.in_range(move_row, move_col) and self.squares[move_row][move_col].has_enemy_piece(piece.color):
initial = Square(row, col)
final_piece = self.squares[move_row][move_col].piece
final = Square(move_row, move_col, final_piece)
move = Move(initial, final)
if virtual:
if not self.in_check(piece, move):
piece.add_move(move)
else:
piece.add_move(move)
r, fr = 3 if piece.color == 'white' else 4, 2 if piece.color == 'white' else 5
if Square.in_range(col-1) and row == r and self.squares[row][col-1].has_enemy_piece(piece.color):
p = self.squares[row][col-1].piece
if isinstance(p, Pawn):
if p.en_passant:
piece.en_passant = False
initial = Square(row, col)
final = Square(fr, col-1, p)
move = Move(initial, final)
if virtual:
if not self.in_check(piece, move):
piece.add_move(move)
else:
piece.add_move(move)
if Square.in_range(col+1) and row == r:
if self.squares[row][col+1].has_enemy_piece(piece.color):
p = self.squares[row][col+1].piece
if isinstance(p, Pawn):
if p.en_passant:
initial = Square(row, col)
final = Square(fr, col+1, p)
move = Move(initial, final)
if virtual:
if not self.in_check(piece, move):
piece.add_move(move)
else:
piece.add_move(move)
def knight_moves():
possible_moves = all_combos(Knight.move_range, True)
for possible_move in possible_moves:
possible_move_row, possible_move_col = possible_move
if Square.in_range(possible_move_row, possible_move_col) and self.squares[possible_move_row][possible_move_col].isEmpty_or_enemy(piece.color) and not self.squares[possible_move_row][possible_move_col].has_friendly_piece(piece.color):
initial = Square(row, col)
final_piece = self.squares[possible_move_row][possible_move_col].piece
final = Square(possible_move_row, possible_move_col, final_piece)
move = Move(initial, final)
if virtual:
if not self.in_check(piece, move):
if piece.color == 'black': print(' '+piece.name+' move '+str(move)+'\n')
piece.add_move(move)
else:
if piece.color == 'black': print(' else '+piece.name+' move '+str(move)+'\n')
piece.add_move(move)
def straght_moves(incrs: set):
for inc in incrs:
row_incr, col_incr = inc
possible_move_row = row + row_incr
possible_move_col = col + col_incr
while True:
if Square.in_range(possible_move_row, possible_move_col):
initial = Square(row, col)
final_piece = self.squares[possible_move_row][possible_move_col].piece
final = Square(possible_move_row, possible_move_col, final_piece)
move = Move(initial, final)
if self.squares[possible_move_row][possible_move_col].isEmpty():
if virtual:
if not self.in_check(piece, move): piece.add_move(move)
else: piece.add_move(move)
elif self.squares[possible_move_row][possible_move_col].has_enemy_piece(piece.color):
if virtual:
if not self.in_check(piece, move): piece.add_move(move)
else: piece.add_move(move)
break
elif self.squares[possible_move_row][possible_move_col].has_friendly_piece(piece.color): break
else: break
possible_move_row, possible_move_col = possible_move_row + row_incr, possible_move_col + col_incr
def king_moves():
adjs = all_combos(Rook.move_range, True).union(all_combos(Bishop.move_range, True))
for possible_move in adjs:
possible_move_row, possible_move_col = possible_move
if Square.in_range(possible_move_row, possible_move_col) and self.squares[possible_move_row][possible_move_col].isEmpty_or_enemy(piece.color):
initial = Square(row, col)
final = Square(possible_move_row, possible_move_col)
move = Move(initial, final)
if virtual:
if not self.in_check(piece, move): piece.add_move(move)
else: piece.add_move(move)
if CASTLING and not piece.moved:
left_rook = self.squares[row][0].piece
if isinstance(left_rook, Rook):
if not left_rook.moved:
for c in range(1, 4):
if self.squares[row][c].has_piece(): break
if c == 3:
piece.left_rook = left_rook
initial = Square(row, 0)
final = Square(row, 3)
moveR = Move(initial, final)
initial = Square(row, col)
final = Square(row, 2)
moveK = Move(initial, final)
if virtual:
if not self.in_check(piece, moveK) and not self.in_check(left_rook, moveR):
left_rook.add_move(moveR)
piece.add_move(moveK)
else:
left_rook.add_move(moveR)
piece.add_move(moveK)
right_rook = self.squares[row][7].piece
if isinstance(right_rook, Rook):
if not right_rook.moved:
for c in range(5, 7):
if self.squares[row][c].has_piece(): break
if c == 6:
piece.right_rook = right_rook
initial = Square(row, 7)
final = Square(row, 5)
moveR = Move(initial, final)
initial = Square(row, col)
final = Square(row, 6)
moveK = Move(initial, final)
if virtual:
if not self.in_check(piece, moveK) and not self.in_check(right_rook, moveR):
right_rook.add_move(moveR)
piece.add_move(moveK)
else:
right_rook.add_move(moveR)
piece.add_move(moveK)
if isinstance(piece, Pawn): pawn_moves()
elif isinstance(piece, Knight): knight_moves()
elif isinstance(piece, Bishop): straght_moves(all_combos(Bishop.move_range))
elif isinstance(piece, Rook): straght_moves(all_combos(Rook.move_range))
elif isinstance(piece, Queen): straght_moves(all_combos(Bishop.move_range).union(all_combos(Rook.move_range)))
elif isinstance(piece, King): king_moves()
def _create(self):
for row in range(ROWS):
for col in range(COLS): self.squares[row][col] = Square(row, col)
def _add_pieces(self, color):
row_pawn, row_other = (6, 7) if color == 'white' else (1, 0)
for col in range(COLS): self.squares[row_pawn][col] = Square(row_pawn, col, Pawn(color))
for col in (1, 6): self.squares[row_other][col] = Square(row_other, col, Knight(color))
for col in (2, 5): self.squares[row_other][col] = Square(row_other, col, Bishop(color))
for col in (0, 7): self.squares[row_other][col] = Square(row_other, col, Rook(color))
self.squares[row_other][3] = Square(row_other, 3, Queen(color))
self.squares[row_other][4] = Square(row_other, 4, King(color))
# from square import Square
class Move:
def __init__(self, initial, final): self.initial, self.final = initial, final
def __str__(self):
s = ''
s += f'({self.initial.row}, {self.initial.col})'
s += f' -> ({self.final.row}, {self.final.col})'
return s
def __eq__(self, other: 'Move'): return self.initial == other.initial and self.final == other.final
Я создал шахматную партию по учебнику YouTube, и она не работает должным образом. Происходят действительно странные ошибки, я проверял код тысячу раз и не нашел решения. Я в основном подозреваю, что ошибка находится внутри [b]board. py[/b] функцию in_check, потому что это место, где мы вычисляем все ходы, и как только я закомментировал функцию in_check, она заработала без ошибок. Я нашел несколько ошибок в этой игре, и одна из них заключается в том, что иногда дружественные фигуры могут фактически захватывать друг друга, этого никогда не происходит в начале игры, но это происходит после того, как один из королей поставил шах, и если, например, фигура закреплена (если она движется, король будет под шахом), то другие фигуры, ходы которых были ограничены, чтобы они могли защитить короля, у них все равно будут свои ходы и они могут фактически захватить закрепленную дружественную фигуру . Другая похожая ситуация заключается в том, что, например, если левый конь защищает короля, он будет работать нормально, как и ожидалось, но другой конь начнет действовать странно и двигаться свободно независимо от ситуации с королем. Он также может захватить не другие дружественные фигуры, но другой конь! Вот несколько скриншотов, чтобы было понятно: Вы можете видеть, что ходы ферзя не ограничены, потому что король не находится под шахом, я использовал слоном, чтобы преградить путь белому слону, и последний возможный ход ферзя все еще активен, где находится черный слон. Ранее я также использовал перемещенного коня, чтобы защитить короля, и сделал ход его в другое место, и другой конь, как вы видите, может каким-то образом захватить перемещенного коня. Поскольку предыдущий ход этого коня был ограничен тем местом, где он может защитить короля, этот ход все еще активен и может захватить дружественного слона, хотя в кодах коню запрещено добавлять поля с дружественными фигурами в качестве допустимых ходов. Итак, я публикую классы, которые Я подозреваю, что один из них содержит эту ошибку, так что, возможно, вы, ребята, сможете мне с ней помочь: [b]settings.py[/b] [code]WIDTH = HEIGHT = 800 SCREEN_WIDTH = SCREEN_HEIGHT = 800 ROWS = COLS = 8 NAME = 'Chess Game' SquareSize = WIDTH // COLS
SHOW_MOVES = True SHOW_TRACES = False SHOW_HOVER = True CASTLING = True PAWN_EN_PASSANT = True PROMOTION = True WARN_CHECKS = False WARN_PINS = False INSTANT_CHECKMATE = False TO_QUEEN = True TO_LOST_PIECES = True [/code] [b]main.py[/b] [code]import pygame as pg from sys import exit from settings import * from game import Game from square import Square from move import Move from piece import * class Main: def __init__(self): pg.init() self.screen = pg.display.set_mode((WIDTH, HEIGHT)) pg.display.set_caption(NAME) self.game = Game() def mainloop(self): game, board, screen, dragger = self.game, self.game.board, self.screen, self.game.dragger while True: game.show_bg(screen) game.show_last_move(screen) game.show_moves(screen) game.show_pieces(screen) if not pg.mouse.get_focused(): game.set_hover(-1, -1) game.show_hover(screen, game.nextPlayer) if dragger.dragging: dragger.update_texture(screen) for event in pg.event.get(): if event.type == pg.MOUSEBUTTONDOWN: # click dragger.update_mouse(event.pos) clicked_row = dragger.mouseY // SquareSize clicked_col = dragger.mouseX // SquareSize if isinstance(board.squares[clicked_row][clicked_col].piece, Knight): pass print('----------------------------------') # if the clicked square has a piece: if board.squares[clicked_row][clicked_col].has_piece(): piece = board.squares[clicked_row][clicked_col].piece if piece.color == game.nextPlayer: # valid piece (color) ? board.calculate_moves(piece, clicked_row, clicked_col, True) dragger.save_initial(event.pos) dragger.drag_piece(piece) # show methods game.show_bg(screen) game.show_last_move(screen) game.show_moves(screen) game.show_pieces(screen) elif event.type == pg.MOUSEMOTION: motion_row, motion_col = event.pos[1], event.pos[0] game.set_hover(motion_row, motion_col) motion_row, motion_col = motion_row // SquareSize, motion_col // SquareSize print('\r'+str(motion_row)+', '+str(motion_col)+', ('+str(event.pos[1])+', '+str(event.pos[0])+') ', end='\r') if dragger.dragging: dragger.update_mouse(event.pos) game.show_bg(screen) game.show_last_move(screen) game.show_moves(screen) game.show_pieces(screen) game.show_hover(screen, game.nextPlayer) dragger.update_texture(screen) elif event.type == pg.MOUSEBUTTONUP: if dragger.dragging: dragger.update_mouse(event.pos) released_row, released_col = dragger.mouseY // SquareSize, dragger.mouseX // SquareSize initial, final = Square(dragger.initial_row, dragger.initial_col), Square(released_row, released_col) move = Move(initial, final) if board.valid_move(dragger.piece, move): game.playSound(True) if board.squares[released_row][released_col].has_enemy_piece(game.nextPlayer) else game.playSound() board.move(dragger.piece, move, False) if PAWN_EN_PASSANT: board.en_passant_on(dragger.piece) game.show_bg(screen) game.show_last_move(screen) game.show_pieces(screen) game.next_turn() else: game.playSound(None) dragger.undrag_piece() elif event.type == pg.KEYDOWN: if event.key == pg.K_TAB: game.change_theme() if event.key == pg.K_r: game.reset() game, board, dragger = self.game, self.game.board, self.game.dragger if event.type == pg.QUIT: pg.quit() exit() pg.display.update() main = Main() main.mainloop() [/code] [b]dragger.py[/b] [code]import pygame as pg from piece import Piece from settings import * class Dragger: def __init__(self): self.mouseX = self.mouseY = self.initial_row = self.initial_col = self.piece = None self.dragging = False
# blit method
def update_texture(self, surface: pg.Surface): #add this method can be turned into a general function self.piece.set_texture(size = 125) img = pg.image.load(self.piece.texture) img_center = self.mouseX, self.mouseY self.piece.texture_rect = img.get_rect(center = img_center) surface.blit(img, self.piece.texture_rect)
# other methods
def update_mouse(self, pos): self.mouseX, self.mouseY = pos def save_initial(self, pos): self.initial_row, self.initial_col = pos[1] // SquareSize, pos[0] // SquareSize def drag_piece(self, piece: Piece): self.piece, self.dragging = piece, True def undrag_piece(self): self.piece, self.dragging = None, False [/code] [b]board.py[/b] [code]from copy import deepcopy from settings import * from square import Square from move import Move from sound import Sound from piece import * from itertools import permutations, product class Board: def __init__(self): self.squares, self.lastMove = [[None for row in range(ROWS)] for col in range(COLS)], None self._create() teams = {'white', 'black'} for team in teams: self._add_pieces(team) def move(self, piece: Piece, move: Move, testing: bool = False): initial = move.initial final = move.final en_passant_empty = self.squares[final.row][final.col].isEmpty() self.squares[initial.row][initial.col].piece = None self.squares[final.row][final.col].piece = piece diff = final.col - initial.col if isinstance(piece, Pawn): if en_passant_empty and diff != 0: self.squares[initial.row][initial.col + diff].piece = None self.squares[final.row][final.col].piece = piece if not testing: Sound('assets/Audios/capture.wav').play() else: self.check_promotion(piece, final)
if isinstance(piece, King): if not testing and abs(initial.col - final.col) == 2: rook = piece.left_rook if diff < 0 else piece.right_rook self.move(rook, rook.moves[-1]) Sound('assets/Audios/castling.mp3').play() if isinstance(piece, Knight) and piece.color == 'black':print(' '+piece.name+' move '+str(move)+'\n') piece.moved = True piece.clear_moves() self.lastMove = move def valid_move(self, piece: Piece, move: Move): return move in piece.moves def check_promotion(self, piece: Piece, final: Square): if PROMOTION and (final.row == 0 or final.row == 7): if TO_LOST_PIECES: pass elif TO_QUEEN: self.squares[final.row][final.col].piece = Queen(piece.color) else: return Sound('assets/Audios/promotion.mp3').play() def en_passant_on(self, piece: Piece): if not PAWN_EN_PASSANT or not isinstance(piece, Pawn) or not piece.en: return for row in range(ROWS): for col in range(COLS): if isinstance(self.squares[row][col].piece, Pawn): self.squares[row][col].piece.en_passant = False piece.en_passant = True def in_check(self, piece: Piece, move: Move): if not INSTANT_CHECKMATE: virtual_piece = deepcopy(piece) virtual_board = deepcopy(self) virtual_board.move(virtual_piece, move, True) for row in range(ROWS): for col in range(COLS): if virtual_board.squares[row][col].has_enemy_piece(piece.color): p = virtual_board.squares[row][col].piece virtual_board.calculate_moves(p, row, col, False) for m in p.moves: c = None if m.final.piece != None: c = m.final.piece.color print(m.final.has_enemy_piece(c)) if isinstance(m.final.piece, King): return True return False def calculate_moves(self, piece: Piece, row: int, col: int, virtual: bool = True):
def all_combos(tpl: tuple, add = False): tmp = set() per = set(permutations(tpl)) sign_variations = set(product(*[(x, -x) for x in tpl])) for variation in sign_variations: tmp.update(permutations(variation)) if add: res = [] for Row, Col in tmp: res.append((row+Row, col+Col)) return set(res) return tmp def pawn_moves(): if isinstance(piece, Pawn): steps = 1 if piece.moved else 2 piece.en = True if steps == 2 else False start, end = row + piece.dir, row + (piece.dir * (1 + steps)) for move_row in range(start, end, piece.dir): if Square.in_range(move_row) and self.squares[move_row][col].isEmpty(): initial, final = Square(row, col), Square(move_row, col) move = Move(initial, final)
if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move) else: break
move_row, move_cols = row + piece.dir, [col-1, col+1] for move_col in move_cols: if Square.in_range(move_row, move_col) and self.squares[move_row][move_col].has_enemy_piece(piece.color): initial = Square(row, col) final_piece = self.squares[move_row][move_col].piece final = Square(move_row, move_col, final_piece) move = Move(initial, final) if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move)
r, fr = 3 if piece.color == 'white' else 4, 2 if piece.color == 'white' else 5 if Square.in_range(col-1) and row == r and self.squares[row][col-1].has_enemy_piece(piece.color): p = self.squares[row][col-1].piece if isinstance(p, Pawn): if p.en_passant: piece.en_passant = False initial = Square(row, col) final = Square(fr, col-1, p) move = Move(initial, final) if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move) if Square.in_range(col+1) and row == r: if self.squares[row][col+1].has_enemy_piece(piece.color): p = self.squares[row][col+1].piece if isinstance(p, Pawn): if p.en_passant: initial = Square(row, col) final = Square(fr, col+1, p) move = Move(initial, final) if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move) def knight_moves(): possible_moves = all_combos(Knight.move_range, True) for possible_move in possible_moves: possible_move_row, possible_move_col = possible_move if Square.in_range(possible_move_row, possible_move_col) and self.squares[possible_move_row][possible_move_col].isEmpty_or_enemy(piece.color) and not self.squares[possible_move_row][possible_move_col].has_friendly_piece(piece.color): initial = Square(row, col) final_piece = self.squares[possible_move_row][possible_move_col].piece final = Square(possible_move_row, possible_move_col, final_piece) move = Move(initial, final) if virtual: if not self.in_check(piece, move): if piece.color == 'black': print(' '+piece.name+' move '+str(move)+'\n') piece.add_move(move)
else: if piece.color == 'black': print(' else '+piece.name+' move '+str(move)+'\n') piece.add_move(move) def straght_moves(incrs: set): for inc in incrs: row_incr, col_incr = inc possible_move_row = row + row_incr possible_move_col = col + col_incr while True: if Square.in_range(possible_move_row, possible_move_col): initial = Square(row, col) final_piece = self.squares[possible_move_row][possible_move_col].piece final = Square(possible_move_row, possible_move_col, final_piece) move = Move(initial, final) if self.squares[possible_move_row][possible_move_col].isEmpty(): if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move) elif self.squares[possible_move_row][possible_move_col].has_enemy_piece(piece.color): if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move) break elif self.squares[possible_move_row][possible_move_col].has_friendly_piece(piece.color): break else: break possible_move_row, possible_move_col = possible_move_row + row_incr, possible_move_col + col_incr def king_moves(): adjs = all_combos(Rook.move_range, True).union(all_combos(Bishop.move_range, True)) for possible_move in adjs: possible_move_row, possible_move_col = possible_move if Square.in_range(possible_move_row, possible_move_col) and self.squares[possible_move_row][possible_move_col].isEmpty_or_enemy(piece.color): initial = Square(row, col) final = Square(possible_move_row, possible_move_col) move = Move(initial, final) if virtual: if not self.in_check(piece, move): piece.add_move(move) else: piece.add_move(move) if CASTLING and not piece.moved: left_rook = self.squares[row][0].piece if isinstance(left_rook, Rook): if not left_rook.moved: for c in range(1, 4): if self.squares[row][c].has_piece(): break if c == 3: piece.left_rook = left_rook initial = Square(row, 0) final = Square(row, 3) moveR = Move(initial, final) initial = Square(row, col) final = Square(row, 2) moveK = Move(initial, final) if virtual: if not self.in_check(piece, moveK) and not self.in_check(left_rook, moveR): left_rook.add_move(moveR) piece.add_move(moveK) else: left_rook.add_move(moveR) piece.add_move(moveK) right_rook = self.squares[row][7].piece if isinstance(right_rook, Rook): if not right_rook.moved: for c in range(5, 7): if self.squares[row][c].has_piece(): break if c == 6: piece.right_rook = right_rook initial = Square(row, 7) final = Square(row, 5) moveR = Move(initial, final) initial = Square(row, col) final = Square(row, 6) moveK = Move(initial, final) if virtual: if not self.in_check(piece, moveK) and not self.in_check(right_rook, moveR): right_rook.add_move(moveR) piece.add_move(moveK) else: right_rook.add_move(moveR) piece.add_move(moveK) if isinstance(piece, Pawn): pawn_moves() elif isinstance(piece, Knight): knight_moves() elif isinstance(piece, Bishop): straght_moves(all_combos(Bishop.move_range)) elif isinstance(piece, Rook): straght_moves(all_combos(Rook.move_range)) elif isinstance(piece, Queen): straght_moves(all_combos(Bishop.move_range).union(all_combos(Rook.move_range))) elif isinstance(piece, King): king_moves() def _create(self): for row in range(ROWS): for col in range(COLS): self.squares[row][col] = Square(row, col) def _add_pieces(self, color): row_pawn, row_other = (6, 7) if color == 'white' else (1, 0) for col in range(COLS): self.squares[row_pawn][col] = Square(row_pawn, col, Pawn(color)) for col in (1, 6): self.squares[row_other][col] = Square(row_other, col, Knight(color)) for col in (2, 5): self.squares[row_other][col] = Square(row_other, col, Bishop(color)) for col in (0, 7): self.squares[row_other][col] = Square(row_other, col, Rook(color)) self.squares[row_other][3] = Square(row_other, 3, Queen(color)) self.squares[row_other][4] = Square(row_other, 4, King(color)) [/code] [b]piece.py[/b] [code]from move import Move class Piece: def __init__(self, name, color, worth, texture = None, texture_rect = None): self.name, self.color = name, color worth_sign = 1 if color == 'white' else -1 self.worth = worth * worth_sign self.moves = [] self.moved = False self.texture = texture self.set_texture() self.texture_rect = texture_rect def set_texture(self, size = 80): self.texture = f'assets/textures/{size}px/{self.color}-{self.name}-{size}px.png' def add_move(self, move: Move): self.moves.append(move) def clear_moves(self): return self.moves.clear() class Pawn(Piece): def __init__(self, color): self.dir, self.en_passant, self.en = -1 if color == 'white' else 1, False, False super().__init__('pawn', color, 1.0) class Knight(Piece): move_range = (1, 2) def __init__(self, color): super().__init__('knight', color, 3.0) class Bishop(Piece): move_range = (1, 1) def __init__(self, color): super().__init__('bishop', color, 3.001) class Rook(Piece): move_range = (1, 0) def __init__(self, color): super().__init__('rook', color, 5.0) class Queen(Piece): def __init__(self, color): super().__init__('queen', color, 9.0) class King(Piece): def __init__(self, color): self.left_rook = None self.right_rook = None from math import inf super().__init__('king', color, inf) [/code] [b]move.py[/b] [code]# from square import Square class Move: def __init__(self, initial, final): self.initial, self.final = initial, final def __str__(self): s = '' s += f'({self.initial.row}, {self.initial.col})' s += f' -> ({self.final.row}, {self.final.col})' return s def __eq__(self, other: 'Move'): return self.initial == other.initial and self.final == other.final [/code] [b]square.py[/b] [code]from piece import Piece class Square: def __init__(self, row: int, col: int, piece: Piece = None): self.row, self.col, self.piece = row, col, piece def __eq__(self, other: 'Square'): return self.row == other.row and self.col == other.col def has_piece(self): return self.piece != None def isEmpty(self): return not self.has_piece() def has_friendly_piece(self, color): return self.has_piece() and self.piece.color == color def has_enemy_piece(self, color): return self.has_piece() and self.piece.color != color def isEmpty_or_enemy(self, color): return self.isEmpty() or self.has_enemy_piece(color) @staticmethod def in_range(*args): for arg in args: if arg < 0 or arg > 7: return False return True [/code] Надеюсь, вы это понимаете и поможете мне исправить, насколько я вижу, это единственные ошибки, оставшиеся в игре. [b]Заранее спасибо.[/b]
Мне нужен совет относительно моего любимого проекта. Я создаю механизм распознавания шахматных фигур, используя библиотеку Python PyTorch.
Теперь у меня есть две основные проблемы:
Мой набор данных.
Как мне подготовить изображения?
У меня 7...
Я работаю над шахматной игрой на C++, которая отображает доску в консоли с использованием шахматных символов Юникода. Однако вместо отображения белого ферзя (♕), черного ферзя (♛) и других шахматных фигур Unicode программа отображает вопросительные...
Я работаю над шахматной игрой на C++, которая отображает доску в консоли с использованием шахматных символов Юникода. Однако вместо отображения белого ферзя (♕), черного ферзя (♛) и других шахматных фигур Unicode программа отображает вопросительные...
Я работаю над шахматной игрой на C++, которая отображает доску в консоли с использованием шахматных символов Юникода. Однако вместо того, чтобы показать чёрного ферзя ( ♕ ), белая королева ( ♛ ) и других шахматных фигур Unicode, программа отображает...