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: il tressette ai 21» (video/SCALETTA-CARTE.md, clip 2).
|
||||
// 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 · il tressette ai 21", en: "Come si gioca · il tressette ai 21" };
|
||||
export const cues = [
|
||||
c("dove", "Per il tressette ai ventuno servono quattro giocatori: il giocatore di carte chiama due amici, e uno fa da socio ad Andrea"),
|
||||
c("mazzo", "Mazzo e livello si scelgono come per la briscola"),
|
||||
c("tavolo", "Il socio è di fronte, gli avversari ai lati. Dieci carte a testa, e si gira verso destra"),
|
||||
c("accuse", "In alto le accuse: la napoletana, cioè Asso, due e tre dello stesso seme, oppure tre Assi, tre due o tre tre. Valgono punti subito"),
|
||||
c("seme", "Chi esce gioca quel che vuole; gli altri devono rispondere al seme, se ce l'hanno. Le carte che non si possono giocare diventano scure"),
|
||||
c("ordine", "Prende la più alta del seme di uscita: il tre, poi il due, l'Asso, il regio, la donna, il gobbo, e giù fino al quattro"),
|
||||
c("segni", "Chi esce può fare un segno al socio. Si sceglie coi pulsanti qui sotto, o coi tasti B, S e V, e poi si gioca la carta"),
|
||||
c("striscio", "Striscio vuol dire: di questo seme ne ho ancora, non è l'ultima"),
|
||||
c("busso", "Busso: prendi con la migliore che hai, e poi ritornami il seme"),
|
||||
c("volo", "Volo: era l'ultima carta di questo seme"),
|
||||
c("punti", "L'Asso vale un punto; il tre, il due e le figure un terzo di punto. L'ultima presa vale un punto in più"),
|
||||
c("smazzata", "A fine smazzata si contano i punti interi, e le accuse si sommano"),
|
||||
c("fine", "Si gioca smazzata dopo smazzata: la coppia che arriva per prima a ventuno è fuori, e ha vinto. Buon tressette!"),
|
||||
];
|
||||
|
||||
export const setup = base;
|
||||
|
||||
export async function run(d) {
|
||||
const p = d.page, r = regista(d, "tutorial-tressette");
|
||||
await r.ascolta();
|
||||
await r.vaiA("oratorio", [470, 300]);
|
||||
await r.cue("dove");
|
||||
await r.parlaCon("giocatore_carte");
|
||||
await r.scegli("Un tressette ai 21?");
|
||||
await r.cue("mazzo");
|
||||
await r.scegli("Con le toscane.");
|
||||
await r.scegli("Seria.");
|
||||
// Una smazzata fissa: accuse, e Andrea che usa striscio, busso e volo.
|
||||
await p.evaluate(async () => {
|
||||
const { newTressette } = await import("/src/engine/tressette.js");
|
||||
game.closeup = { id: "tressette", ...newTressette(11, { level: "seria", deck: "toscane" }) };
|
||||
});
|
||||
await sleep(800);
|
||||
await p.waitForFunction(() => window.music?.want === "assets/audio/carte.mp3", null, { timeout: 10000 });
|
||||
await r.cue("tavolo");
|
||||
await r.muovi([320, 60], 0.9); await sleep(300); await r.muovi([600, 150], 0.9); await sleep(300); await r.muovi([40, 150], 0.9);
|
||||
|
||||
let k = 1, detto = new Set(), seme = false, accuse = false;
|
||||
for (let i = 0; i < 600; i++) {
|
||||
const s = await p.evaluate(async () => {
|
||||
const { canPlay } = await import("/src/engine/tressette.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; }
|
||||
// Le accuse si dicono giocando la prima carta: se ne parla quando sono scritte in alto.
|
||||
if (!accuse && await p.evaluate(() => game.closeup.accuse.length > 0)) { accuse = true; await r.cue("accuse"); }
|
||||
const m = await p.evaluate(async (k) => {
|
||||
const T = await import("/src/engine/tressette.js"), c = game.closeup, m = T.choose(T.observation(c, 0), "male", k);
|
||||
const { handX, CARD } = await import("/src/engine/tressette-render.js");
|
||||
return { ...m, follow: c.table.length > 0, at: [handX(c.hands[0].length, m.index) + 21, CARD.y + 30] };
|
||||
}, k++);
|
||||
if (m.follow && !seme) { seme = true; await r.cue("seme"); await r.cue("ordine"); }
|
||||
if (m.signal && !detto.has(m.signal)) {
|
||||
if (!detto.size) await r.cue("segni");
|
||||
detto.add(m.signal);
|
||||
await r.cue(m.signal);
|
||||
}
|
||||
if (m.signal) await d.click(p.locator(`#tressette-${m.signal}`), 0.6);
|
||||
await p.locator("#scene").scrollIntoViewIfNeeded();
|
||||
await r.clicca(m.at, 0.7);
|
||||
if (k === 7) await r.cue("punti");
|
||||
}
|
||||
await p.waitForFunction(() => ["smazzata", "result"].includes(game.closeup.step), null, { timeout: 60000 });
|
||||
await sleep(1200);
|
||||
await r.cue("smazzata");
|
||||
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