Files
leggenda-del-regolo/video/tutorial-scopa.mjs
T

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();
}