chore: initial commit
This commit is contained in:
99
docs/FINDINGS.md
Normal file
99
docs/FINDINGS.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Findings
|
||||
|
||||
> Last Updated: 2026-03-31T00:00:00.000Z
|
||||
|
||||
## Summary
|
||||
|
||||
Initial analysis of the Scopone Scientifico Phaser 3 codebase. This document is populated by the Planner agent as research is performed.
|
||||
|
||||
## Codebase Observations
|
||||
|
||||
- **Total source files**: 9 TypeScript (6 in `src/`), 3 Java (Capacitor boilerplate)
|
||||
- **Largest file**: `GameScene.ts` (~1340 lines) — rendering, input, effects, audio, UI
|
||||
- **Game logic is framework-independent**: `game/` modules have zero Phaser imports
|
||||
- **No test framework**: only `tsc --noEmit` for type-checking
|
||||
- **No linter/formatter**: code style enforced manually
|
||||
- **AI plays all 3 non-human seats** using the same heuristic
|
||||
- **Procedural audio**: all sound is Web Audio oscillators — no audio asset files
|
||||
|
||||
## Potential Improvement Areas
|
||||
|
||||
- **AI cheats with perfect information**: `scoreDump()` and `opponentThreatScore()` in `ai.ts` iterate `opp.hand` directly — bots can see all opponent cards. Must be replaced with imperfect-information card tracking.
|
||||
- **No mastery/difficulty levels**: All 3 AI seats use the same heuristic at the same strength.
|
||||
- **No card tracking**: No module tracks which cards have been played or remains in the deck.
|
||||
- **No minimax**: Pure heuristic scoring, no look-ahead or game tree search.
|
||||
- **Allied bot is selfish**: Compagno (player 2) plays identically to opponents — no cooperative strategy.
|
||||
|
||||
## 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 dealt** (10 each), **no initial table cards** — the "scientifico" variant
|
||||
- Play passes around the table (counter-clockwise in Italian tradition; this game uses 0→1→2→3)
|
||||
- Each turn: play one card face-up to the table
|
||||
|
||||
#### Capture Rules
|
||||
1. If the played card's value **matches a table card**, the table card **must** be captured (single card, not a sum)
|
||||
2. If **multiple table cards match** the played value, exactly one is captured (player chooses)
|
||||
3. If **no direct match**, the player may capture a **subset of table cards summing** to the played value
|
||||
4. If the played card matches both a single card and a sum, **the single card must be captured** (not the sum)
|
||||
5. There is **no obligation to play a capturing card** — a player may choose to play a non-capturing card instead. But if the played card CAN capture, it MUST capture.
|
||||
6. **Scopa**: capturing ALL remaining table cards awards +1 point (except on the very last card of the round)
|
||||
|
||||
#### Scoring (per round, 4 fixed points + scope)
|
||||
| Category | Rule |
|
||||
|------------|----------------------------------------------------------|
|
||||
| **Carte** | Team with majority of captured cards (20+ of 40). Tie = no point. |
|
||||
| **Denari** | Team with majority of coins/denara suit cards (6+ of 10). Tie = no point. |
|
||||
| **Settebello** | Team capturing the 7 of denara. Always awarded. |
|
||||
| **Primiera** | Team with highest prime value. Prime = best card per suit using special scale. Tie = no point. Must have all 4 suits. |
|
||||
| **Scope** | +1 per scopa achieved during play. |
|
||||
|
||||
#### Primiera Values (confirmed matching codebase)
|
||||
| Card value | Primiera value |
|
||||
|------------|---------------|
|
||||
| 7 | 21 |
|
||||
| 6 | 18 |
|
||||
| 1 (Ace) | 16 |
|
||||
| 5 | 15 |
|
||||
| 4 | 14 |
|
||||
| 3 | 13 |
|
||||
| 2 | 12 |
|
||||
| 8,9,10 | 10 |
|
||||
|
||||
A team missing an entire suit **cannot win primiera** (even 3×21=63 loses to 21+16+16+16=69 with all 4 suits).
|
||||
|
||||
#### Winning
|
||||
- First team to **11+ points** at the end of a round wins
|
||||
- If both reach 11 in the same round, higher total wins; if tied, play continues
|
||||
|
||||
#### Strategy Notes (from Pagat.com)
|
||||
- **7 of coins (settebello)** is the single most valuable card — contributes to all 4 fixed scoring categories
|
||||
- **Avoid giving scope**: leave table total ≥ 11 when possible
|
||||
- **Anchor strategy**: leave a card on table that your team controls (you hold duplicates of that value)
|
||||
- **Whirlwind**: consecutive scope — clearing the table forces opponent to play, partner captures, repeat
|
||||
- **Sevens > sixes > aces** in priority for primiera control
|
||||
- **Paired/unpaired tracking**: if all captures are single-card matches, the last card matches the last table card. Sum captures disrupt this pattern, important for end-game planning.
|
||||
|
||||
### Codebase Capture Rule Validation
|
||||
The `findCaptures()` in `engine.ts` correctly implements:
|
||||
- Direct match priority over sum captures ✓
|
||||
- Multiple direct matches: takes ALL matching cards (slight deviation — pagat.com says choose ONE, but Wikipedia says take all. The codebase takes all direct matches. This is the **existing behavior** and must not be altered per success criteria.)
|
||||
- Sum subsets via power set enumeration ✓
|
||||
- `applyMove()` auto-captures when possible ✓
|
||||
|
||||
### Minimax Feasibility Analysis
|
||||
- 10 cards per player × 4 players = 40 total moves per round
|
||||
- Full game tree: ~10^12 nodes — infeasible for exhaustive search
|
||||
- **Approach**: Depth-limited alpha-beta with determinization for imperfect information
|
||||
- Sample N possible opponent hand assignments consistent with card tracking
|
||||
- Run minimax on each sample to limited depth (4–6 plies)
|
||||
- Average/vote across samples for best move
|
||||
- Alpha-beta pruning reduces effective branching factor significantly
|
||||
- Depth 4 (one full rotation) with ~5 moves per player = ~625 nodes per sample — very manageable
|
||||
- 10–20 samples × 625 nodes = ~6,000–12,500 evaluations — runs in <100ms on modern hardware
|
||||
Reference in New Issue
Block a user