1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] Fixing a code with import chess module for Fairy-Pieces in Python: it does not...

Discussão em 'Python' iniciado por Stack, Julho 8, 2025.

  1. Stack

    Stack Membro Participativo

    Fixing a code with import chess module for Fairy-Pieces in Python is required: it does not produce the optimal move Aa4a1 but sub-optimal Kg8h8 after which a one move checkmate ce3e1 may be delivered.The code is given here. Here A stands for Amazon which is white Queen plus Knight and c is black cyril which is rook plus knight. I will not only offer a Bounty but also 160 $ with a bank transfer once this bug is fixed.

    import time
    from datetime import datetime
    from collections import deque
    import copy

    def print_board(board):
    print(str(board))

    class ChessBoard:
    """Vlastní implementace šachovnice pro pohádkové figury"""

    def __init__(self, fen=None):
    self.board = [[None for _ in range(8)] for _ in range(8)]
    self.turn = True # True = bílý, False = černý
    self.castling_rights = {'K': True, 'Q': True, 'k': True, 'q': True}
    self.en_passant = None
    self.halfmove_clock = 0
    self.fullmove_number = 1

    if fen:
    self.set_fen(fen)
    else:
    self.setup_initial_position()

    def __str__(self):
    rows = []
    for i, row in enumerate(self.board[::-1], 1):
    safe_row = []
    for piece in row:
    if piece is None:
    safe_row.append('.')
    elif isinstance(piece, tuple):
    color, symbol = piece
    safe_row.append(symbol.upper() if color == 'w' else symbol.lower())
    else:
    safe_row.append(str(piece))
    rows.append(f"{8 - i + 1} " + " ".join(safe_row))
    rows.append(" a b c d e f g h")
    return "\n".join(rows)

    def setup_initial_position(self):
    """Nastaví základní pozici"""
    pieces = ['R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R']
    for i, piece in enumerate(pieces):
    self.board[0] = ('w', piece)
    for i in range(8):
    self.board[1] = ('w', 'P')

    pieces = ['R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R']
    for i, piece in enumerate(pieces):
    self.board[7] = ('b', piece)
    for i in range(8):
    self.board[6] = ('b', 'P')

    def set_fen(self, fen_string):
    """Nastaví pozici z FEN stringu"""
    parts = fen_string.split()

    # Pozice figur
    rows = parts[0].split('/')
    for rank, row in enumerate(rows):
    file_idx = 0
    for char in row:
    if char.isdigit():
    for _ in range(int(char)):
    self.board[7-rank][file_idx] = None
    file_idx += 1
    else:
    color = 'w' if char.isupper() else 'b'
    self.board[7-rank][file_idx] = (color, char.upper())
    file_idx += 1

    # Na tahu
    self.turn = parts[1] == 'w'

    # Rošáda
    castling = parts[2] if len(parts) > 2 else '-'
    self.castling_rights = {
    'K': 'K' in castling,
    'Q': 'Q' in castling,
    'k': 'k' in castling,
    'q': 'q' in castling
    }

    # En passant
    self.en_passant = parts[3] if len(parts) > 3 and parts[3] != '-' else None

    # Počítadla tahů
    self.halfmove_clock = int(parts[4]) if len(parts) > 4 else 0
    self.fullmove_number = int(parts[5]) if len(parts) > 5 else 1

    def get_fen(self):
    """Vrátí FEN string pozice"""
    fen_parts = []
    for rank in range(7, -1, -1):
    row_fen = ""
    empty_count = 0

    for file in range(8):
    piece = self.board[rank][file]
    if piece is None:
    empty_count += 1
    else:
    if empty_count > 0:
    row_fen += str(empty_count)
    empty_count = 0
    color, piece_type = piece
    row_fen += piece_type if color == 'w' else piece_type.lower()

    if empty_count > 0:
    row_fen += str(empty_count)

    fen_parts.append(row_fen)

    position = '/'.join(fen_parts)

    # Na tahu
    turn = 'w' if self.turn else 'b'

    # Rošáda
    castling = ''
    for right in ['K', 'Q', 'k', 'q']:
    if self.castling_rights
    :
    castling += right
    if not castling:
    castling = '-'

    # En passant
    en_passant = self.en_passant if self.en_passant else '-'

    return f"{position} {turn} {castling} {en_passant} {self.halfmove_clock} {self.fullmove_number}"

    def copy(self):
    """Vytvoří kopii šachovnice"""
    new_board = ChessBoard()
    new_board.board = [row[:] for row in self.board]
    new_board.turn = self.turn
    new_board.castling_rights = self.castling_rights.copy()
    new_board.en_passant = self.en_passant
    new_board.halfmove_clock = self.halfmove_clock
    new_board.fullmove_number = self.fullmove_number
    return new_board

    def make_move(self, from_pos, to_pos):
    """Provede tah"""
    from_rank, from_file = from_pos
    to_rank, to_file = to_pos

    piece = self.board[from_rank][from_file]
    self.board[to_rank][to_file] = piece
    self.board[from_rank][from_file] = None

    # Změnit hráče na tahu
    self.turn = not self.turn

    # Inkrementovat počítadla
    if self.turn:
    self.fullmove_number += 1
    self.halfmove_clock += 1

    def find_king(self, color):
    """Najde krále dané barvy"""
    for rank in range(8):
    for file in range(8):
    piece = self.board[rank][file]
    if piece and piece[0] == color and piece[1] == 'K':
    return (rank, file)
    return None

    def is_check(self, color):
    """Kontroluje zda je král v šachu"""
    king_pos = self.find_king(color)
    if not king_pos:
    return False

    enemy_color = 'b' if color == 'w' else 'w'

    for rank in range(8):
    for file in range(8):
    piece = self.board[rank][file]
    if piece and piece[0] == enemy_color:
    if self.attacks_square((rank, file), king_pos):
    return True
    return False

    def attacks_square(self, from_pos, to_pos):
    """Kontroluje zda figura útočí na dané pole"""
    rank, file = from_pos
    piece = self.board[rank][file]

    if not piece:
    return False

    color, piece_type = piece

    if piece_type == 'P':
    return self.pawn_attacks(from_pos, to_pos, color)
    elif piece_type == 'R':
    return self.rook_attacks(from_pos, to_pos)
    elif piece_type == 'N':
    return self.knight_attacks(from_pos, to_pos)
    elif piece_type == 'B':
    return self.bishop_attacks(from_pos, to_pos)
    elif piece_type == 'Q':
    return self.queen_attacks(from_pos, to_pos)
    elif piece_type == 'K':
    return self.king_attacks(from_pos, to_pos)
    elif piece_type == 'A': # Amazonka (Q+N)
    return self.queen_attacks(from_pos, to_pos) or self.knight_attacks(from_pos, to_pos)
    elif piece_type == 'C': # Cyril (R+N)
    return self.rook_attacks(from_pos, to_pos) or self.knight_attacks(from_pos, to_pos)
    elif piece_type == 'E': # Eve (B+N)
    return self.bishop_attacks(from_pos, to_pos) or self.knight_attacks(from_pos, to_pos)

    return False

    def pawn_attacks(self, from_pos, to_pos, color):
    """Kontroluje útok pěšce"""
    from_rank, from_file = from_pos
    to_rank, to_file = to_pos

    direction = 1 if color == 'w' else -1

    return (abs(from_file - to_file) == 1 and
    to_rank - from_rank == direction)

    def knight_attacks(self, from_pos, to_pos):
    """Kontroluje útok jezdce"""
    from_rank, from_file = from_pos
    to_rank, to_file = to_pos

    dr = abs(from_rank - to_rank)
    df = abs(from_file - to_file)

    return (dr == 2 and df == 1) or (dr == 1 and df == 2)

    def rook_attacks(self, from_pos, to_pos):
    """Kontroluje útok věže"""
    from_rank, from_file = from_pos
    to_rank, to_file = to_pos

    if from_rank != to_rank and from_file != to_file:
    return False

    if from_rank == to_rank: # Horizontální
    start = min(from_file, to_file) + 1
    end = max(from_file, to_file)
    for f in range(start, end):
    if self.board[from_rank][f] is not None:
    return False
    else: # Vertikální
    start = min(from_rank, to_rank) + 1
    end = max(from_rank, to_rank)
    for r in range(start, end):
    if self.board[r][from_file] is not None:
    return False

    return True

    def bishop_attacks(self, from_pos, to_pos):
    """Kontroluje útok střelce"""
    from_rank, from_file = from_pos
    to_rank, to_file = to_pos

    dr = to_rank - from_rank
    df = to_file - from_file

    if abs(dr) != abs(df) or dr == 0:
    return False

    step_r = 1 if dr > 0 else -1
    step_f = 1 if df > 0 else -1

    steps = abs(dr)
    for i in range(1, steps):
    check_rank = from_rank + i * step_r
    check_file = from_file + i * step_f
    if self.board[check_rank][check_file] is not None:
    return False

    return True

    def queen_attacks(self, from_pos, to_pos):
    """Kontroluje útok dámy"""
    return self.rook_attacks(from_pos, to_pos) or self.bishop_attacks(from_pos, to_pos)

    def king_attacks(self, from_pos, to_pos):
    """Kontroluje útok krále"""
    from_rank, from_file = from_pos
    to_rank, to_file = to_pos

    return (abs(from_rank - to_rank) <= 1 and
    abs(from_file - to_file) <= 1 and
    from_pos != to_pos)

    class FairyChessAnalyzer:
    def __init__(self, start_fen):
    self.start_fen = start_fen
    self.L = []
    self.fen_to_index = {}
    self.iteration_count = 0
    # Konstanty pro hodnocení (z pohledu aktuálního hráče na tahu)
    self.WIN = 1000 # Vyhrává hráč na tahu
    self.LOSE = -1000 # Prohrává hráč na tahu
    self.DRAW = 0 # Remíza

    def print_time(self, message=""):
    """Vypíše čas ve formátu %hh%mm%ss"""
    now = datetime.now()
    time_str = now.strftime("%H:%M:%S")
    print(f"[{time_str}] Průchod {self.iteration_count}: {message}")

    def generate_moves(self, board, from_pos):
    """Generuje všechny možné tahy z dané pozice"""
    rank, file = from_pos
    piece = board.board[rank][file]

    if not piece:
    return []

    color, piece_type = piece
    moves = []

    # Kontrola zda je figura na tahu
    if (color == 'w') != board.turn:
    return []

    if piece_type == 'P':
    moves = self.generate_pawn_moves(board, from_pos)
    elif piece_type == 'R':
    moves = self.generate_rook_moves(board, from_pos)
    elif piece_type == 'N':
    moves = self.generate_knight_moves(board, from_pos)
    elif piece_type == 'B':
    moves = self.generate_bishop_moves(board, from_pos)
    elif piece_type == 'Q':
    moves = self.generate_queen_moves(board, from_pos)
    elif piece_type == 'K':
    moves = self.generate_king_moves(board, from_pos)
    elif piece_type == 'A': # Amazonka (Q+N)
    moves = self.generate_queen_moves(board, from_pos) + self.generate_knight_moves(board, from_pos)
    elif piece_type == 'C': # Cyril (R+N)
    moves = self.generate_rook_moves(board, from_pos) + self.generate_knight_moves(board, from_pos)
    elif piece_type == 'E': # Eve (B+N)
    moves = self.generate_bishop_moves(board, from_pos) + self.generate_knight_moves(board, from_pos)

    # Filtrovat legální tahy
    legal_moves = []
    for move in moves:
    if self.is_move_legal(board, from_pos, move):
    legal_moves.append(move)

    return legal_moves

    def generate_pawn_moves(self, board, from_pos):
    """Generuje tahy pěšce"""
    rank, file = from_pos
    piece = board.board[rank][file]
    color = piece[0]
    moves = []

    direction = 1 if color == 'w' else -1
    start_rank = 1 if color == 'w' else 6

    # Tah dopředu
    new_rank = rank + direction
    if 0 <= new_rank <= 7 and board.board[new_rank][file] is None:
    moves.append((new_rank, file))

    # Dvojitý tah z výchozí pozice
    if rank == start_rank and board.board[new_rank + direction][file] is None:
    moves.append((new_rank + direction, file))

    # Braní
    for df in [-1, 1]:
    new_file = file + df
    if 0 <= new_file <= 7 and 0 <= new_rank <= 7:
    target = board.board[new_rank][new_file]
    if target and target[0] != color:
    moves.append((new_rank, new_file))

    return moves

    def generate_knight_moves(self, board, from_pos):
    """Generuje tahy jezdce"""
    rank, file = from_pos
    piece = board.board[rank][file]
    color = piece[0]
    moves = []

    knight_moves = [(2,1), (2,-1), (-2,1), (-2,-1), (1,2), (1,-2), (-1,2), (-1,-2)]

    for dr, df in knight_moves:
    new_rank = rank + dr
    new_file = file + df

    if 0 <= new_rank <= 7 and 0 <= new_file <= 7:
    target = board.board[new_rank][new_file]
    if not target or target[0] != color:
    moves.append((new_rank, new_file))

    return moves

    def generate_sliding_moves(self, board, from_pos, directions):
    """Generuje tahy pro posuvné figury"""
    rank, file = from_pos
    piece = board.board[rank][file]
    color = piece[0]
    moves = []

    for dr, df in directions:
    for distance in range(1, 8):
    new_rank = rank + dr * distance
    new_file = file + df * distance

    if not (0 <= new_rank <= 7 and 0 <= new_file <= 7):
    break

    target = board.board[new_rank][new_file]

    if not target:
    moves.append((new_rank, new_file))
    elif target[0] != color:
    moves.append((new_rank, new_file))
    break
    else:
    break

    return moves

    def generate_rook_moves(self, board, from_pos):
    """Generuje tahy věže"""
    directions = [(0,1), (0,-1), (1,0), (-1,0)]
    return self.generate_sliding_moves(board, from_pos, directions)

    def generate_bishop_moves(self, board, from_pos):
    """Generuje tahy střelce"""
    directions = [(1,1), (1,-1), (-1,1), (-1,-1)]
    return self.generate_sliding_moves(board, from_pos, directions)

    def generate_queen_moves(self, board, from_pos):
    """Generuje tahy dámy"""
    directions = [(0,1), (0,-1), (1,0), (-1,0), (1,1), (1,-1), (-1,1), (-1,-1)]
    return self.generate_sliding_moves(board, from_pos, directions)

    def generate_king_moves(self, board, from_pos):
    """Generuje tahy krále"""
    rank, file = from_pos
    piece = board.board[rank][file]
    color = piece[0]
    moves = []

    for dr in [-1, 0, 1]:
    for df in [-1, 0, 1]:
    if dr == 0 and df == 0:
    continue

    new_rank = rank + dr
    new_file = file + df

    if 0 <= new_rank <= 7 and 0 <= new_file <= 7:
    target = board.board[new_rank][new_file]
    if not target or target[0] != color:
    moves.append((new_rank, new_file))

    return moves

    def is_move_legal(self, board, from_pos, to_pos):
    """Kontroluje zda je tah legální"""
    temp_board = board.copy()
    temp_board.make_move(from_pos, to_pos)

    # Kontrola zda vlastní král není v šachu
    color = 'w' if board.turn else 'b'
    return not temp_board.is_check(color)

    def get_all_legal_moves(self, board):
    """Získá všechny legální tahy"""
    moves = []

    for rank in range(8):
    for file in range(8):
    piece = board.board[rank][file]
    if piece:
    color = piece[0]
    if (color == 'w') == board.turn:
    piece_moves = self.generate_moves(board, (rank, file))
    for to_pos in piece_moves:
    moves.append((rank, file, to_pos[0], to_pos[1]))

    return moves

    def evaluate_position(self, board):
    """Evaluuje pozici - vrací hodnotu z pohledu hráče na tahu"""
    # Získat všechny legální tahy
    legal_moves = self.get_all_legal_moves(board)

    # Kontrola koncových pozic
    if len(legal_moves) == 0:
    current_color = 'w' if board.turn else 'b'
    if board.is_check(current_color):
    # Mat - hráč na tahu prohrává
    return self.LOSE
    else:
    # Pat - remíza
    return self.DRAW

    # Pozice není koncová
    return None

    def create_position_dict(self, fen, depth):
    """Vytvoří slovník pro pozici"""
    board = ChessBoard(fen)
    evaluation = self.evaluate_position(board)

    return {
    'depth': depth,
    'N': [], # Následníci
    'P': [], # Předchůdci
    'FEN': board.get_fen(),
    'board': board,
    'evaluation': evaluation,
    'minimax_value': evaluation
    }

    def build_position_tree(self, max_depth=5):
    """Postaví strom pozic pomocí BFS"""
    self.iteration_count += 1
    self.print_time("Začátek generování stromu pozic")

    # Inicializace
    start_dict = self.create_position_dict(self.start_fen, 0)
    self.L.append(start_dict)
    self.fen_to_index[start_dict['FEN']] = 0

    queue = deque([0])

    for depth in range(max_depth):
    self.iteration_count += 1

    if not queue:
    break

    level_size = len(queue)
    self.print_time(f"Hloubka {depth}, pozic: {level_size}")

    for _ in range(level_size):
    if not queue:
    break

    current_index = queue.popleft()
    current_pos = self.L[current_index]

    # Přeskočit koncové pozice
    if current_pos['evaluation'] is not None:
    continue

    try:
    # Získat všechny legální tahy
    legal_moves = self.get_all_legal_moves(current_pos['board'])

    for move in legal_moves:
    from_rank, from_file, to_rank, to_file = move

    # Vytvořit novou pozici
    temp_board = current_pos['board'].copy()
    temp_board.make_move((from_rank, from_file), (to_rank, to_file))
    new_fen = temp_board.get_fen()

    if new_fen not in self.fen_to_index:
    # Nová pozice
    new_dict = self.create_position_dict(new_fen, depth + 1)
    new_index = len(self.L)
    self.L.append(new_dict)
    self.fen_to_index[n


    PREMATURE END DUE TO LIMIT OF CHARACTERS

    Continue reading...​

Compartilhe esta Página