I've created a code for chess endgame with non-standard figures Amazon/Eve/Cyril.
Amazon, say, is like Queen and Knight at one piece.
The code is here:
The fix amounts to outputting continuous chain of numbers like -994,995,-996,997,-998,999,-1000.
Once fixed I can offer around 100$.
Amazon, say, is like Queen and Knight at one piece.
The code is here:
import chess
from typing import Iterator, Optional, Dict, Tuple
from chess import Move, BB_ALL, Bitboard, PieceType, Color
import time
from collections import deque
import threading
# Definice nových figur
AMAZON = 7
CYRIL = 8
EVE = 9
# Rozšíření seznamu PIECE_SYMBOLS
chess.PIECE_SYMBOLS.append('a')
chess.PIECE_SYMBOLS.append('c')
chess.PIECE_SYMBOLS.append('e')
class CustomBoard(chess.Board):
def __init__(self, fen=None):
self.amazons_white = chess.BB_EMPTY
self.amazons_black = chess.BB_EMPTY
self.cyrils_white = chess.BB_EMPTY
self.cyrils_black = chess.BB_EMPTY
self.eves_white = chess.BB_EMPTY
self.eves_black = chess.BB_EMPTY
super().__init__(None)
if fen:
self.set_custom_fen(fen)
self.debug_amazons()
self.debug_cyrils()
self.debug_eves()
def clear_square(self, square):
super()._remove_piece_at(square)
self.amazons_white &= ~chess.BB_SQUARES[square]
self.amazons_black &= ~chess.BB_SQUARES[square]
self.cyrils_white &= ~chess.BB_SQUARES[square]
self.cyrils_black &= ~chess.BB_SQUARES[square]
self.eves_white &= ~chess.BB_SQUARES[square]
self.eves_black &= ~chess.BB_SQUARES[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.cyrils_white = chess.BB_EMPTY
self.cyrils_black = chess.BB_EMPTY
self.eves_white = chess.BB_EMPTY
self.eves_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() == 'C':
if color == chess.WHITE:
self.cyrils_white |= chess.BB_SQUARES[square]
else:
self.cyrils_black |= chess.BB_SQUARES[square]
piece_type = CYRIL
elif c.upper() == 'E':
if color == chess.WHITE:
self.eves_white |= chess.BB_SQUARES[square]
else:
self.eves_black |= chess.BB_SQUARES[square]
piece_type = EVE
elif c == 'P' and chess.square_rank(square) == 7:
piece_type = AMAZON
color = chess.WHITE
elif c == 'p' and chess.square_rank(square) == 0:
piece_type = AMAZON
color = chess.BLACK
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
def _set_piece_at(self, square: chess.Square, piece_type: PieceType, color: Color) -> None:
self.clear_square(square)
super()._set_piece_at(square, piece_type, color)
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 == CYRIL:
if color == chess.WHITE:
self.cyrils_white |= chess.BB_SQUARES[square]
else:
self.cyrils_black |= chess.BB_SQUARES[square]
elif piece_type == EVE:
if color == chess.WHITE:
self.eves_white |= chess.BB_SQUARES[square]
else:
self.eves_black |= chess.BB_SQUARES[square]
def piece_at(self, square: chess.Square) -> Optional[chess.Piece]:
if self.amazons_white & chess.BB_SQUARES[square]:
return chess.Piece(AMAZON, chess.WHITE)
elif self.amazons_black & chess.BB_SQUARES[square]:
return chess.Piece(AMAZON, chess.BLACK)
elif self.cyrils_white & chess.BB_SQUARES[square]:
return chess.Piece(CYRIL, chess.WHITE)
elif self.cyrils_black & chess.BB_SQUARES[square]:
return chess.Piece(CYRIL, chess.BLACK)
elif self.eves_white & chess.BB_SQUARES[square]:
return chess.Piece(EVE, chess.WHITE)
elif self.eves_black & chess.BB_SQUARES[square]:
return chess.Piece(EVE, chess.BLACK)
return super().piece_at(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_cyrils = self.cyrils_white
our_eves = self.eves_white
else:
our_amazons = self.amazons_black
our_cyrils = self.cyrils_black
our_eves = self.eves_black
# Generování tahů 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):
yield Move(from_square, to_square)
# Generování tahů pro Cyrily
for from_square in chess.scan_forward(our_cyrils & from_mask):
attacks = self.cyril_attacks(from_square)
valid_moves = attacks & ~our_pieces & to_mask
for to_square in chess.scan_forward(valid_moves):
yield Move(from_square, to_square)
# Generování tahů pro Evy
for from_square in chess.scan_forward(our_eves & from_mask):
attacks = self.eve_attacks(from_square)
valid_moves = attacks & ~our_pieces & to_mask
for to_square in chess.scan_forward(valid_moves):
yield Move(from_square, to_square)
# Generování tahů pro standardní figury
for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
piece = self.piece_at(move.from_square)
if piece and piece.piece_type not in [AMAZON, CYRIL, EVE]:
yield move
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 amazon_attacks(self, square):
return self.queen_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
def cyril_attacks(self, square):
return self.rook_attacks(square) | chess.BB_KNIGHT_ATTACKS[quare]
def eve_attacks(self, square):
return self.bishop_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
def is_pseudo_legal(self, move):
from_square = move.from_square
to_square = move.to_square
piece = self.piece_at(from_square)
if not piece or piece.color != self.turn:
return False
if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
return False
if self.is_castling(move):
return True
if piece.piece_type == AMAZON:
return bool(self.amazon_attacks(from_square) & chess.BB_SQUARES[to_square])
elif piece.piece_type == CYRIL:
return bool(self.cyril_attacks(from_square) & chess.BB_SQUARES[to_square])
elif piece.piece_type == EVE:
return bool(self.eve_attacks(from_square) & chess.BB_SQUARES[to_square])
else:
return super().is_pseudo_legal(move)
def is_legal(self, move):
if not self.is_pseudo_legal(move):
return False
from_square = move.from_square
to_square = move.to_square
piece = self.piece_at(from_square)
captured_piece = self.piece_at(to_square)
# Kontrola pro všechny figury: nelze brát figuru stejné barvy
if captured_piece and captured_piece.color == piece.color:
return False
# Dočasně provést tah
self.clear_square(from_square)
self._set_piece_at(to_square, piece.piece_type, piece.color)
# Najít pozici krále
king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
# Kontrola, zda je král v šachu po tahu
is_check = self._is_attacked_by(not self.turn, king_square) if king_square is not None else False
# Vrátit pozici do původního stavu
self.clear_square(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)
return not is_check
def _is_attacked_by(self, color, square):
attackers = self.attackers(color, square)
return bool(attackers)
def attackers(self, color: Color, square: chess.Square) -> Bitboard:
if square is None:
return chess.BB_EMPTY
attackers = chess.BB_EMPTY
occupied = self.occupied
occupied_co = self.occupied_co[color]
# Jezdci
attackers |= chess.BB_KNIGHT_ATTACKS[square] & self.knights & occupied_co
# Král
attackers |= chess.BB_KING_ATTACKS[square] & self.kings & occupied_co
# Pěšci
if color == chess.WHITE:
attackers |= chess.BB_PAWN_ATTACKS[chess.BLACK][square] & self.pawns & occupied_co
else:
attackers |= chess.BB_PAWN_ATTACKS[chess.WHITE][square] & self.pawns & occupied_co
# Střelcové útoky (včetně dam a amazonek)
bishop_attacks = chess.BB_DIAG_ATTACKS[square][occupied & chess.BB_DIAG_MASKS[square]]
attackers |= bishop_attacks & ((self.bishops | self.queens) & occupied_co)
# Věžové útoky (včetně dam, amazonek a cyrilů)
rook_attacks = (
chess.BB_RANK_ATTACKS[square][occupied & chess.BB_RANK_MASKS[square]] |
chess.BB_FILE_ATTACKS[square][occupied & chess.BB_FILE_MASKS[square]]
)
attackers |= rook_attacks & ((self.rooks | self.queens) & occupied_co)
# Amazonky (Dáma + Jezdec)
amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
amazon_attacks = bishop_attacks | rook_attacks | chess.BB_KNIGHT_ATTACKS[square]
attackers |= amazon_attacks & amazons
# Cyrilové (Věž + Jezdec)
cyrils = self.cyrils_white if color == chess.WHITE else self.cyrils_black
cyril_attacks = rook_attacks | chess.BB_KNIGHT_ATTACKS[square]
attackers |= cyril_attacks & cyrils
# Evy (Střelec + Jezdec)
eves = self.eves_white if color == chess.WHITE else self.eves_black
eve_attacks = bishop_attacks | chess.BB_KNIGHT_ATTACKS[square]
attackers |= eve_attacks & eves
return attackers
def push(self, 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)
self.clear_square(move.from_square)
self.clear_square(move.to_square)
self._set_piece_at(move.to_square, piece.piece_type, piece.color)
self.turn = not self.turn
self.move_stack.append((move, captured_piece))
def pop(self):
if not self.move_stack:
return None
move, captured_piece = self.move_stack.pop()
piece = self.piece_at(move.to_square)
self.clear_square(move.from_square)
self.clear_square(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)
self.turn = not self.turn
return move
def is_check(self):
king_square = self.king(self.turn)
if king_square is None:
return False
is_check = self._is_attacked_by(not self.turn, king_square)
return is_check
def is_checkmate(self):
if not self.is_check():
return False
legal_moves = list(self.generate_legal_moves())
return len(legal_moves) == 0
def is_game_over(self):
return self.is_checkmate() or self.is_stalemate() or self.is_insufficient_material()
def is_stalemate(self):
if self.is_check():
return False
legal_moves = list(self.generate_legal_moves())
return len(legal_moves) == 0
def is_insufficient_material(self):
return (self.pawns | self.rooks | self.queens | self.amazons_white | self.amazons_black |
self.cyrils_white | self.cyrils_black | self.eves_white | self.eves_black) == 0 and (
chess.popcount(self.occupied) <= 3
)
def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
for move in self.generate_pseudo_legal_moves(from_mask, to_mask):
if self.is_legal(move):
yield move
def debug_amazons(self):
pass
def debug_cyrils(self):
pass
def debug_eves(self):
pass
def piece_symbol(self, piece):
if piece is None:
return '.'
if piece.piece_type == AMAZON:
return 'A' if piece.color == chess.WHITE else 'a'
if piece.piece_type == CYRIL:
return 'C' if piece.color == chess.WHITE else 'c'
if piece.piece_type == EVE:
return 'E' if piece.color == chess.WHITE else 'e'
return piece.symbol()
def piece_type_at(self, square):
if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
return AMAZON
if (self.cyrils_white | self.cyrils_black) & chess.BB_SQUARES[square]:
return CYRIL
if (self.eves_white | self.eves_black) & chess.BB_SQUARES[square]:
return EVE
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
if self.cyrils_white & chess.BB_SQUARES[square]:
return chess.WHITE
if self.cyrils_black & chess.BB_SQUARES[square]:
return chess.BLACK
if self.eves_white & chess.BB_SQUARES[square]:
return chess.WHITE
if self.eves_black & chess.BB_SQUARES[square]:
return chess.BLACK
return super().color_at(square)
@property
def legal_moves(self):
return list(self.generate_legal_moves())
def __str__(self):
builder = []
for square in chess.SQUARES_180:
piece = self.piece_at(square)
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)
def format_time(seconds):
hours, remainder = divmod(seconds, 3600)
minutes, seconds = divmod(remainder, 60)
return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
def print_elapsed_time(stop_event, start_time):
while not stop_event.is_set():
elapsed_time = time.time() - start_time
print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
time.sleep(1)
def simplify_fen(fen):
return ' '.join(fen.split()[:4])
def calculate_optimal_moves(start_fen: str) -> Dict[str, Tuple[int, str]]:
print("Funkce calculate_optimal_moves byla zavolána8")
print(f"Počáteční FEN: {start_fen}")
board = CustomBoard(start_fen)
POZ = {1: simplify_fen(start_fen)}
AR = {simplify_fen(start_fen): {'used': 0, 'to_end': None, 'depth': 0, 'type': 'normal', 'parent': None}}
N = 1
M = 0
start_time = time.time()
current_depth = 0
positions_at_depth = {0: 0}
depth_start_time = start_time
stop_event = threading.Event()
timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
timer_thread.start()
try:
print("Začínám generovat pozice...")
print("Počáteční pozice:7")
print_board(start_fen)
depth_1_positions = [] # Seznam pro ukládání pozic v hloubce 1
# Generate all positions
while M < N:
M += 1
current_fen = POZ[M]
board.set_custom_fen(current_fen)
simplified_current_fen = simplify_fen(current_fen)
current_depth = AR[simplified_current_fen]['depth']
if current_depth not in positions_at_depth:
positions_at_depth[current_depth] = 0
if current_depth > 0:
depth_time = time.time() - depth_start_time
total_time = time.time() - start_time
print(f"\nHloubka {current_depth - 1}: {positions_at_depth[current_depth - 1]} pozic, "
f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
if current_depth == 1:
print("Všechny pozice v hloubce 1:")
for pos in depth_1_positions:
print_board(pos)
print()
depth_start_time = time.time()
positions_at_depth[current_depth] += 1
if current_depth == 1:
depth_1_positions.append(current_fen)
if AR[simplified_current_fen]['used'] == 0:
AR[simplified_current_fen]['used'] = 1
legal_moves = list(board.legal_moves)
for move in legal_moves:
board.push(move)
POZ2 = board.fen()
simplified_POZ2 = simplify_fen(POZ2)
if simplified_POZ2 not in AR:
N += 1
POZ[N] = simplified_POZ2
AR[simplified_POZ2] = {
'used': 0,
'to_end': None,
'depth': current_depth + 1,
'type': 'normal',
'parent': simplified_current_fen
}
board.pop()
# Print last depth
depth_time = time.time() - depth_start_time
total_time = time.time() - start_time
print(f"\nHloubka {current_depth}: {positions_at_depth[current_depth]} pozic, "
f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
print(f"Příklad pozice v hloubce {current_depth}:")
print_board(current_fen)
print(f"Generování pozic dokončeno. Celkový počet pozic: {N}")
# Initial evaluation
print("\nZačínám počáteční ohodnocení...")
F_checkmate = 0
F_stalemate = 0
F_drawing = 0
F_check = 0
F_normal = 0
for i in range(1, N + 1):
current_fen = POZ[i]
board.set_custom_fen(current_fen)
simplified_current_fen = simplify_fen(current_fen)
if board.is_checkmate():
AR[simplified_current_fen]['to_end'] = -1000
AR[simplified_current_fen]['type'] = 'checkmate'
F_checkmate += 1
elif board.is_stalemate():
AR[simplified_current_fen]['to_end'] = 0
AR[simplified_current_fen]['type'] = 'stalemate'
F_stalemate += 1
elif board.is_insufficient_material():
AR[simplified_current_fen]['to_end'] = 0
AR[simplified_current_fen]['type'] = 'drawing'
F_drawing += 1
elif board.is_check():
AR[simplified_current_fen]['to_end'] = None
AR[simplified_current_fen]['type'] = 'check'
F_check += 1
else:
AR[simplified_current_fen]['to_end'] = None
AR[simplified_current_fen]['type'] = 'normal'
F_normal += 1
print(f"Počet pozic v matu je {F_checkmate}")
print(f"Počet pozic v patu je {F_stalemate}")
print(f"Počet pozic v remíze je {F_drawing}")
print(f"Počet pozic v šachu je {F_check}")
print(f"Počet normálních pozic je {F_normal}")
# Iterative evaluation
print("\nZačínám iterativní ohodnocení...6")
uroven = 0
while True:
uroven += 1
level_start_time = time.time()
print(f"Výpočet v úrovni {uroven}")
changed = False
current_level_positions = 0
for i in range(1, N + 1):
current_fen = POZ[i]
board.set_custom_fen(current_fen)
simplified_current_fen = simplify_fen(current_fen)
if AR[simplified_current_fen]['to_end'] is None or AR[simplified_current_fen]['to_end'] == 0:
hod = -2000
for move in board.legal_moves:
board.push(move)
POZ2 = board.fen()
simplified_POZ2 = simplify_fen(POZ2)
if simplified_POZ2 in AR and AR[simplified_POZ2]['to_end'] is not None:
hod2 = -AR[simplified_POZ2]['to_end']
if hod2 > hod:
hod = hod2
board.pop()
if hod == 1001 - uroven:
new_to_end = 1000 - uroven
new_type = 'winning'
elif hod == -1001 + uroven:
new_to_end = -1000 + uroven
new_type = 'losing'
elif hod == 0:
new_to_end = 0
new_type = 'drawing'
else:
new_to_end = None
new_type = None
if new_to_end is not None and (AR[simplified_current_fen]['to_end'] != new_to_end or AR[simplified_current_fen]['type'] != new_type):
AR[simplified_current_fen]['to_end'] = new_to_end
AR[simplified_current_fen]['type'] = new_type
changed = True
current_level_positions += 1
level_end_time = time.time()
total_elapsed_time = level_end_time - start_time
level_elapsed_time = level_end_time - level_start_time
print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
print(f"Čas úrovně: {format_time(level_elapsed_time)} / Celkový čas: {format_time(total_elapsed_time)}")
if not changed:
print("Hodnocení ukončeno - žádné další změny.5")
break
print(f"Celkem nalezeno {sum(1 for data in AR.values() if data['to_end'] is not None)} ohodnocených pozic")
print(f"Celkem nalezeno {sum(1 for data in AR.values() if data['to_end'] is None)} neohodnocených pozic")
print("\nVýpočet dokončen.")
# Print optimal moves with parent check
current_fen = start_fen
simplified_current_fen = simplify_fen(current_fen)
optimal_moves = [simplified_current_fen]
while True:
board = CustomBoard(current_fen)
if board.is_checkmate():
print("Mat detekován!4")
break
if board.is_insufficient_material():
print("Nedostatečný materiál detekován!")
break
half_move_clock = current_fen.split()[-2]
if half_move_clock != '-' and int(half_move_clock) >= 100:
print("Remíza pravidlem 50 tahů detekována!")
break
if simplified_current_fen not in AR:
print(f"Pozice {simplified_current_fen} není v AR.")
break
current_value = AR[simplified_current_fen]['to_end']
if current_value == 0:
print("Remíza dosažena!")
break
hod = -2000 if current_value > 0 else 2000
best_fen = None
for move in board.legal_moves:
board.push(move)
POZ2 = board.fen()
simplified_POZ2 = simplify_fen(POZ2)
if simplified_POZ2 in AR and AR[simplified_POZ2]['parent'] == simplified_current_fen:
hod2 = -AR[simplified_POZ2]['to_end']
if current_value > 0: # Silnější hráč
if hod2 > hod:
hod = hod2
best_fen = simplified_POZ2
else: # Slabší hráč
if hod2 < hod:
hod = hod2
best_fen = simplified_POZ2
board.pop()
if best_fen is None:
print("Žádný další tah nebyl nalezen.")
break
optimal_moves.append(best_fen)
current_fen = best_fen
simplified_current_fen = simplify_fen(current_fen)
print("\nOptimální tahy3:")
for fen in optimal_moves:
print_board(fen)
hodnota = AR[simplify_fen(fen)]['to_end']
typ_pozice = AR[simplify_fen(fen)]['type']
print(f"Hodnota: {hodnota}, Typ: {typ_pozice}")
print(fen)
print("\n")
return {fen: (data['to_end'], data['type']) for fen, data in AR.items() if data['to_end'] is not None}
finally:
stop_event.set()
timer_thread.join()
# Helper function to print the board
def print_board(fen):
board = CustomBoard(fen)
print(board)
# Najděte nejmenší kladnou hodnotu to_end ve všech FEN záznamech v AR
def find_min_positive_value(AR):
min_positive_value = float('inf')
min_fen = None
for fen, (value, type_pozice) in AR.items():
if value is not None and value > 0 and value < min_positive_value:
min_positive_value = value
min_fen = fen
if min_positive_value == float('inf'):
print("Žádná kladná hodnota nebyla nalezena.")
else:
print(f"Nejmenší kladná hodnota: {min_positive_value}, FEN: {min_fen}")
# # Main execution
# # Main execution
# if __name__ == "__main__":
# start_fen = "7K/8/k1P5/7p/8/8/8/8 w - - 0 1"
# start_fen = "7K/8/8/8/8/k7/8/7A w - - 0 1"
# # start_fen = "7K/8/8/2a5/8/1k6/8/7A w - - 0 1"
# start_fen = "7K/8/k1P5/7p/8/8/8/8 w - - 0 1"
# start_fen = "6K1/3E4/8/8/8/k7/8/8 w - - 0 1"
# start_fen = "8/5A2/8/8/2K5/8/ka6/8 w - - 0 1"
# start_fen = "8/8/8/2k5/8/8/1K6/3Q4 w - - 0 1"
# start_fen = "8/7k/7r/8/8/RK6/8/8 w - - 0 1"
# AR = calculate_optimal_moves(start_fen)
# find_min_positive_value(AR)
def print_20_successors(AR, start_fen):
print("\nVýpis 20 následníků počáteční pozice:")
simplified_start_fen = simplify_fen(start_fen)
if simplified_start_fen not in AR:
print(f"Počáteční pozice {simplified_start_fen} nebyla nalezena v AR.")
return
count = 0
for fen, (hodnota, typ_pozice) in AR.items():
if count >= 20:
break
print(f"\nFEN: {fen}")
print("Hodnoty:")
print(f" Hodnota: {hodnota}")
print(f" Typ pozice: {typ_pozice}")
print_board(fen)
count += 1
if __name__ == "__main__":
start_fen = "8/8/8/2k5/8/8/1K6/1Q6 w - - 0 1"
start_fen = "8/7k/8/8/8/1K6/8/1Q6 w - - 0 1"
start_fen = "8/7k/8/8/8/1K6/8/1A6 w - - 0 1"
start_fen = "8/7k/8/8/8/1K6/1A6/8 w - - 0 1"
start_fen = "8/8/8/5k2/8/1K6/8/4A3 w - - 0 1"
start_fen = "8/8/8/5k2/8/8/K7/2A5 w - - 0 1"
AR = calculate_optimal_moves(start_fen)
find_min_positive_value(AR)
# Přidáno: Volání nové funkce pro výpis 20 následníků
# print_20_successors(AR, start_fen)
# print("\nVýsledky:")
# for hodnota in range(-996, -1001, -1): # Generuje hodnoty -996, -997, -998, -999, -1000
# for fen, (fen_hodnota, typ_pozice) in AR.items():
# if fen_hodnota == hodnota:
# print(f"FEN: {fen}")
# print(f"Hodnota: {fen_hodnota}")
# print(f"Typ pozice: {typ_pozice}")
# temp_board = CustomBoard(fen)
# if temp_board.is_checkmate():
# print("Stav: Mat")
# elif temp_board.is_stalemate():
# print("Stav: Pat")
# elif temp_board.is_insufficient_material():
# print("Stav: Nedostatečný materiál")
# elif temp_board.is_check():
# print("Stav: Šach")
# else:
# print("Stav: Normální pozice")
# print_board(fen)
# print()
# Print optimal moves
# Print optimal moves
current_fen = start_fen
simplified_current_fen = simplify_fen(current_fen)
simplified_current_fen1 = simplified_current_fen
optimal_moves = [start_fen]
while True:
board = CustomBoard(current_fen)
if board.is_checkmate():
print("Mat detekován!2")
break
# Opravená část
half_move_clock = current_fen.split()[-2]
if board.is_insufficient_material() or (half_move_clock != '-' and int(half_move_clock) >= 100):
if board.is_insufficient_material():
print("Nedostatečný materiál detekován!")
else:
print("Remíza pravidlem 50 tahů detekována!")
AR[simplified_current_fen] = (0, 'drawing') # Aktualizujeme AR pro tuto pozici
break
if simplified_current_fen not in AR:
print(f"Pozice {simplified_current_fen} není v AR.")
break
current_value = AR[simplified_current_fen][0]
if current_value == 0:
print("Remíza dosažena!")
break
hod = -2000 if current_value > 0 else 2000
best_fen = None
for move in board.legal_moves:
board.push(move)
POZ2 = board.fen()
simplified_POZ2 = simplify_fen(POZ2)
if simplified_POZ2 in AR:
hod2 = -AR[simplified_POZ2][0]
if current_value > 0: # Silnější hráč
if hod2 > hod:
hod = hod2
best_fen = simplified_POZ2
else: # Slabší hráč
if hod2 < hod:
hod = hod2
best_fen = simplified_POZ2
board.pop()
if best_fen is None:
print("Žádný další tah nebyl nalezen.")
break
optimal_moves.append(best_fen)
current_fen = best_fen
simplified_current_fen = simplify_fen(current_fen)
print("\nOptimální tahy1:")
for fen in reversed(optimal_moves):
print_board(fen)
hodnota, typ_pozice = AR[simplify_fen(fen)]
print(f"Hodnota: {hodnota}, Typ: {typ_pozice}")
print(fen)
print("\n")The output is here:Output:Mat detekován!2
Optimální tahy1:
........
.......k
.....A..
........
........
........
K.......
........
Hodnota: -1000, Typ: checkmate
8/7k/5A2/8/8/8/K7/8 b - -
........
.......k
........
....A...
........
........
K.......
........
Hodnota: 999, Typ: winning
8/7k/8/4A3/8/8/K7/8 w - -
........
........
......k.
....A...
........
........
K.......
........
Hodnota: -998, Typ: losing
8/8/6k1/4A3/8/8/K7/8 b - -
........
........
......k.
........
........
........
K.......
A.......
Hodnota: 997, Typ: winning
8/8/6k1/8/8/8/K7/A7 w - -
........
........
........
.....k..
........
........
K.......
A.......
Hodnota: -994, Typ: losing
8/8/8/5k2/8/8/K7/A7 b - -
........
........
........
.....k..
........
........
K.......
..A.....
Hodnota: 993, Typ: winning
8/8/8/5k2/8/8/K7/2A5 w - - 0 1The bad thing is that it outputs numbers like -994 and then it jumps to 997.The fix amounts to outputting continuous chain of numbers like -994,995,-996,997,-998,999,-1000.
Once fixed I can offer around 100$.
Larz60+ write Dec-08-2024, 07:14 AM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Done for you this time. Please use bbcode tags on future posts.
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Done for you this time. Please use bbcode tags on future posts.
