Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import chess
- import random
- from itertools import combinations, permutations
- from functools import lru_cache
- from concurrent.futures import ThreadPoolExecutor, as_completed
- import time
- import threading
- # Generování unikátních šachových pozic
- def generate_chess_positions(pieces):
- all_squares = [chess.SQUARES[i] for i in range(64)]
- unique_fens = set()
- for squares in combinations(all_squares, len(pieces)):
- perm = permutations(squares)
- for square_perm in perm:
- board = chess.Board(None)
- board.clear_board()
- for piece, square in zip(pieces, square_perm):
- board.set_piece_at(square, chess.Piece.from_symbol(piece))
- if board.is_valid():
- if random.choice([True, False]):
- board.turn = chess.BLACK # Náhodně nastavíme tah pro černého
- unique_fens.add(board.fen())
- return unique_fens
- # Hodnocení šachovnice
- def evaluate_board(board, depth):
- if board.is_checkmate():
- return 1000 - depth if not board.turn else -1000 + depth
- elif board.is_stalemate() or board.is_insufficient_material():
- return 0
- return 4 # Basic heuristic for non-terminal positions
- # Minimax s LRU cache pro zrychlení
- @lru_cache(maxsize=None)
- def minimax(fen, depth, alpha, beta, maximizing_player, max_depth):
- board = chess.Board(fen)
- if depth == max_depth or board.is_game_over():
- return evaluate_board(board, depth), None # Vrátit tuple s hodnocením a None pro tah
- best_eval = float('-inf') if maximizing_player else float('inf')
- best_move = None
- for move in board.legal_moves:
- board.push(move)
- eval, _ = minimax(board.fen(), depth + 1, alpha, beta, not maximizing_player, max_depth)
- board.pop()
- if maximizing_player:
- if eval > best_eval:
- best_eval = eval
- best_move = move
- alpha = max(alpha, eval)
- if beta <= alpha:
- break
- else:
- if eval < best_eval:
- best_eval = eval
- best_move = move
- beta = min(beta, eval)
- if beta <= alpha:
- break
- return best_eval, best_move # Vrátit tuple s hodnocením a nejlepším tahem
- # Funkce pro paralelní zpracování
- def process_position(fen, max_depth, dot_event):
- evaluation, best_move = minimax(fen, 0, float('-inf'), float('inf'), chess.Board(fen).turn == chess.WHITE, max_depth)
- dot_event.set() # Nastavit událost pro tisk tečky
- return (fen, evaluation, best_move)
- # Funkce pro výpis uplynulého času
- def print_elapsed_time(stop_event):
- start_time = time.time()
- while not stop_event.is_set():
- time.sleep(1)
- elapsed_time = time.time() - start_time
- days, remainder = divmod(elapsed_time, 86400)
- hours, remainder = divmod(remainder, 3600)
- minutes, seconds = divmod(remainder, 60)
- print(f"\rUplynulý čas: {int(days)}d {int(hours):02}h {int(minutes):02}m {int(seconds):02}s", end='', flush=True)
- # Funkce pro tisk teček
- def print_dots(dot_event, stop_event):
- while not stop_event.is_set():
- if dot_event.wait(0.1): # Čekat na nastavení události s timeoutem
- print(".", end='', flush=True)
- dot_event.clear()
- # Hlavní část kódu
- initial_pieces = ['K', 'k', 'Q']
- unique_positions = generate_chess_positions(initial_pieces)
- evaluations = []
- print("Počet unikátních pozic:", len(unique_positions))
- # Nastavení a spuštění vlákna pro výpis času
- stop_event = threading.Event()
- dot_event = threading.Event()
- time_thread = threading.Thread(target=print_elapsed_time, args=(stop_event,))
- dot_thread = threading.Thread(target=print_dots, args=(dot_event, stop_event))
- time_thread.start()
- dot_thread.start()
- # Paralelní zpracování pozic
- max_depth = 19 # Limit depth for demonstration purposes
- batch_size = 100 # Zpracovat menší dávky paralelně
- with ThreadPoolExecutor(max_workers=16) as executor:
- for i in range(0, len(unique_positions), batch_size):
- batch_positions = list(unique_positions)[i:i + batch_size]
- futures = [executor.submit(process_position, fen, max_depth, dot_event) for fen in batch_positions]
- for future in as_completed(futures):
- fen, evaluation, best_move = future.result()
- evaluations.append((fen, evaluation, best_move))
- dot_event.set() # Nastavit událost pro tisk tečky po dokončení úlohy
- # Zastavení vlákna pro výpis času a teček
- stop_event.set()
- time_thread.join()
- dot_thread.join()
- # Print results
- print()
- for position, eval, move in evaluations:
- if eval != 0 and eval != 4 and eval < 983:
- turn = "White" if chess.Board(position).turn == chess.WHITE else "Black"
- print(f"FEN: {position}, Turn: {turn}, Best Move: {move}, Evaluation: {eval}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement