Game of 2048
Phase 1 — Core grid, rules & scoring
- 4×4 board, slide/merge logic (left/right/up/down)
- Spawn logic (A new 2 or 4 with configurable odds, e.g. 80% chance of spawning a 2, 20% chance of spawning a 4)
- Deterministic update order; single-move application
- Score tracking; win (tile 2048) and lose detection
Functional result: A small script runs a playable loop in the console: moves apply correctly, tiles spawn, score updates, and win/lose states are detected.
Phase 2 — Opponent types & CLI
- CLI:
2048.py <opponent_type>viaargparse - Opponent interface:
choose_spawn(board) -> (row, col ,val) - Implement
randomandadversarial(choose worst legal spawn)-
Random opponent: picks an empty cell at random and places a tile (2 or 4) using the spawn logic (like the normal 2048 game)
-
Adversarial opponent: tries to make the game harder; chooses the empty cell that will create the worst possible situation for the player
-
- Optional
--seedfor reproducible behavior; validate type
Functional result: Running with random or adversarial changes difficulty; invalid types fall back to random; repeated runs with the same seed behave identically.
Phase 3 — GUI (Tkinter) gameplay
- Window with 4×4 grid, colored tiles, score label
- Keyboard input (arrows/WASD) driving moves
- After each move: spawn via selected opponent, update UI
- End-of-game modal when 2048 reached or no moves left
Functional result: Launching 2048.py random opens a responsive board where keys move tiles, score updates live, and a clear dialog appears on win/lose.
Phase 4 — Minimal UX polish
- “New Game” button (reseed + clear board/score)
- Simple animation timing (
after) for slide/merge feel - Lightweight guardrails: ignore input during animation; cap FPS
Functional result: Players can restart instantly; moves feel smooth without jank; rapid key presses don’t break state, and overall play remains stable.