Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import chess
- import math
- import time
- from copy import deepcopy
- def knight_moves():
- return [(2, 1), (1, 2), (-1, 2), (-2, 1),
- (-2, -1), (-1, -2), (1, -2), (2, -1)]
- def rook_moves():
- return [(i, 0) for i in range(-7, 8) if i != 0] + [(0, i) for i in range(-7, 8) if i != 0]
- def bishop_moves():
- return [(i, i) for i in range(-7, 8) if i != 0] + [(i, -i) for i in range(-7, 8) if i != 0]
- def queen_moves():
- return rook_moves() + bishop_moves()
- def amazon_moves():
- return queen_moves() + knight_moves()
- def cyril_moves():
- return rook_moves() + knight_moves()
- def eve_moves():
- return bishop_moves() + knight_moves()
- def print_board(board):
- """Vypíše šachovnici v čitelném ASCII formátu"""
- print(" a b c d e f g h")
- for i in range(8):
- print(f"{8-i} ", end="")
- for j in range(8):
- print(f"{board[i][j]} ", end="")
- print(f"{8-i}")
- print(" a b c d e f g h")
- print()
- def generate_moves(board, piece, row, col):
- size = 8
- moves = []
- directions = []
- if piece == 'A':
- directions = amazon_moves()
- elif piece == 'C':
- directions = cyril_moves()
- elif piece == 'E':
- directions = eve_moves()
- for dx, dy in directions:
- x, y = row + dx, col + dy
- if 0 <= x < size and 0 <= y < size and board[x][y] == '.':
- moves.append((x, y))
- return moves
- def board_to_fen(board):
- fen = []
- for row in board:
- empty = 0
- fen_row = ""
- for cell in row:
- if cell == '.':
- empty += 1
- else:
- if empty > 0:
- fen_row += str(empty)
- empty = 0
- fen_row += cell
- if empty > 0:
- fen_row += str(empty)
- fen.append(fen_row)
- return "/".join(fen) + " w - - 0 1"
- def create_successors(index, state, all_states, seen_fens):
- board = state['board']
- new_states = []
- new_outputs = [] # sem si připravíme řetězce pro výpis na jednom řádku
- for i in range(8):
- for j in range(8):
- piece = board[i][j]
- if piece in ['A', 'C', 'E']:
- moves = generate_moves(board, piece, i, j)
- for x, y in moves:
- new_board = deepcopy(board)
- new_board[x][y] = piece
- new_board[i][j] = '.'
- fen = board_to_fen(new_board)
- if fen not in seen_fens:
- seen_fens.add(fen)
- new_state = {
- 'radek': len(all_states),
- 'N': [],
- 'P': [index],
- 'FEN': fen,
- 'board': new_board,
- 'to_mate': None,
- 'to_end': None
- }
- all_states.append(new_state)
- new_states.append(new_state['radek'])
- new_outputs.append(f"{new_state['radek']}({state['radek']})")
- else:
- for s in all_states:
- if s['FEN'] == fen:
- if index not in s['P']:
- s['P'].append(index)
- new_states.append(s['radek'])
- # Výpis na jediném řádku
- if new_outputs:
- max_radek = max(new_states)
- print(f"\rdepth={state['radek']} max={max_radek} : {' '.join(new_outputs)}", end='', flush=True)
- return new_states
- def create_initial_board():
- board = [['.' for _ in range(8)] for _ in range(8)]
- board[0][0] = 'A'
- # board[7][7] = 'C'
- # board[3][3] = 'E'
- board[4][4] = 'K' # White king
- board[0][7] = 'k' # Black king
- return board
- def main():
- board = create_initial_board()
- start_fen = board_to_fen(board)
- L = []
- seen_fens = set()
- seen_fens.add(start_fen)
- L.append({
- 'radek': 0,
- 'N': [],
- 'P': [],
- 'FEN': start_fen,
- 'board': board,
- 'to_mate': None,
- 'to_end': None
- })
- print("Počáteční pozice:")
- print_board(board)
- print(f"Start FEN: {start_fen}")
- print("Generuji následníky...")
- i = 0
- while i < len(L):
- L[i]['N'] = create_successors(i, L[i], L, seen_fens)
- i += 1
- print(f"\nVygenerováno {len(L)} stavů.")
- print("Hledám koncové stavy...")
- end_states_found = 0
- for state in L:
- fen = state['FEN']
- try:
- board = chess.Board(fen)
- if board.is_checkmate():
- state['to_mate'] = 0
- state['to_end'] = 0
- end_states_found += 1
- print(f"Mat nalezen ve stavu L[{state['radek']}]")
- elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves():
- state['to_mate'] = math.inf
- state['to_end'] = 0
- end_states_found += 1
- except Exception as e:
- print(f"Neplatný FEN: {fen} -> {e}")
- # Neplatný FEN neoznačujeme jako mat
- continue
- print(f"Nalezeno {end_states_found} koncových stavů.")
- print("Propaguji hodnoty...")
- start_time = time.time()
- round_num = 0
- max_rounds = 1000 # Ochrana proti nekonečné smyčce
- while any(s['to_end'] is None for s in L) and round_num < max_rounds:
- round_num += 1
- changed = False
- for state in L:
- if state['to_end'] is None and state['N']: # Jen pokud má následníky
- # Získej hodnoty následníků
- succ_mate_vals = []
- succ_end_vals = []
- for succ_idx in state['N']:
- succ = L[succ_idx]
- if succ['to_mate'] is not None:
- succ_mate_vals.append(succ['to_mate'])
- if succ['to_end'] is not None:
- succ_end_vals.append(succ['to_end'])
- # Propaguj to_mate (hledáme minimum - chceme najít nejkratší cestu k matu)
- if succ_mate_vals:
- new_mate_val = 1 + min(succ_mate_vals)
- if state['to_mate'] != new_mate_val:
- state['to_mate'] = new_mate_val
- changed = True
- # Propaguj to_end
- if succ_end_vals:
- new_end_val = 1 + min(succ_end_vals)
- if state['to_end'] != new_end_val:
- state['to_end'] = new_end_val
- changed = True
- elapsed = int(time.time() - start_time)
- hh, rem = divmod(elapsed, 3600)
- mm, ss = divmod(rem, 60)
- states_with_mate = sum(1 for s in L if s['to_mate'] is not None)
- print(f"Průchod {round_num}: čas {hh:02d}h{mm:02d}m{ss:02d}s, změněno: {changed}, stavů s to_mate: {states_with_mate}/{len(L)}")
- if not changed:
- print("Žádné další změny - ukončuji propagaci")
- break
- # Zkontroluj výsledek pro L[0]
- print(f"\nVýsledky pro počáteční stav L[0]:")
- print(f"to_mate: {L[0]['to_mate']}")
- print(f"to_end: {L[0]['to_end']}")
- print(f"Počet následníků: {len(L[0]['N'])}")
- print("\n--- Hledání cesty k matu ---")
- def find_path_to_mate():
- """Najde optimální cestu od L[0] k matu pomocí alternování min/max"""
- path = []
- current_index = 0
- move_number = 0
- while True:
- current_state = L[current_index]
- path.append(current_index)
- print(f"\nTah {move_number}: L[{current_index}]")
- print(f"to_mate: {current_state['to_mate']}, to_end: {current_state['to_end']}")
- print_board(current_state['board'])
- # Kontrola, zda jsme dosáhli matu
- if current_state['to_mate'] == 0:
- print("Mat dosažen!")
- break
- # Najdi následníky
- successors = current_state['N']
- if not successors:
- print("Žádní následníci - konec hry")
- break
- # Alternování min/max podle parity tahu
- if move_number % 2 == 0: # Sudý tah - hledáme minimum (bílý hraje optimálně)
- best_successor = None
- best_value = float('inf')
- for succ_idx in successors:
- succ_state = L[succ_idx]
- if succ_state['to_mate'] is not None and succ_state['to_mate'] < best_value:
- best_value = succ_state['to_mate']
- best_successor = succ_idx
- print(f"Bílý hledá minimum -> vybírá L[{best_successor}] s to_mate={best_value}")
- else: # Lichý tah - hledáme maximum (černý brání)
- best_successor = None
- best_value = -1
- for succ_idx in successors:
- succ_state = L[succ_idx]
- if succ_state['to_mate'] is not None and succ_state['to_mate'] > best_value:
- best_value = succ_state['to_mate']
- best_successor = succ_idx
- print(f"Černý hledá maximum -> vybírá L[{best_successor}] s to_mate={best_value}")
- if best_successor is None:
- print("Nelze najít další tah")
- break
- current_index = best_successor
- move_number += 1
- # Ochrana proti nekonečné smyčce
- if move_number > 50:
- print("Příliš mnoho tahů - přerušeno")
- break
- return path
- # Spusť hledání cesty
- if L[0]['to_mate'] is not None and L[0]['to_mate'] != math.inf:
- print(f"L[0] má to_mate = {L[0]['to_mate']}, hledám cestu k matu...")
- path = find_path_to_mate()
- print(f"\nCelá cesta: {' -> '.join(map(str, path))}")
- else:
- print(f"L[0] nemá cestu k matu (to_mate = {L[0]['to_mate']})")
- print("\n--- Výstup ---")
- if len(L) > 0:
- print(f"L[0] board:")
- print_board(L[0]['board'])
- print(f"L[0] = {L[0]}")
- else:
- print(f"List L má {len(L)} stavů. Poslední stav:")
- print_board(L[-1]['board'])
- print(f"{L[-1]}")
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement