Bocce: il clic fissa la mira come al biliardo, così andando verso la forza o «Lancia» il puntatore non la sposta più (scoperto girando il video: la boccia partiva a due passi). Copioni dei video «Come si gioca» di scopa, tressette, bocce e biliardo, e video/sovrapposte.py per controllare che il narratore non parli sopra i personaggi
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1dxvtsZx8NE9fwjXUNDBr
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
// 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();
|
||||
}
|
||||
Reference in New Issue
Block a user