Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import chess
- import time
- from itertools import permutations, combinations
- from functools import lru_cache
- class CustomPiece(chess.Piece):
- def __init__(self, piece_type, color):
- super().__init__(piece_type, color)
- class Amazon(CustomPiece):
- def __init__(self, color):
- super().__init__(chess.QUEEN, color)
- def symbol(self):
- return 'A' if self.color == chess.WHITE else 'a'
- class Bob(CustomPiece):
- def __init__(self, color):
- super().__init__(chess.ROOK, color)
- def symbol(self):
- return 'B' if self.color == chess.WHITE else 'b'
- class Cyryl(CustomPiece):
- def __init__(self, color):
- super().__init__(chess.QUEEN, color)
- def symbol(self):
- return 'C' if self.color == chess.WHITE else 'c'
- class CustomBoard(chess.Board):
- def __init__(self, fen=None):
- self.custom_pieces = {
- 'A': Amazon(chess.WHITE), 'a': Amazon(chess.BLACK),
- 'B': Bob(chess.WHITE), 'b': Bob(chess.BLACK),
- 'C': Cyryl(chess.WHITE), 'c': Cyryl(chess.BLACK)
- }
- super().__init__(fen)
- def set_fen(self, fen):
- parts = fen.split(' ')
- while len(parts) < 6:
- parts.append("0")
- board_part = parts[0]
- turn_part = parts[1]
- castling_part = parts[2]
- en_passant_part = parts[3]
- halfmove_clock = parts[4]
- fullmove_number = parts[5]
- self.set_board_fen(board_part)
- self.turn = chess.WHITE if turn_part == 'w' else chess.BLACK
- self.castling_rights = chess.BB_EMPTY if castling_part == '-' else chess.SquareSet.from_square(chess.parse_square(castling_part))
- self.ep_square = None if en_passant_part == '-' else chess.parse_square(en_passant_part)
- self.halfmove_clock = int(halfmove_clock)
- self.fullmove_number = int(fullmove_number)
- def set_board_fen(self, fen):
- self.clear()
- rows = fen.split('/')
- for rank, row in enumerate(rows):
- file = 0
- for char in row:
- if char.isdigit():
- file += int(char)
- else:
- square = chess.square(file, 7 - rank)
- if char in self.custom_pieces:
- self.set_piece_at(square, self.custom_pieces[char])
- else:
- self.set_piece_at(square, chess.Piece.from_symbol(char))
- file += 1
- def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
- for move in super().generate_legal_moves(from_mask, to_mask):
- yield move
- for square in self.piece_map():
- piece = self.piece_at(square)
- if piece.symbol().lower() in ['a', 'b', 'c']:
- yield from self.generate_custom_piece_moves(square, piece)
- def generate_custom_piece_moves(self, square, piece):
- knight_moves = [
- (2, 1), (2, -1), (-2, 1), (-2, -1),
- (1, 2), (1, -2), (-1, 2), (-1, -2)
- ]
- directions = []
- if piece.symbol().lower() == 'a': # Amazon: Bishop + Knight moves
- directions = [
- chess.BB_DIAG_A1H8, chess.BB_DIAG_A8H1
- ]
- elif piece.symbol().lower() == 'b': # Bob: Rook + Knight moves
- directions = [
- chess.BB_RANK_1, chess.BB_FILE_A
- ]
- elif piece.symbol().lower() == 'c': # Cyryl: Queen + Knight moves
- directions = [
- chess.BB_DIAG_A1H8, chess.BB_DIAG_A8H1, chess.BB_RANK_1, chess.BB_FILE_A
- ]
- for direction in directions:
- for dest_square in chess.SquareSet(direction):
- move = chess.Move(square, dest_square)
- if self.is_pseudo_legal(move):
- yield move
- # Handle knight moves
- for dx, dy in knight_moves:
- dest_square = chess.square(chess.square_file(square) + dx, chess.square_rank(square) + dy)
- if 0 <= chess.square_file(dest_square) < 8 and 0 <= chess.square_rank(dest_square) < 8:
- move = chess.Move(square, dest_square)
- if self.is_pseudo_legal(move):
- yield move
- @lru_cache(maxsize=None)
- def simplify_fen_string(fen):
- parts = fen.split(' ')
- simplified_fen = ' '.join(parts[:4]) # Zachováváme pouze informace o pozici
- if len(parts) < 6:
- simplified_fen += " 0 1"
- return simplified_fen
- def print_board(fen):
- board = CustomBoard(fen)
- print(board)
- # Startovní pozice
- start_fen = "8/6A1/8/8/8/k1K5/8/8 w - - 0 1"
- simplified_POZ2 = simplify_fen_string(start_fen)
- POZ = {1: simplified_POZ2}
- AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': 0}}
- N = 1
- M = 0
- start_time = time.time()
- def format_elapsed_time(elapsed_time):
- hours, remainder = divmod(elapsed_time, 3600)
- minutes, seconds = divmod(remainder, 60)
- return f"{int(hours)}h {int(minutes)}m {int(seconds)}s"
- def print_elapsed_time(total_time, level_time):
- print(f"{format_elapsed_time(total_time)} / {format_elapsed_time(level_time)}")
- while M < N:
- M += 1
- current_fen = POZ[M]
- board = CustomBoard(current_fen)
- simplified_current_fen = simplify_fen_string(current_fen)
- if simplified_current_fen not in AR:
- AR[simplified_current_fen] = {'used': 0, 'to_end': 0}
- if AR[simplified_current_fen]['used'] == 0:
- AR[simplified_current_fen]['used'] = 1
- for move in board.legal_moves:
- # Check if the move is a promotion
- if board.is_pseudo_legal(move) and move.promotion:
- move.promotion = chess.QUEEN # Set promotion to queen only
- board.push(move)
- POZ2 = board.fen()
- simplified_POZ2 = simplify_fen_string(POZ2)
- if simplified_POZ2 not in AR:
- AR[simplified_POZ2] = {'used': None, 'to_end': 0}
- if AR[simplified_POZ2]['used'] is None:
- N += 1
- POZ[N] = simplified_POZ2
- AR[simplified_POZ2] = {'used': 0, 'to_end': 0}
- board.pop() # Vrátíme tah zpět
- print(f"Počet pozic je {N}")
- # Přidání kontroly pro mat, remízu a výchozí hodnotu
- F = 0
- for i in range(1, N + 1):
- current_fen = POZ[i]
- board = CustomBoard(current_fen)
- simplified_current_fen = simplify_fen_string(current_fen)
- if simplified_current_fen not in AR:
- AR[simplified_current_fen] = {'used': 0, 'to_end': 0}
- if board.is_checkmate():
- AR[simplified_current_fen]['to_end'] = -1000
- F += 1
- elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves() or board.is_fivefold_repetition():
- AR[simplified_current_fen]['to_end'] = 0
- else:
- AR[simplified_current_fen]['to_end'] = 0
- print(f"Počet pozic v matu je {F}")
- uroven = 0
- while F > 0:
- uroven += 1
- level_start_time = time.time()
- print(f"Výpočet v úrovni {uroven}")
- F = 0
- current_level_positions = 0
- for i in range(1, N + 1):
- current_fen = POZ[i]
- board = CustomBoard(current_fen)
- simplified_current_fen = simplify_fen_string(current_fen)
- if AR[simplified_current_fen]['to_end'] == 0:
- hod = -2000
- for move in board.legal_moves:
- # Check if the move is a promotion
- if board.is_pseudo_legal(move) and move.promotion:
- move.promotion = chess.QUEEN # Set promotion to queen only
- board.push(move)
- POZ2 = board.fen()
- simplified_POZ2 = simplify_fen_string(POZ2)
- if simplified_POZ2 not in AR or AR[simplified_POZ2]['to_end'] is None:
- hod2 = 0
- else:
- hod2 = -AR[simplified_POZ2]['to_end']
- if hod2 > hod:
- hod = hod2
- board.pop() # Vrátíme tah zpět
- if hod == 1001 - uroven:
- AR[simplified_current_fen]['to_end'] = 1000 - uroven
- F += 1
- current_level_positions += 1
- if hod == -1001 + uroven:
- AR[simplified_current_fen]['to_end'] = -1000 + uroven
- F += 1
- 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_elapsed_time(total_elapsed_time, level_elapsed_time)
- print(f"Nalezeno {F} pozic celkem")
- # Výpis všech pozic s to_end == 17
- print("Pozice s to_end == 17:")
- for fen, data in AR.items():
- if data['to_end'] is not None and data['to_end'] < 983 and data['to_end'] > 0:
- print(f"{fen} -> to_end: {data['to_end']}")
- print("*****")
- print("Pozice s to_end == -20:")
- for fen, data in AR.items():
- if data['to_end'] is not None and data['to_end'] > -981 and data['to_end'] < 0:
- print(f"{fen} -> to_end: {data['to_end']}")
- current_fen = POZ[1]
- board = CustomBoard(current_fen)
- simplified_current_fen = simplify_fen_string(current_fen)
- hod = AR[simplified_current_fen]['to_end']
- print(f"Hodnocení počáteční pozice je {hod}")
- # Závěrečný kód pro procházení nejlepších tahů
- current_fen = start_fen
- simplified_current_fen = simplify_fen_string(current_fen)
- optimal_moves = []
- while AR[simplified_current_fen]['to_end'] is not None and AR[simplified_current_fen]['to_end'] > -1000:
- board = CustomBoard(current_fen)
- simplified_current_fen = simplify_fen_string(current_fen)
- hod = -2000
- for move in board.legal_moves:
- # Check if the move is a promotion
- if board.is_pseudo_legal(move) and move.promotion:
- move.promotion = chess.QUEEN # Set promotion to queen only
- board.push(move)
- POZ2 = board.fen()
- simplified_POZ2 = simplify_fen_string(POZ2)
- if simplified_POZ2 not in AR or AR[simplified_POZ2]['to_end'] is None:
- hod2 = 0
- else:
- hod2 = -AR[simplified_POZ2]['to_end']
- if hod2 > hod:
- hod = hod2
- best_fen = simplified_POZ2
- board.pop() # Vrátíme tah zpět
- optimal_moves.append(best_fen)
- current_fen = best_fen
- simplified_current_fen = simplify_fen_string(current_fen)
- # Tisk šachovnic v opačném pořadí
- for fen in reversed(optimal_moves):
- print_board(fen)
- print("\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement