How utkarsh-naman/3t works
1. Repository shape
- This repo is centered on a tic-tac-toe engine called 3T, with the main implementation in Go.
- It also contains two packaging/porting tracks:
- a Go WebAssembly build under WASM/
- a Rust implementation under Rust/ and WASM Rust/
- The overall architecture is the same across these tracks: build a compact game graph offline, then run a small engine against that graph at runtime.
2. Core runtime engine
- The runtime engine lives in src/TTTEngine/.
- Its responsibility is to take a board state, look it up in the precomputed game graph, and determine outcomes / next choices.
- The engine is intentionally lightweight because most expensive reasoning is pushed into offline map construction.
3. Game-state model layer
- src/model/ defines the data structures for the game graph and node/state representation.
- This is the shared boundary between the builder and the engine: the builder produces graph data in this model, and the engine consumes it.
- In the Rust port, the same role is played by Rust/src/model/ and the mirrored WASM Rust files.
4. Offline map-building pipeline
- src/mapBuilder/ is the graph generation pipeline.
- It appears to run in stages:
- build an empty map / initial structure
- assign terminal values
- propagate or finalize values for non-terminal states
- The build steps are also called out directly in the README, which suggests graph generation is a required preprocessing step before using the engine.
5. Symmetry reduction as a major optimization
- src/SymmetryReduction/ is a key architectural subsystem.
- It reduces equivalent tic-tac-toe positions under board symmetries, so the engine stores and evaluates fewer distinct states.
- This is one of the main reasons the engine is “resource optimized”: many board states collapse to a canonical representative before being stored or queried.
6. State transition utilities
- src/utils/nextstates.go and src/utils/prevstates.go provide transition logic around the graph.
- These utilities likely generate successor states from a move and reconstruct predecessor relationships for building or verification.
- They sit between raw board logic and the graph builder / engine logic.
7. Constants and win logic
- src/Constants/ contains the hard-coded domain tables:
- win masks
- symmetry tables
- value encodings
- These are foundational to both the builder and the runtime engine, since tic-tac-toe evaluation depends on detecting wins and mapping symmetric positions consistently.
8. Precomputed artifacts and graph outputs
- The repository includes generated .ttt files under bin/graph/... and Rust/bin/output/....
- These are the serialized game graphs/maps used by the engine rather than recomputed on every run.
- The presence of valued vs. unvalued outputs suggests the build pipeline can produce intermediate and finalized versions of the graph.
9. Root Go application entrypoint
- The root main.go ties the Go implementation together for local execution.
- src/lib.go and the package layout imply the root code can be used both as a library and as an executable.
- The repo also includes index.html and browser assets, indicating the engine can be exercised visually or via wasm in a browser context.
10. WebAssembly browser runtime
- WASM/ is a separate Go module compiled to WebAssembly.
- It packages the engine for browser execution using main.wasm plus wasm_exec.js and an HTML host page.
- This is a runtime delivery layer, not a separate algorithmic subsystem: it exposes the same engine behavior in a browser-friendly form.
11. Rust port and Rust WASM build
- Rust/ is a Rust version of the same engine/build logic.
- WASM Rust/ contains the wasm-pack style browser bundle for that Rust implementation, including generated JS bindings and a .wasm binary.
- Architecturally, this mirrors the Go setup: shared engine concepts, different language/runtime packaging.
12. External and tooling boundaries
- The repo uses standard language toolchains only:
- Go modules for the main and WASM Go builds
- Cargo for the Rust build
- wasm targets for browser execution
- There are no obvious external services; the architecture is self-contained and file-driven.
13. What an architecture diagram should emphasize
- The most important flow is:
- board rules + symmetry tables + win masks
- into offline map construction
- producing serialized game graphs
- consumed by the runtime engine
- exposed either as a CLI/local Go app or a WebAssembly browser app
- The main boundary is between graph generation and graph consumption; the rest of the repo supports that split.
14. Notable duplication across languages
- The Go, Rust, and WASM folders largely repeat the same conceptual modules: model, engine, symmetry reduction, constants, and utilities.
- That duplication is important for diagramming: it suggests multiple deployment targets for the same core algorithm, rather than several unrelated products.
Main entry points: buildEmptyMap.go Build empty · mapbuilder Map builder · 3TEngine.go T3 engine · Constants Constants
Components 26
Go core
Primary Go implementation of the 3T engine and offline map builder.
- Main app · Root Go executable and local entrypoint.
main.go - Constants · Win masks, symmetry tables, and value encodings for the game domain.
src/Constants - Symmetry reduction · Collapses equivalent board states under board symmetries.
src/SymmetryReduction - Game model · Shared graph and state structures used by builder and engine.
src/model - Build empty · Initial graph construction and empty-map setup.
src/mapBuilder/buildEmptyMap.go - Set terminal · Assigns terminal outcomes to winning and draw states.
src/mapBuilder/setTerminalValues.go - Propagate values · Finalizes values for non-terminal states during offline map generation.
src/mapBuilder/setValues.go - T3 engine · Lightweight runtime that answers from the precomputed game graph.
src/TTTEngine/3TEngine.go - Game graph · In-memory graph representation used by the runtime engine.
src/TTTEngine/3TGameGraph.go - Next states · Generates successor states from moves.
src/utils/nextstates.go - Prev states · Reconstructs predecessor relationships for build and verification.
src/utils/prevstates.go - TTT maps · Precomputed valued and unvalued game-map outputs consumed by the engine.
bin/graph/valued/map1.ttt
Go WASM
Browser-delivered Go build compiled to WebAssembly.
- WASM app · Go WebAssembly runtime entrypoint.
WASM/main.go - WASM engine · Browser-facing engine logic compiled to WebAssembly.
WASM/tttEngine.go - WASM constants · Go WASM copy of the domain tables and win logic.
WASM/constants.go
Rust port
Rust implementation mirroring the Go architecture.
- Rust lib · Rust library root for the ported implementation.
Rust/src/lib.rs - Game model · Rust graph and state structures mirroring the Go model.
Rust/src/model - Map builder · Rust offline pipeline for building and valuing the game graph.
Rust/src/mapbuilder - TTT engine · Rust runtime engine that queries the precomputed map.
Rust/src/game_engine/ttt_engine.rs - Symmetry reduction · Rust symmetry reduction layer for canonical board states.
Rust/src/symmetry_reduction - Constants · Rust win masks, symmetry tables, and value encodings.
Rust/src/constants - TTT maps · Rust-produced serialized map outputs.
Rust/bin/output/map/valued/map1.ttt
Rust WASM
Browser-delivered Rust build and generated package.
- WASM package · Browser package generated from the Rust implementation.
WASM Rust/pkg/tte_wasm.js - WASM lib · Rust WebAssembly library entrypoint.
WASM Rust/src/lib.rs - WASM engine · Rust WebAssembly engine implementation.
WASM Rust/src/ttt_engine.rs - Game model · Rust WASM state and map structures.
WASM Rust/src/state_model.rs
Connections 27
- Constants → Symmetry reduction: tables · Symmetry tables and encodings feed canonical reduction.
- Constants → Set terminal: wins · Win masks and values drive terminal assignment.
- Constants → T3 engine: rules · Engine uses domain encodings and win logic.
- Symmetry reduction → Build empty: canonicalize · Builder reduces states before graph construction.
- Game model → Build empty: state schema · Builder emits graph data in the shared model.
- Build empty → Set terminal: stage · Initial structure is then annotated with terminal values.
- Set terminal → Propagate values: stage · Terminal assignments feed value propagation.
- Propagate values → TTT maps: serialize · Offline pipeline writes finalized map artifacts.
- TTT maps → T3 engine: load · Runtime engine consumes the precomputed graph.
- Next states → Build empty: transitions · Successor generation supports building the graph.
- Prev states → Propagate values: backtrack · Predecessor traversal supports verification and valuation.
- Game graph → T3 engine: answers · Engine queries the graph for outcomes and choices.
- Main app → T3 engine: runs · Root executable ties the Go engine together.
- Main app → TTT maps: uses · Local execution can read generated map files.
- WASM app → WASM engine: bootstraps · Browser entrypoint starts the WebAssembly engine.
- WASM constants → WASM engine: rules · WASM engine uses the same domain tables.
- Constants → Symmetry reduction: tables · Rust symmetry reduction depends on shared constants.
- Constants → Map builder: wins · Builder uses win masks and value encodings.
- Game model → Map builder: state schema · Rust builder emits the shared model.
- Game model → TTT engine: state schema · Rust engine consumes the same graph model.
- Symmetry reduction → Map builder: canonicalize · Symmetry reduction feeds Rust map construction.
- Map builder → TTT maps: serialize · Rust pipeline writes finalized map files.
- TTT maps → TTT engine: load · Rust runtime consumes the precomputed graph.
- Rust lib → TTT engine: exports · Crate root exposes the Rust runtime components.
- WASM lib → WASM engine: exports · WebAssembly crate root exposes engine logic.
- Game model → WASM engine: state schema · WASM engine uses the Rust state model.
- WASM package → WASM engine: bundle · Generated package wraps the compiled WASM engine.