Giochi di carte dopo la revisione di Codex sui tre insieme; player dei video «Come si gioca» e primo copione

Esito che vale e si salva appena deciso, per tutti i minigiochi (anche tornando al titolo dalla schermata del risultato); briscola: uscire durante il conteggio non perde più la vittoria; tressette: si esce ai 21 col primo evento che ci porta, accusa compresa (prima vinceva sempre Andrea se ci arrivavano tutte e due), il carico che fa vincere si dà anche se è il 2, accuse che non escono dal tavolo, convenzioni scritte nell'aiuto; scopa: primiera valutata per quel che migliora, finale esatto a mazzo finito, presa sulla tavola al rilascio con scelta e conferma, frecce e Invio sempre sulla presa scelta. Tastiera: Invio e Spazio giocano sempre la carta scelta. Tavola descritta a parole. Classi CSS comuni ai tre giochi.
Video: player nel gioco (pulsante «Guarda il video» nel «Come si gioca», compare quando il video esiste), video/narra.py per la voce del narratore, pezzi comuni dei copioni e il copione della briscola; scaletta in video/SCALETTA-CARTE.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A1dxvtsZx8NE9fwjXUNDBr
This commit is contained in:
2026-10-26 16:39:22 +01:00
co-authored by Claude Opus 5.5
parent 30e324d7e2
commit 7e1e6f6144
24 changed files with 594 additions and 73 deletions
+24 -2
View File
@@ -60,7 +60,7 @@ test('l’ultima pescata è la briscola, poi tre prese senza mazzo; totale e con
}
assert.ok(lastDraw); assert.equal(c.step, 'count'); assert.equal(c.history.length, 20);
assert.equal(c.hands.player.length + c.hands.cpu.length, 0); assert.equal(c.stock.length, 0);
assert.equal(c.result, undefined, 'risultato solo dopo il conteggio');
assert.equal(c.result.player + c.result.cpu, 120, 'il risultato è già deciso: il conteggio lo mostra soltanto');
assert.equal(new Set([...c.taken.player, ...c.taken.cpu].map(a => a.id)).size, 40);
assert.deepEqual(counted(c), { player: 0, cpu: 0 });
update(c, 0.36); assert.equal(c.count, 1);
@@ -165,7 +165,7 @@ test('oratorio: dialogo, livelli, abbandono, risultati, rivincita e salvataggio
g.closeupClose(); settle(g); assert.equal(!!g.state.flags.briscola_vinta, outcome === 'win');
assert.equal(!!g.state.flags.briscola_giocata, outcome !== 'quit');
g.act('talk', 'giocatore_carte'); settle(g);
assert.equal(g.options()[0].text, outcome === 'quit' ? 'Una briscola?' : 'La rivincita?');
assert.equal(g.options()[0].text, outcome === 'quit' ? 'Una briscola?' : 'Rivincita a briscola?');
assert.ok(MINIGAMES.bocce.press && MINIGAMES.biliardo.press);
}
});
@@ -181,3 +181,25 @@ test('due mazzi, stesse regole: le napoletane cambiano solo i nomi', () => {
// L'avversario ragiona sul mazzo giusto: le carte non viste sono napoletane.
assert.ok(unseen(observation(n)).every(a => DECKS.napoletane.suits.includes(a.suit)));
});
// Codex (revisione dei tre giochi): l'esito vale appena è deciso. Uscire durante il conteggio della briscola non lo
// perde, e i flag finiscono nel salvataggio anche se dal risultato si torna al titolo senza uscire dal tavolo.
test('carte all\'oratorio: l\'esito si salva appena deciso, e uscire durante il conteggio non lo perde', () => {
const games = [['Una briscola?', 'briscola', 'briscola_vinta'], ['Un tressette ai 21?', 'tressette', 'tressette_vinto'], ['Una scopa?', 'scopa', 'scopa_vinta']];
for (const [ask, id, flag] of games) {
const saved = [], g = new Game(story, { onSave: s => saved.push(s) });
settle(g); g.go('oratorio'); settle(g);
g.act('talk', 'giocatore_carte'); settle(g);
for (const text of [ask, 'Con le toscane.', 'Seria.']) { g.choose(g.options().findIndex(o => o.text === text)); settle(g); }
assert.equal(g.closeup?.id, id);
// La briscola durante il conteggio: il risultato c'è già. Gli altri due, a risultato.
Object.assign(g.closeup, id === 'briscola' ? { step: 'count', result: { winner: 'player', player: 70, cpu: 50 } } : { step: 'result', result: { winner: 'player' } });
g.update(0.01);
assert.equal(saved.at(-1).flags[flag], true, `${id}: la vittoria è già nel salvataggio`);
assert.equal(g.state.flags[flag], true);
g.closeupClose(); const said = settle(g).map(s => s.text);
const win = story.closeups[id].win.find(e => e.say).say, quit = story.closeups[id].quit[0].say;
assert.ok(said.includes(win) && !said.includes(quit), `${id}: esce con la battuta della vittoria, non con quella di chi lascia`);
assert.equal(g.state.flags[flag], true);
}
});