Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1dxvtsZx8NE9fwjXUNDBr
80 lines
4.2 KiB
JavaScript
80 lines
4.2 KiB
JavaScript
// Copione del video «Come si gioca: la scopa» (video/SCALETTA-CARTE.md, clip 3).
|
|
// Giro: video/narra.py, poi rec.mjs come in video/SCALETTA.md, poi video/monta.py <cartella> --tutorial.
|
|
import { c, sleep, setup as base, regista } from "./tutorial-comune.mjs";
|
|
|
|
export const title = { it: "Come si gioca · la scopa", en: "Come si gioca · la scopa" };
|
|
export const cues = [
|
|
c("dove", "Allo stesso tavolo dell'oratorio si gioca anche a scopa, in due: basta chiedere «Una scopa?»"),
|
|
c("mazzo", "Mazzo e livello si scelgono come per la briscola"),
|
|
c("valori", "Quattro carte in tavola e tre in mano. L'Asso vale uno, le altre il loro numero, il gobbo otto, la donna nove e il regio dieci"),
|
|
c("presa", "Con una carta prendi quella dello stesso valore; se non c'è, un gruppo di carte che fa la stessa somma. Se puoi prendere, devi"),
|
|
c("scelta", "Quando le prese possibili sono più d'una, scegli tu: tocca una carta in tavola, oppure usa i pulsanti qui sotto"),
|
|
c("scopa", "Se con la tua carta pulisci tutta la tavola, è scopa: un punto in più"),
|
|
c("resto", "Finite le tre carte se ne danno altre tre, finché c'è mazzo. Quel che resta in tavola alla fine va all'ultimo che ha preso"),
|
|
c("conto", "A fine smazzata un punto a chi ha più carte, uno a chi ha più mattoni, uno per il settebello, il sette di mattoni, e uno per la primiera"),
|
|
c("primiera", "La primiera somma la carta migliore di ogni seme: il sette vale ventuno, il sei diciotto, l'Asso sedici"),
|
|
c("fine", "Si va agli undici punti, una smazzata dopo l'altra. Buona scopa!"),
|
|
];
|
|
|
|
export const setup = base;
|
|
|
|
export async function run(d) {
|
|
const p = d.page, r = regista(d, "tutorial-scopa");
|
|
await r.ascolta();
|
|
await r.vaiA("oratorio", [470, 300]);
|
|
await r.cue("dove");
|
|
await r.parlaCon("giocatore_carte");
|
|
await r.scegli("Una scopa?");
|
|
await r.cue("mazzo");
|
|
await r.scegli("Con le toscane.");
|
|
await r.scegli("Seria.");
|
|
// Una smazzata fissa: Andrea sceglie fra due prese, fa due scope e la vince 5 a 1.
|
|
await p.evaluate(async () => {
|
|
const { newScopa } = await import("/src/engine/scopa.js");
|
|
game.closeup = { id: "scopa", ...newScopa(73, { level: "seria", deck: "toscane" }) };
|
|
});
|
|
await sleep(800);
|
|
await p.waitForFunction(() => window.music?.want === "assets/audio/carte.mp3", null, { timeout: 10000 });
|
|
await r.cue("valori");
|
|
await r.muovi([320, 160], 1.0); await sleep(500); await r.muovi([320, 300], 1.0);
|
|
await r.cue("presa");
|
|
|
|
// Una mossa di Andrea, come la sceglierebbe un giocatore attento; la scelta fra più prese si fa col pulsante.
|
|
let k = 1, scelta = false, scopa = false;
|
|
for (let i = 0; i < 400; i++) {
|
|
const s = await p.evaluate(async () => {
|
|
const { canPlay } = await import("/src/engine/scopa.js");
|
|
return ["smazzata", "result"].includes(game.closeup.step) ? "fine" : canPlay(game.closeup) && !game.speech ? "tocca" : "aspetta";
|
|
});
|
|
if (s === "fine") break;
|
|
if (s === "aspetta") { await sleep(150); continue; }
|
|
const m = await p.evaluate(async (k) => {
|
|
const S = await import("/src/engine/scopa.js"), c = game.closeup, m = S.choose(S.observation(c, "player"), "male", k);
|
|
const card = c.hands.player[m.index], many = S.captures(c.table, card).length > 1;
|
|
const clean = !!m.captured && m.captured.length === c.table.length;
|
|
const { handX, HAND } = await import("/src/engine/scopa-render.js");
|
|
return { ...m, many, clean, at: [handX(c.hands.player.length, m.index) + 32, HAND.y + 46] };
|
|
}, k++);
|
|
if (m.many && !scelta) { scelta = true; await r.cue("scelta"); }
|
|
if (m.clean && !scopa) { scopa = true; await r.cue("scopa"); }
|
|
await r.clicca(m.at, 0.7);
|
|
if (m.many) {
|
|
await p.waitForFunction(() => game.closeup.step === "choose", null, { timeout: 5000 });
|
|
await sleep(900);
|
|
await d.click(p.locator(`#scopa-options [data-option="${m.option}"]`), 0.7);
|
|
await p.locator("#scene").scrollIntoViewIfNeeded();
|
|
}
|
|
if (k === 9) await r.cue("resto");
|
|
}
|
|
await p.waitForFunction(() => game.closeup.step === "smazzata", null, { timeout: 60000 });
|
|
await sleep(1200);
|
|
await r.cue("conto");
|
|
await r.cue("primiera");
|
|
await r.cue("fine");
|
|
await r.aspetta();
|
|
await d.click(p.locator("#closeup-close"), 0.6);
|
|
await r.fermi(800);
|
|
await r.fine();
|
|
await r.salvaAudio();
|
|
}
|