Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import chess
- from typing import Iterator
- from chess import Move, BB_ALL, Bitboard
- # Definice nových figur
- AMAZON = 7
- class CustomBoard(chess.Board):
- def __init__(self, fen=None):
- self.amazons_white = chess.BB_EMPTY
- self.amazons_black = chess.BB_EMPTY
- self.custom_bishops_white = chess.BB_EMPTY
- self.custom_bishops_black = chess.BB_EMPTY
- super().__init__(None)
- if fen:
- self.set_custom_fen(fen)
- print("Šachovnice inicializována")
- self.debug_amazons()
- self.debug_custom_bishops()
- def set_custom_fen(self, fen):
- parts = fen.split()
- board_part = parts[0]
- self.clear()
- self.amazons_white = chess.BB_EMPTY
- self.amazons_black = chess.BB_EMPTY
- self.custom_bishops_white = chess.BB_EMPTY
- self.custom_bishops_black = chess.BB_EMPTY
- square = 56
- for c in board_part:
- if c == '/':
- square -= 16
- elif c.isdigit():
- square += int(c)
- else:
- color = chess.WHITE if c.isupper() else chess.BLACK
- if c.upper() == 'A':
- if color == chess.WHITE:
- self.amazons_white |= chess.BB_SQUARES[square]
- else:
- self.amazons_black |= chess.BB_SQUARES[square]
- piece_type = AMAZON
- elif c.upper() == 'B':
- if color == chess.WHITE:
- self.custom_bishops_white |= chess.BB_SQUARES[square]
- else:
- self.custom_bishops_black |= chess.BB_SQUARES[square]
- piece_type = chess.BISHOP
- else:
- piece_type = chess.PIECE_SYMBOLS.index(c.lower())
- self._set_piece_at(square, piece_type, color)
- square += 1
- self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
- self.castling_rights = chess.BB_EMPTY
- if '-' not in parts[2]:
- if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
- if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
- if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
- if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
- self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
- self.halfmove_clock = int(parts[4])
- self.fullmove_number = int(parts[5])
- def _set_piece_at(self, square, piece_type, color):
- super()._set_piece_at(square, piece_type, color)
- if piece_type is not None:
- if piece_type == AMAZON:
- if color == chess.WHITE:
- self.amazons_white |= chess.BB_SQUARES[square]
- else:
- self.amazons_black |= chess.BB_SQUARES[square]
- elif piece_type == chess.BISHOP:
- if color == chess.WHITE:
- self.custom_bishops_white |= chess.BB_SQUARES[square]
- else:
- self.custom_bishops_black |= chess.BB_SQUARES[square]
- else:
- self.amazons_white &= ~chess.BB_SQUARES[square]
- self.amazons_black &= ~chess.BB_SQUARES[square]
- self.custom_bishops_white &= ~chess.BB_SQUARES[square]
- self.custom_bishops_black &= ~chess.BB_SQUARES[square]
- def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
- our_pieces = self.occupied_co[self.turn]
- if self.turn == chess.WHITE:
- our_amazons = self.amazons_white
- our_custom_bishops = self.custom_bishops_white
- else:
- our_amazons = self.amazons_black
- our_custom_bishops = self.custom_bishops_black
- # Generujeme tahy pro amazonky
- for from_square in chess.scan_forward(our_amazons & from_mask):
- attacks = self.amazon_attacks(from_square)
- valid_moves = attacks & ~our_pieces & to_mask
- for to_square in chess.scan_forward(valid_moves):
- move = Move(from_square, to_square)
- print(f"Pseudo-legální tah amazonky: {move}")
- yield move
- # Generujeme tahy pro vlastní střelce
- for from_square in chess.scan_forward(our_custom_bishops & from_mask):
- attacks = self.bishop_attacks(from_square)
- valid_moves = attacks & ~our_pieces & to_mask
- for to_square in chess.scan_forward(valid_moves):
- move = Move(from_square, to_square)
- print(f"Pseudo-legální tah vlastního střelce: {move}")
- yield move
- # Generujeme standardní tahy pro ostatní figury
- for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
- if self.piece_type_at(move.from_square) not in [AMAZON, chess.BISHOP]:
- print(f"Standardní pseudo-legální tah: {move}")
- yield move
- def amazon_attacks(self, square):
- return self.queen_attacks(square) | self.knight_attacks(square)
- def queen_attacks(self, square):
- return self.bishop_attacks(square) | self.rook_attacks(square)
- def bishop_attacks(self, square):
- return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
- def rook_attacks(self, square):
- return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
- chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
- def knight_attacks(self, square):
- return chess.BB_KNIGHT_ATTACKS[square]
- # def set_custom_fen(self, fen):
- # parts = fen.split()
- # board_part = parts[0]
- # self.clear()
- # self.amazons_white = chess.BB_EMPTY
- # self.amazons_black = chess.BB_EMPTY
- # self.custom_bishops_white = chess.BB_EMPTY
- # self.custom_bishops_black = chess.BB_EMPTY
- # square = 56
- # for c in board_part:
- # if c == '/':
- # square -= 16
- # elif c.isdigit():
- # square += int(c)
- # else:
- # color = chess.WHITE if c.isupper() else chess.BLACK
- # if c.upper() == 'A':
- # if color == chess.WHITE:
- # self.amazons_white |= chess.BB_SQUARES[square]
- # else:
- # self.amazons_black |= chess.BB_SQUARES[square]
- # piece_type = AMAZON
- # elif c.upper() == 'B':
- # if color == chess.WHITE:
- # self.custom_bishops_white |= chess.BB_SQUARES[square]
- # else:
- # self.custom_bishops_black |= chess.BB_SQUARES[square]
- # piece_type = chess.BISHOP
- # else:
- # piece_type = chess.PIECE_SYMBOLS.index(c.lower())
- # self._set_piece_at(square, piece_type, color)
- # square += 1
- self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
- self.castling_rights = chess.BB_EMPTY
- if '-' not in parts[2]:
- if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
- if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
- if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
- if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
- self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
- self.halfmove_clock = int(parts[4])
- self.fullmove_number = int(parts[5])
- def is_pseudo_legal(self, move):
- from_square = move.from_square
- to_square = move.to_square
- piece = self.piece_at(from_square)
- print(f"Kontrola pseudo-legality tahu: {move}")
- print(f"Figura na {chess.SQUARE_NAMES[from_square]}: {self.piece_symbol(piece)}")
- print(f"Barva na tahu: {'bílá' if self.turn == chess.WHITE else 'černá'}")
- if not piece:
- print("Na výchozím poli není žádná figura")
- return False
- # Speciální kontrola pro amazonku na A2
- if from_square == chess.A2 and piece.piece_type == AMAZON:
- piece_color = chess.WHITE if self.amazons_white & chess.BB_SQUARES[chess.A2] else chess.BLACK
- else:
- piece_color = piece.color
- if piece_color != self.turn:
- print("Figura není barvy hráče na tahu")
- return False
- if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
- print("Cílové pole je obsazeno vlastní figurou")
- return False
- if self.is_castling(move):
- print("Tah je rošáda")
- return True
- if piece.piece_type == AMAZON:
- print("Figura je amazonka")
- attacks = self.amazon_attacks(from_square)
- is_valid = bool(attacks & chess.BB_SQUARES[to_square])
- print(f"Cílové pole {chess.SQUARE_NAMES[to_square]}: {'platné' if is_valid else 'neplatné'}")
- return is_valid
- elif piece.piece_type == chess.BISHOP and ((self.custom_bishops_white & chess.BB_SQUARES[from_square]) or (self.custom_bishops_black & chess.BB_SQUARES[from_square])):
- print("Figura je vlastní střelec")
- return bool(self.bishop_attacks(from_square) & chess.BB_SQUARES[to_square])
- else:
- print("Kontrola standardní pseudo-legality")
- return super().is_pseudo_legal(move)
- # def is_legal(self, move):
- # print(f"Kontrola legality tahu: {move}")
- # if not self.is_pseudo_legal(move):
- # print(f"Tah {move} není pseudo-legální")
- # return False
- # Simulujeme tah bez volání push a pop
- piece = self.piece_at(move.from_square)
- captured_piece = self.piece_at(move.to_square)
- self._remove_piece_at(move.from_square)
- self._set_piece_at(move.to_square, piece.piece_type, piece.color)
- king_square = self.king(self.turn)
- is_check = self._is_attacked_by(not self.turn, king_square)
- # Vracíme pozici do původního stavu
- self._remove_piece_at(move.to_square)
- self._set_piece_at(move.from_square, piece.piece_type, piece.color)
- if captured_piece:
- self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
- print(f"Tah {move} {'staví' if is_check else 'nestaví'} vlastního krále do šachu")
- return not is_check
- def push(self, move):
- print(f"Provádím tah: {move}")
- if not self.is_legal(move):
- raise ValueError(f"Move {move} is not legal in position {self.fen()}")
- piece = self.piece_at(move.from_square)
- captured_piece = self.piece_at(move.to_square)
- # Odstranění figury z původní pozice
- self._remove_piece_at(move.from_square)
- # Přesunutí figury na novou pozici
- self._set_piece_at(move.to_square, piece.piece_type, piece.color)
- # Aktualizace bitboardů pro vlastní figury
- if piece.piece_type == AMAZON:
- if piece.color == chess.WHITE:
- self.amazons_white &= ~chess.BB_SQUARES[move.from_square]
- self.amazons_white |= chess.BB_SQUARES[move.to_square]
- else:
- self.amazons_black &= ~chess.BB_SQUARES[move.from_square]
- self.amazons_black |= chess.BB_SQUARES[move.to_square]
- elif piece.piece_type == chess.BISHOP and ((self.custom_bishops_white & chess.BB_SQUARES[move.from_square]) or (self.custom_bishops_black & chess.BB_SQUARES[move.from_square])):
- if piece.color == chess.WHITE:
- self.custom_bishops_white &= ~chess.BB_SQUARES[move.from_square]
- self.custom_bishops_white |= chess.BB_SQUARES[move.to_square]
- else:
- self.custom_bishops_black &= ~chess.BB_SQUARES[move.from_square]
- self.custom_bishops_black |= chess.BB_SQUARES[move.to_square]
- # Aktualizace turn, fullmove_number a halfmove_clock
- self.turn = not self.turn
- self.fullmove_number += 1 if self.turn == chess.WHITE else 0
- self.halfmove_clock += 1
- if captured_piece or piece.piece_type == chess.PAWN:
- self.halfmove_clock = 0
- # Uložení tahu do historie
- self.move_stack.append(move)
- def pop(self):
- if not self.move_stack:
- print("The move stack is empty.")
- return None
- move = self.move_stack.pop()
- # Vrácení figury na původní pozici
- piece = self.piece_at(move.to_square)
- self._remove_piece_at(move.to_square)
- self._set_piece_at(move.from_square, piece.piece_type, piece.color)
- # Aktualizace bitboardů pro vlastní figury
- if piece.piece_type == AMAZON:
- if piece.color == chess.WHITE:
- self.amazons_white &= ~chess.BB_SQUARES[move.to_square]
- self.amazons_white |= chess.BB_SQUARES[move.from_square]
- else:
- self.amazons_black &= ~chess.BB_SQUARES[move.to_square]
- self.amazons_black |= chess.BB_SQUARES[move.from_square]
- elif piece.piece_type == chess.BISHOP and ((self.custom_bishops_white & chess.BB_SQUARES[move.to_square]) or (self.custom_bishops_black & chess.BB_SQUARES[move.to_square])):
- if piece.color == chess.WHITE:
- self.custom_bishops_white &= ~chess.BB_SQUARES[move.to_square]
- self.custom_bishops_white |= chess.BB_SQUARES[move.from_square]
- else:
- self.custom_bishops_black &= ~chess.BB_SQUARES[move.to_square]
- self.custom_bishops_black |= chess.BB_SQUARES[move.from_square]
- # Obnovení zabrané figury, pokud existovala
- if captured_piece:
- self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
- # Aktualizace turn, fullmove_number a halfmove_clock
- self.turn = not self.turn
- self.fullmove_number -= 1 if self.turn == chess.BLACK else 0
- return move
- def is_check(self):
- king_square = self.king(self.turn)
- if king_square is None:
- return False
- return self._is_attacked_by(not self.turn, king_square)
- # def _is_attacked_by(self, color, square):
- # if super().is_attacked_by(color, square):
- # return True
- # attackers = self.amazons_white if color == chess.WHITE else self.amazons_black
- # for attacker_square in chess.scan_forward(attackers):
- # if self.amazon_attacks(attacker_square) & chess.BB_SQUARES[square]:
- # return True
- # return False
- def is_legal(self, move):
- print(f"Kontrola legality tahu: {move}")
- if not self.is_pseudo_legal(move):
- print(f"Tah {move} není pseudo-legální")
- return False
- # Simulujeme tah bez volání push a pop
- from_square = move.from_square
- to_square = move.to_square
- piece = self.piece_at(from_square)
- captured_piece = self.piece_at(to_square)
- # Speciální kontrola pro amazonku na A2
- if from_square == chess.A2 and piece.piece_type == AMAZON:
- piece_color = chess.WHITE if self.amazons_white & chess.BB_SQUARES[chess.A2] else chess.BLACK
- else:
- piece_color = piece.color
- self._remove_piece_at(from_square)
- self._set_piece_at(to_square, piece.piece_type, piece_color)
- king_square = self.king(self.turn)
- is_check = self._is_attacked_by(not self.turn, king_square)
- # Vracíme pozici do původního stavu
- self._remove_piece_at(to_square)
- self._set_piece_at(from_square, piece.piece_type, piece_color)
- if captured_piece:
- self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
- print(f"Tah {move} {'staví' if is_check else 'nestaví'} vlastního krále do šachu")
- return not is_check
- def _is_attacked_by(self, color, square):
- if self.is_attacked_by(color, square):
- return True
- attackers = self.amazons_white if color == chess.WHITE else self.amazons_black
- for attacker_square in chess.scan_forward(attackers):
- if self.amazon_attacks(attacker_square) & chess.BB_SQUARES[square]:
- return True
- return False
- def debug_amazons(self):
- print(f"Bitboard bílých amazonek: {format(self.amazons_white, '064b')}")
- print(f"Bitboard černých amazonek: {format(self.amazons_black, '064b')}")
- for square in chess.SQUARES:
- if self.amazons_white & chess.BB_SQUARES[square]:
- print(f"Bílá amazonka na {chess.SQUARE_NAMES[square]}")
- if self.amazons_black & chess.BB_SQUARES[square]:
- print(f"Černá amazonka na {chess.SQUARE_NAMES[square]}")
- def debug_custom_bishops(self):
- print(f"Bitboard bílých vlastních střelců: {format(self.custom_bishops_white, '064b')}")
- print(f"Bitboard černých vlastních střelců: {format(self.custom_bishops_black, '064b')}")
- for square in chess.SQUARES:
- if self.custom_bishops_white & chess.BB_SQUARES[square]:
- print(f"Bílý vlastní střelec na {chess.SQUARE_NAMES[square]}")
- if self.custom_bishops_black & chess.BB_SQUARES[square]:
- print(f"Černý vlastní střelec na {chess.SQUARE_NAMES[square]}")
- def piece_symbol(self, piece):
- if piece is None:
- return '.'
- if piece.piece_type == AMAZON:
- return 'A' if piece.color == chess.WHITE else 'a'
- return piece.symbol()
- def piece_type_at(self, square):
- if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
- return AMAZON
- return super().piece_type_at(square)
- def color_at(self, square):
- if self.amazons_white & chess.BB_SQUARES[square]:
- return chess.WHITE
- if self.amazons_black & chess.BB_SQUARES[square]:
- return chess.BLACK
- return super().color_at(square)
- @property
- def legal_moves(self):
- legal_moves = [move for move in self.generate_pseudo_legal_moves() if self.is_legal(move)]
- for move in legal_moves:
- piece = self.piece_at(move.from_square)
- print(f"Legální tah: {move}")
- if piece.piece_type == AMAZON:
- print(f"Legální tah amazonky {'A' if piece.color == chess.WHITE else 'a'}: {move}")
- return legal_moves
- def __str__(self):
- builder = []
- for square in chess.SQUARES_180:
- piece = self.piece_at(square)
- if (self.amazons_white & chess.BB_SQUARES[square]):
- symbol = 'A'
- elif (self.amazons_black & chess.BB_SQUARES[square]):
- symbol = 'a'
- else:
- symbol = self.piece_symbol(piece) if piece else '.'
- builder.append(symbol)
- if chess.square_file(square) == 7:
- if square != chess.H1:
- builder.append('\n')
- return ''.join(builder)
- if __name__ == "__main__":
- start_fen = "a7/3k4/8/8/1B6/8/A7/6K1 w - - 0 1"
- print(f"Vytváření šachovnice s FEN: {start_fen}")
- board = CustomBoard(start_fen)
- print("Současná pozice:")
- print(board)
- print("Generování legálních tahů pro počáteční pozici...")
- legal_moves = list(board.legal_moves)
- print(f"Počet legálních tahů: {len(legal_moves)}")
- print("Legální tahy:")
- for move in legal_moves:
- from_square = chess.SQUARE_NAMES[move.from_square]
- to_square = chess.SQUARE_NAMES[move.to_square]
- piece = board.piece_at(move.from_square)
- print(f"{board.piece_symbol(piece)}: {from_square}-{to_square}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement