TranspositionTable class is a specialized hash table that caches position evaluations to dramatically speed up the solver. In Connect 4, the same position can be reached through different move sequences (called a “transposition”), and this table allows the solver to skip re-evaluating positions it has already seen.
Overview
What is a Transposition?
A transposition occurs when different move sequences lead to the same board position:How it Works
- Unique Position Key: Each position has a unique 64-bit key generated by
Position::key() - Hash Index: The key is mapped to a table index using modulo:
index = key % table_size - Storage: Each entry stores the position key and its evaluated score
- Collision Handling: Newer entries overwrite older ones at the same index (replacement strategy)
Memory Usage
The default table size is 8,388,608 entries (2^23), which uses approximately 64 MB of memory:- Each entry: 16 bytes (8-byte key + 8-byte value with padding)
- Total: 8,388,608 × 16 bytes ≈ 134 MB
Entry Structure
Unique position identifier. A value of 0 indicates an empty entry.
The evaluated score for this position (-128 to 127).
Constructor
Number of entries in the table. Should ideally be a power of 2 for optimal performance. Default is 2^23 = 8,388,608 entries.
- Default (8M entries): ~64 MB
- 16M entries: ~128 MB
- 4M entries: ~32 MB
Public Methods
put()
Unique position key from
Position::key()The evaluated score to store (typically from negamax search)
get()
Unique position key from
Position::key()int8_t - The stored score, or 0 if not found
Important: A return value of 0 could mean either:
- The position was never stored
- The position was stored with a score of
0(draw) - The entry was overwritten by a collision
reset()
0 and all values to 0.
Use cases:
- Starting a new game
- Running benchmarks
- Freeing memory for other uses
Usage in Solver
TheSolver class uses a TranspositionTable internally. Here’s a conceptual example of how it’s used during negamax search:
Performance Impact
The transposition table provides dramatic speedups:- Without TT: May evaluate millions of duplicate positions
- With TT: Each unique position evaluated at most once
- Speedup: Often 10x-100x faster depending on the position
Implementation Details
Hash Function
- Simple and predictable
- Sufficient for Connect 4 (positions are well-distributed)
- Easy to understand and debug
Collision Strategy
When two different positions hash to the same index (a collision), the newer entry overwrites the older one. This is called a “replacement strategy.” Tradeoffs:- Simple to implement
- Always stores the most recent evaluation
- May occasionally discard useful data
- In practice, the table is large enough that this rarely matters
Memory Optimization
The table usesint8_t (1 byte) for scores instead of int (4 bytes) to save memory:
- Range: -128 to +127
- Sufficient for Connect 4 (max score is ±22, since max moves is 42)
- 4x memory savings compared to using
int
Best Practices
- Size Selection: Use a power of 2 for the table size (better performance on some systems)
- Memory Budget: Default 64 MB is usually fine; increase if you have RAM to spare
- Reset Between Games: Call
reset()when starting a new independent search - Don’t Reset During Search: Keep the table intact during a single game analysis