4.9 KiB
4.9 KiB
Findings
Last Updated: 2026-04-02T18:12:18.000Z
Summary
Initializer refresh for the current Scopone Scientifico codebase. The existing findings were stale relative to the latest AI and tracker implementation, so the observations below reflect the current source tree.
Codebase Observations
- Primary gameplay code lives in 8 TypeScript source files under
src/; the Android wrapper adds 3 Java files. - The largest modules are
src/scenes/GameScene.ts(1446 lines) andsrc/game/ai.ts(1210 lines). src/game/remains framework-independent and contains the rules engine, score calculation, card tracker, and AI logic.- The AI now has three distinct difficulty levels:
beginner,advanced, andmaster. - The
advancedandmastertiers useCardTrackerto reason about unseen cards instead of reading hidden hands directly. - The
mastertier performs determinization plus alpha-beta search and reports progress back to the scene. GameScenedisplays AI progress through a top think bar and updates it from theAIDecisionProgresscallback.- Audio remains fully procedural via Web Audio; no audio asset pipeline is present.
- No ESLint or Prettier config is present.
- The only repository-wide verification command supplied is
npx tsc --noEmit.
Potential Improvement Areas
GameScene.tsstill centralizes scene layout, input, effects, audio, HUD, and round transitions in one file, which raises maintenance cost.ai.tsmixes heuristic tiers, inference helpers, determinization, and alpha-beta evaluation in one module.- The
masterprofile allows up to 9800 ms of search budget, which may be expensive on slower devices even with batch yielding. - There is still no dedicated automated test suite for rules or AI behavior beyond type-checking.
- Formatting rules are enforced socially rather than by a linter/formatter toolchain.
Current Rule / Implementation Notes
Capture behavior in engine.ts
- Direct-match capture has priority over subset-sum capture.
- When multiple direct matches exist,
findCaptures()returns one single-card option per matching card. - Subset-sum captures are explored only when no direct match exists.
applyMove()defaults to the first legal capture if no explicit capture choice is supplied.
AI implementation snapshot
beginneradds randomness around a basic heuristic to remain beatable.advancedadds race awareness, anti-scopa logic, partner setup, anchor play, and tracker-based probability estimates.masterorders legal moves with a quick evaluator, samples hidden hands, then scores moves with alpha-beta search under a deadline.masterMove()yields back to the browser between batches so Phaser can repaint the progress UI.
Scene / UI implementation snapshot
MenuSceneexposes difficulty selection before match start.GameScenerecords every played card and captured table card inCardTracker.- The HUD continuously displays cards, denari, settebello, primiera, scope, and total points for both teams.
- Round-end and game-over flows are managed in-scene rather than through separate overlay components.
Research Performed
Web Research: Scopone Scientifico Rules (2026-03-31)
Sources: Wikipedia (Scopa article, Scopone section), Pagat.com (Scopone page by John McLeod)
Core Rules (Scopone Scientifico variant)
- 4 players, 2 fixed teams of 2 (sit opposite): Team A = players 0+2, Team B = players 1+3.
- 40-card Napoletane deck: 4 suits (
bastoni,coppe,denara,spade), values 1-10. - All 40 cards are dealt at the start of the round; the table begins empty.
- Turns advance in the implementation as
0 -> 1 -> 2 -> 3.
Capture Rules
- If the played card matches one or more table cards by value, a direct match must be taken.
- If multiple direct matches exist, one matching table card is chosen.
- If no direct match exists, a subset of table cards may be captured when their values sum to the played value.
- A direct match has priority over any possible sum capture.
- Scopa awards a point only when the table is cleared before the final play of the round.
Scoring
| Category | Rule |
|---|---|
| Carte | Majority of captured cards |
| Denari | Majority of denara suit cards |
| Settebello | Team that captures the 7 of denara |
| Primiera | Highest best-of-each-suit prime value |
| Scope | One point per scopa |
Primiera values used in code
| Card value | Primiera value |
|---|---|
| 7 | 21 |
| 6 | 18 |
| 1 | 16 |
| 5 | 15 |
| 4 | 14 |
| 3 | 13 |
| 2 | 12 |
| 8, 9, 10 | 10 |
SCOPONE-0008: AI progress rendering notes (2026-04-02)
- The current implementation does not use Phaser
TimerEventprogress helpers. - Instead,
chooseMove()emits its own normalized progress payload throughAIDecisionProgress. GameScene.updateThinkBar()renders remaining time from that callback.- The yielding behavior in
masterMove()is necessary so the browser can repaint while search batches continue.