Full-Stack & AI Developer | Columbia CS | Puzzle solver & systems thinker
AI-Powered 2048 Solver
I built an AI agent to play 2048 using expectiminimax search with alpha-beta pruning and custom heuristics. The solver evaluates board states based on structure, smoothness, and long-term potential, consistently reaching the 2048 and 4096 tiles. All decisions are made in under 150ms.
Goals
-
Build an autonomous agent that can play 2048 effectively and consistently reach high-value tiles (2048, 4096, and beyond).
-
Implement a decision-making algorithm that accounts for randomness in the game (tile spawns) and plans several moves ahead.
-
Explore and evaluate the effectiveness of expectiminimax search for real-time game play.
-
Tune the solver for accuracy and performance, aiming for completion of each move within 200ms.
​
Specs
-
Programming language: Python 3
-
Search algorithm: Expectiminimax with alpha-beta pruning
-
Evaluation functions: Custom heuristics measuring monotonicity, smoothness, empty tiles, and maximum tile position
-
Performance tuning: Implemented depth-limited search with selective pruning for playable frame rates
-
Data structures: Matrix representation of the board, depth-aware node evaluation, and probabilistic modeling of tile spawns (90% 2s, 10% 4s)
​
Design process
-
Started with a basic implementation of 2048 in Python to replicate game mechanics and environment.
-
Defined board evaluation heuristics:
-
Monotonicity: Incentivizes smooth increasing sequences across rows/columns.
-
Smoothness: Penalizes large differences between adjacent tiles.
-
Empty tiles: Encourages keeping the board open.
-
Max tile in corner: Promotes long-term strategy.
-
-
Integrated an expectiminimax algorithm to account for the randomness in new tile spawns.
-
Introduced alpha-beta pruning to reduce computation time and allow deeper searches (typically to depth 4–6).
-
Performed simulation runs (100+ games) to track average highest tile and win rates.
​
Challenges
-
The branching factor of the game tree was large due to randomness, requiring optimization to maintain speed.
-
Tuning the weighting of heuristics was nontrivial and took some trial and error — strong performance on some boards could lead to poor generalization.
-
Real-time performance was a constraint; early versions took 1–2 seconds per move, later reduced to ~100–150ms with pruning.
-
Some game states caused loops or indecision due to heuristic plateaus; this required handling for tiebreaking and move prioritization.
-
Balancing lookahead depth with system resources — deeper searches gave better results but risked frame lag.
​
Outcomes
-
The solver regularly achieved 2048 and 4096 tiles, with occasional paths toward 8192, surpassing average human play.
-
Demonstrated that a well-tuned expectiminimax agent can outperform simpler greedy or rule-based strategies.
-
The algorithm consistently made moves within 100–150ms.
-
Visualized game play using a color-coded CLI display and stored performance logs for later analysis.
-
Codebase was modular, making it easy to swap out or A/B test different heuristics or search strategies.
​
Potential next steps
-
Build a graphical interface to visualize decision-making and gameplay more intuitively.
-
Train a neural network to learn the evaluation function, allowing the agent to improve heuristics from data.
-
Experiment with other search algorithms for comparison with expectiminimax.
-
Integrate move confidence scoring to better understand the agent’s reasoning and risk tolerance.
-
Deploy on a simple web app to make the solver accessible for demonstration or competitive play.



