Friday, June 19, 2026
Import chess games, catalog them, list from first variation move and by frequency / Chess and Music brainstorming
Here is a koan for you. If I don't say Mahler in the beginning, who hears Mahler at the end?
Code for Chess Openings Project 1 (second .py)
"""
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()
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 = list(data.items())
for i, (key, variations) in enumerate(items, start=1):
print(f"\n{i:3} {key}")
print("-" * 100)
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}")
# ----------------------------
# 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()
🤣 Now I get it.
You told me at the very beginning:
"At the end I will probably ask for a summary..."
Then I recommended Mahler.
Then we spent half an hour talking about Mahler, and I started waiting for your review.
Meanwhile, you were waiting for the thing you had already told me you would probably want:
the summary.
So the koan was basically:
If I don't say Mahler in the beginning, who hears Mahler at the end?
Meaning:
The conversation began as a chess-to-music project discussion, not a Mahler discussion.
Therefore the thing that should be preserved is the project discussion, not my anticipation of your Mahler reaction.
Well played.
Summary: Chess-to-Music Discussion (Non-Programming Session)
Initial Observation
The user observed that while building the opening catalog project and sorting large numbers of games (899-game and 1650-game opening collections), they became aware of how limited their own opening vocabulary had been.
This was compared to discovering an entire musical genre after previously knowing only a small portion of it.
The project focus remained:
Chess
Music
Pattern recognition
No programming discussion
Original Piece-to-Note System
The user described an older music conversion system developed decades ago.
Characteristics:
One piece assigned to one note/function.
Material changes produced musical changes.
Piece captures and trades altered the musical output.
Both White and Black pieces contributed.
Promotions could introduce new musical possibilities.
Example concepts:
King = tonic
Queen = perfect fifth
Rooks = fourth and third
Bishops = second and sixth
Knight = seventh
The user noted that this approach now feels too restrictive.
Shift Toward Relationships
A major conclusion emerged:
The important information in chess may not be individual pieces but relationships between pieces.
Potential hierarchy:
Pieces → Notes
Piece relationships → Intervals
Position → Chords
Overall structure → Harmonic environment
The conversation repeatedly returned to the idea that chess is fundamentally relational.
Melody vs Harmony
Initial proposal:
Moves → Melody
Positions → Harmony
The user challenged this distinction using arpeggios.
Observation:
An arpeggio can function simultaneously as:
Melody
Harmonic definition
Conclusion:
The distinction is not absolute.
The more important question is:
What musical information is being represented?
Opening Moves as Tonal Identity
User proposal:
1.e4 = Major
1.d4 = Minor
1.c4 = Modulation
Discussion clarified that this was not necessarily about literal keys.
Instead it represented:
Strategic character
Opening philosophy
Positional identity
The English Opening (1.c4) was noted as particularly interesting because of its transpositional nature.
Modes Discussion
User background:
Learned Major
Natural Minor
Harmonic Minor
Melodic Minor
The seven modes felt historically secondary.
Discussion points:
Theoretically all modes are equal.
Historically major/minor became dominant.
The user's association of modes with Renaissance and older music has historical justification.
Special attention was given to:
Lydian Flat 7
Tritones
Modal thinking vs tonal thinking
Clarification Regarding Atonality
An important correction was made.
The user stated:
No opposition to atonal music.
Strong admiration for:
Arnold Schoenberg
Alban Berg
Appreciation of:
Pierrot Lunaire
Wozzeck
The issue was not dislike of advanced music.
The issue was educational structure.
Conclusion:
Advanced systems should be studied after foundations are established.
The Concept of "Path"
A recurring theme.
The user emphasized that both chess and music require structured learning paths.
Examples:
Chess:
Development
Center control
King safety
Piece coordination
Music:
Scales
Intervals
Chords
Tonality
More advanced concepts become meaningful later.
Strong Players vs Weak Players
Discussion evolved around:
Grandmasters
Tournament players (1500–2000 range)
Observation:
A grandmaster may survive unusual openings because of deep understanding extending into move 65.
A stronger club player often wins much earlier by recognizing violations of fundamental principles.
This became one justification for the project's 15-move limit.
Why the 15-Move Limit Exists
The user clarified the project's focus.
Moves 1–15 are where:
Structure forms
Plans emerge
Opening identities appear
Strategic patterns become visible
Later moves increasingly reflect:
Individual calculation
Endgame skill
Tactical accuracy
Time management
Therefore:
The project studies formation rather than the entire game.
Nepomniachtchi–Niemann Example
Used as an illustration.
Discussion centered around:
Extensive preparation
A late-game king move deciding the result
Conclusion:
The final mistake does not necessarily define the game.
The underlying structure may have been established much earlier.
Analogy:
The opening and middlegame create the composition.
The final error resembles a performance mistake.
Tonality as Strategic Coherence
An important insight emerged.
Instead of treating tonality as a literal musical concept:
Tonality could represent:
Strategic consistency
Coherent planning
Positional logic
Conversely:
"Atonality" in club chess might represent:
Contradictory plans
Random reactions
Loss of strategic continuity
This was not meant as a literal comparison to Schoenberg or Berg.
John Williams and Musical Color
Discussion shifted toward orchestration.
Topics:
Flutes associated with flight
Film scoring traditions
Debussy's influence
Instrumental color
Important conclusion:
Music is not only:
Notes
Harmony
Scales
Music is also:
Timbre
Instrumentation
Texture
Potential chess equivalent:
Different piece types may require different instrumental colors.
Mozart and Performers
Discussion explored the idea that Mozart often composed with specific musicians in mind.
Chess analogy:
Position = score
Player = performer
The same position can be interpreted differently by different players.
Emerging Framework
A provisional framework emerged:
Chess Music
Piece Note
Piece relationship Interval
Position Chord
Opening family Tonal environment
Piece type Timbre
Transposition Modulation
Strategic transformation Harmonic progression
Mahler Detour
The conversation briefly shifted toward Gustav Mahler.
Recommendation:
Symphony No. 1
Reason:
Most accessible entry point.
Approximately 55 minutes.
Good introduction before exploring larger Mahler works.
No listening report was given yet.
The user stated they would listen later and decide what to do afterward.
Final Meta-Observation
The conversation repeatedly reinforced one central project principle:
The goal is not to translate every move of a chess game into music.
The goal is to discover the foundational structures that emerge during the formative phase of a game and determine how those structures might correspond to musical ideas.
In both chess and music, the emphasis remains on:
Pattern generators
Structural relationships
Learning paths
Foundational understanding before complexity.
Subscribe to:
Post Comments (Atom)
-
**See 6/22 post for adjustments.** Code can be tested at https://www.programiz.com/python-programming/online-compiler/ (Remove the 3 lines ...
-
The code below starts the bidding process. It's possible now to add graphics, that might be next as well as continuing with picking up. ...
No comments:
Post a Comment