Monday, June 22, 2026

MODIFICATION - Import chess games, catalog them, list from first variation move and by frequency. / Chess and Music brainstorming

Check previous post for Chess and Music brainstorming, https://1a2b3c4d5e6f7g8h9i10j11k12l13m14n.blogspot.com/2026/06/import-chess-games-catalog-them-list.html """ chessopenings2.py Interactive Opening Catalog + Continuation Analyzer - Loads existing opening catalog (JSON) - Processes ONE PGN at a time - Extracts continuations (moves AFTER opening) - Displays full interactive catalog in PyCharm - Allows manual reordering like chessopenings1.py Requires: pip install python-chess """ import chess.pgn import os import json JSON_FILE = "personal_openings.json" OPENING_SKIP_PLIES = 6 # skip first ~3 full moves MAX_PLIES = 30 # up to 15 full moves # ---------------------------- # LOAD / SAVE # ---------------------------- def load_data(): if os.path.exists(JSON_FILE): with open(JSON_FILE, "r", encoding="utf-8") as f: return json.load(f) return {} def save_data(data): with open(JSON_FILE, "w", encoding="utf-8") as f: json.dump(data, f, indent=4) # ---------------------------- # FORMAT CONTINUATIONS (MOVE NUMBERED) # ---------------------------- def format_continuation(san_moves, start_ply): lines = [] i = 0 ply = start_ply while i < len(san_moves) and ply < MAX_PLIES: move_number = (ply // 2) + 1 white = san_moves[i] i += 1 ply += 1 line = f"{move_number}. {white}" if i < len(san_moves) and ply < MAX_PLIES: black = san_moves[i] i += 1 ply += 1 line += f" {black}" lines.append(line) return lines # ---------------------------- # PROCESS PGN # ---------------------------- def process_pgn(filename, data): game_count = 0 with open(filename, "r", encoding="utf-8", errors="ignore") as pgn: while True: game = chess.pgn.read_game(pgn) if game is None: break game_count += 1 eco = game.headers.get("ECO", "").strip() opening = game.headers.get("Opening", "").strip() variation = game.headers.get("Variation", "").strip() white_elo = game.headers.get("WhiteElo", "") black_elo = game.headers.get("BlackElo", "") try: white_elo = int(white_elo) black_elo = int(black_elo) except ValueError: continue if white_elo < 2100 and black_elo < 2100: continue if not opening: opening = "Unknown Opening" key = f"{eco} | {opening}" if variation: key += f" | {variation}" board = game.board() san_moves = [] for move in game.mainline_moves(): san_moves.append(board.san(move)) board.push(move) continuation_moves = san_moves[ OPENING_SKIP_PLIES:OPENING_SKIP_PLIES + MAX_PLIES ] start_ply = OPENING_SKIP_PLIES continuation_lines = format_continuation( continuation_moves, start_ply ) continuation_str = " | ".join(continuation_lines) if key not in data: data[key] = {} if continuation_str not in data[key]: data[key][continuation_str] = 1 else: data[key][continuation_str] += 1 print("\nGames processed:", game_count) # ---------------------------- # DISPLAY # ---------------------------- def display(data): print("\nOPENING CATALOG (WITH CONTINUATIONS)") print("=" * 100) items = sorted( data.items(), key=lambda item: sum(item[1].values()), reverse=True ) for i, (key, variations) in enumerate(items, start=1): print(f"\n{i:3} {key}") if not variations: print(" (no continuation data yet)") continue sorted_variations = sorted( variations.items(), key=lambda x: x[1], reverse=True ) for j, (cont, freq) in enumerate(sorted_variations[:5], start=1): print(f"\n [{j}] freq={freq}") print(f" {cont}") print("-" * 100) # ---------------------------- # REORDER SYSTEM # ---------------------------- def reorder(data): items = list(data.items()) while True: display(dict(items)) print("\nCommands:") print(" X=Y move item X to position Y") print(" s save") print(" q quit") cmd = input("\nCommand: ").strip().lower() if cmd == "s": save_data(dict(items)) print("\nSaved.") continue if cmd == "q": return dict(items) if "=" in cmd: try: a, b = cmd.split("=") a = int(a) - 1 b = int(b) - 1 item = items.pop(a) items.insert(b, item) except: print("Invalid command") # ---------------------------- # MAIN # ---------------------------- def main(): data = load_data() print("\nChessOpenings2 - Interactive Continuation System") print("------------------------------------------------") filename = input("\nPGN filename (WITHOUT .pgn): ").strip() if not filename: return filename = filename + ".pgn" if not os.path.exists(filename): print("File not found:", filename) return process_pgn(filename, data) data = reorder(data) save_data(data) print("\nDone.") if __name__ == "__main__": main()

No comments:

Post a Comment