Files
scopone/docs/FINDINGS.md
2026-04-02 20:16:27 +02:00

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) and src/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, and master.
  • The advanced and master tiers use CardTracker to reason about unseen cards instead of reading hidden hands directly.
  • The master tier performs determinization plus alpha-beta search and reports progress back to the scene.
  • GameScene displays AI progress through a top think bar and updates it from the AIDecisionProgress callback.
  • 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.ts still centralizes scene layout, input, effects, audio, HUD, and round transitions in one file, which raises maintenance cost.
  • ai.ts mixes heuristic tiers, inference helpers, determinization, and alpha-beta evaluation in one module.
  • The master profile 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

  • beginner adds randomness around a basic heuristic to remain beatable.
  • advanced adds race awareness, anti-scopa logic, partner setup, anchor play, and tracker-based probability estimates.
  • master orders 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

  • MenuScene exposes difficulty selection before match start.
  • GameScene records every played card and captured table card in CardTracker.
  • 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

  1. If the played card matches one or more table cards by value, a direct match must be taken.
  2. If multiple direct matches exist, one matching table card is chosen.
  3. If no direct match exists, a subset of table cards may be captured when their values sum to the played value.
  4. A direct match has priority over any possible sum capture.
  5. 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 TimerEvent progress helpers.
  • Instead, chooseMove() emits its own normalized progress payload through AIDecisionProgress.
  • GameScene.updateThinkBar() renders remaining time from that callback.
  • The yielding behavior in masterMove() is necessary so the browser can repaint while search batches continue.