diff --git a/assets/characters/giocatore-carte.json b/assets/characters/giocatore-carte.json new file mode 100644 index 0000000..fc04181 --- /dev/null +++ b/assets/characters/giocatore-carte.json @@ -0,0 +1,38 @@ +{ + "image": "giocatore-carte.png", + "height": 100, + "frames": { + "sit": { + "x": 0, + "y": 0, + "w": 67, + "h": 100, + "ax": 25.7, + "ay": 100 + }, + "talk": { + "x": 69, + "y": 0, + "w": 68, + "h": 100, + "ax": 27.6, + "ay": 100 + }, + "laugh": { + "x": 139, + "y": 0, + "w": 72, + "h": 99, + "ax": 19.3, + "ay": 99 + }, + "shuffle": { + "x": 213, + "y": 0, + "w": 67, + "h": 97, + "ax": 25.2, + "ay": 97 + } + } +} diff --git a/assets/characters/giocatore-carte.png b/assets/characters/giocatore-carte.png new file mode 100644 index 0000000..1a8584c Binary files /dev/null and b/assets/characters/giocatore-carte.png differ diff --git a/assets/voices/andrea-6e63dafda1.mp3 b/assets/voices/andrea-6e63dafda1.mp3 new file mode 100644 index 0000000..3ad8f1a Binary files /dev/null and b/assets/voices/andrea-6e63dafda1.mp3 differ diff --git a/assets/voices/andrea-71f3bff8a0.mp3 b/assets/voices/andrea-71f3bff8a0.mp3 new file mode 100644 index 0000000..76a44b3 Binary files /dev/null and b/assets/voices/andrea-71f3bff8a0.mp3 differ diff --git a/assets/voices/andrea-b851b9ed26.mp3 b/assets/voices/andrea-b851b9ed26.mp3 new file mode 100644 index 0000000..1120fa3 Binary files /dev/null and b/assets/voices/andrea-b851b9ed26.mp3 differ diff --git a/assets/voices/andrea-be276497e3.mp3 b/assets/voices/andrea-be276497e3.mp3 new file mode 100644 index 0000000..fa07c4e Binary files /dev/null and b/assets/voices/andrea-be276497e3.mp3 differ diff --git a/assets/voices/andrea-d2f285f610.mp3 b/assets/voices/andrea-d2f285f610.mp3 new file mode 100644 index 0000000..3fa62f3 Binary files /dev/null and b/assets/voices/andrea-d2f285f610.mp3 differ diff --git a/assets/voices/andrea-e8599cc8b6.mp3 b/assets/voices/andrea-e8599cc8b6.mp3 new file mode 100644 index 0000000..6c308f6 Binary files /dev/null and b/assets/voices/andrea-e8599cc8b6.mp3 differ diff --git a/assets/voices/giocatore_carte-12f97003ec.mp3 b/assets/voices/giocatore_carte-12f97003ec.mp3 new file mode 100644 index 0000000..a3a3e59 Binary files /dev/null and b/assets/voices/giocatore_carte-12f97003ec.mp3 differ diff --git a/assets/voices/giocatore_carte-13af2e2331.mp3 b/assets/voices/giocatore_carte-13af2e2331.mp3 new file mode 100644 index 0000000..a2f2416 Binary files /dev/null and b/assets/voices/giocatore_carte-13af2e2331.mp3 differ diff --git a/assets/voices/giocatore_carte-1523994a6c.mp3 b/assets/voices/giocatore_carte-1523994a6c.mp3 new file mode 100644 index 0000000..f6ccdd8 Binary files /dev/null and b/assets/voices/giocatore_carte-1523994a6c.mp3 differ diff --git a/assets/voices/giocatore_carte-43e76cf11b.mp3 b/assets/voices/giocatore_carte-43e76cf11b.mp3 new file mode 100644 index 0000000..97f3bb2 Binary files /dev/null and b/assets/voices/giocatore_carte-43e76cf11b.mp3 differ diff --git a/assets/voices/giocatore_carte-4f39bc172d.mp3 b/assets/voices/giocatore_carte-4f39bc172d.mp3 new file mode 100644 index 0000000..cb89ad0 Binary files /dev/null and b/assets/voices/giocatore_carte-4f39bc172d.mp3 differ diff --git a/assets/voices/giocatore_carte-6ce98bce81.mp3 b/assets/voices/giocatore_carte-6ce98bce81.mp3 new file mode 100644 index 0000000..35d8e16 Binary files /dev/null and b/assets/voices/giocatore_carte-6ce98bce81.mp3 differ diff --git a/assets/voices/giocatore_carte-729b3344da.mp3 b/assets/voices/giocatore_carte-729b3344da.mp3 new file mode 100644 index 0000000..46ae995 Binary files /dev/null and b/assets/voices/giocatore_carte-729b3344da.mp3 differ diff --git a/assets/voices/giocatore_carte-89686f55a0.mp3 b/assets/voices/giocatore_carte-89686f55a0.mp3 new file mode 100644 index 0000000..19fd2a9 Binary files /dev/null and b/assets/voices/giocatore_carte-89686f55a0.mp3 differ diff --git a/assets/voices/giocatore_carte-8dfadb4acc.mp3 b/assets/voices/giocatore_carte-8dfadb4acc.mp3 new file mode 100644 index 0000000..5a1f685 Binary files /dev/null and b/assets/voices/giocatore_carte-8dfadb4acc.mp3 differ diff --git a/assets/voices/giocatore_carte-a8846bfa7b.mp3 b/assets/voices/giocatore_carte-a8846bfa7b.mp3 new file mode 100644 index 0000000..21f6fe2 Binary files /dev/null and b/assets/voices/giocatore_carte-a8846bfa7b.mp3 differ diff --git a/assets/voices/giocatore_carte-f1f219bd1c.mp3 b/assets/voices/giocatore_carte-f1f219bd1c.mp3 new file mode 100644 index 0000000..c953961 Binary files /dev/null and b/assets/voices/giocatore_carte-f1f219bd1c.mp3 differ diff --git a/assets/voices/index.json b/assets/voices/index.json index 6ebf404..8f8921a 100644 --- a/assets/voices/index.json +++ b/assets/voices/index.json @@ -487,6 +487,10 @@ "file": "andrea-f798fa755d.mp3", "sec": 4.9 }, + "andrea|Ha già mescolato. Mi sa che aspettava proprio un pollo di passaggio.": { + "file": "andrea-71f3bff8a0.mp3", + "sec": 5.09 + }, "andrea|Una gomma da masticare ancora incartata, persa davanti al palco. Qualcuno ha perso l'appetito.": { "file": "andrea-f2ea95922d.mp3", "sec": 6.54 @@ -1519,6 +1523,70 @@ "file": "andrea-60cdae2e35.mp3", "sec": 5.1 }, + "andrea|Una briscola?": { + "file": "andrea-d2f285f610.mp3", + "sec": 1.04 + }, + "andrea|La rivincita?": { + "file": "andrea-98e4366a56.mp3", + "sec": 0.83 + }, + "andrea|Ora cerco il palio. A dopo.": { + "file": "andrea-6e63dafda1.mp3", + "sec": 2.61 + }, + "giocatore_carte|Gnamo. In due, senza soci e senza scuse.": { + "file": "giocatore_carte-1523994a6c.mp3", + "sec": 3.78 + }, + "giocatore_carte|Il tavolo è qui. Il coraggio ce lo metti te.": { + "file": "giocatore_carte-8dfadb4acc.mp3", + "sec": 3.4 + }, + "andrea|Con le toscane.": { + "file": "andrea-e8599cc8b6.mp3", + "sec": 1.03 + }, + "andrea|Con le napoletane.": { + "file": "andrea-be276497e3.mp3", + "sec": 1.09 + }, + "andrea|Ci ripenso.": { + "file": "andrea-b851b9ed26.mp3", + "sec": 0.8 + }, + "giocatore_carte|Brao. Gobbo, donna e regio, come Dio comanda. Come la vuoi?": { + "file": "giocatore_carte-89686f55a0.mp3", + "sec": 6.14 + }, + "giocatore_carte|Le napoletane? Le tengo per i villeggianti. Come la vuoi?": { + "file": "giocatore_carte-4f39bc172d.mp3", + "sec": 5.13 + }, + "andrea|Alla bona.": { + "file": "andrea-67afa54e05.mp3", + "sec": 0.69 + }, + "andrea|Seria.": { + "file": "andrea-f6ef96032e.mp3", + "sec": 0.58 + }, + "andrea|A fassi male.": { + "file": "andrea-f52137b691.mp3", + "sec": 0.78 + }, + "giocatore_carte|Alla bona. I carichi li regalo, oggi.": { + "file": "giocatore_carte-43e76cf11b.mp3", + "sec": 3.43 + }, + "giocatore_carte|Allora posa il gomito e guarda le carte.": { + "file": "giocatore_carte-f1f219bd1c.mp3", + "sec": 2.51 + }, + "giocatore_carte|Io le conto tutte. Anche quelle che butti via per sbaglio.": { + "file": "giocatore_carte-12f97003ec.mp3", + "sec": 4.19 + }, "andrea|Una Fanta.": { "file": "andrea-8927b87738.mp3", "sec": 0.65 @@ -1815,10 +1883,6 @@ "file": "andrea-83b1337b4d.mp3", "sec": 3.31 }, - "andrea|La rivincita?": { - "file": "andrea-98e4366a56.mp3", - "sec": 0.83 - }, "andrea|Allora, Brento Sanico?": { "file": "andrea-2add39ff10.mp3", "sec": 1.29 @@ -1847,18 +1911,6 @@ "file": "mariano-1c9cd0c325.mp3", "sec": 5.96 }, - "andrea|Alla bona.": { - "file": "andrea-67afa54e05.mp3", - "sec": 0.69 - }, - "andrea|Seria.": { - "file": "andrea-f6ef96032e.mp3", - "sec": 0.58 - }, - "andrea|A fassi male.": { - "file": "andrea-f52137b691.mp3", - "sec": 0.78 - }, "mariano|Alla bona: tiro con gli occhi chiusi.": { "file": "mariano-b1b1ca273b.mp3", "sec": 2.2 @@ -2015,6 +2067,22 @@ "file": "castello-dc8a873d86.mp3", "sec": 4.36 }, + "giocatore_carte|Oh, bravo! Ora però rimescolo io.": { + "file": "giocatore_carte-a8846bfa7b.mp3", + "sec": 2.9 + }, + "giocatore_carte|I carichi portali qui, mica alla stazione! Rivincita quando vuoi.": { + "file": "giocatore_carte-6ce98bce81.mp3", + "sec": 4.72 + }, + "giocatore_carte|Sessanta pari. Un si litiga nemmeno sul conto!": { + "file": "giocatore_carte-13af2e2331.mp3", + "sec": 3.86 + }, + "giocatore_carte|Vai, ti tengo il posto. Le carte mica scappano.": { + "file": "giocatore_carte-729b3344da.mp3", + "sec": 3.3 + }, "mariano|Aspetta, ci vuole il metro...": { "file": "mariano-e8b4ebf3d9.mp3", "sec": 1.62 diff --git a/docs/BRISCOLA.md b/docs/BRISCOLA.md new file mode 100644 index 0000000..e9b0cd1 --- /dev/null +++ b/docs/BRISCOLA.md @@ -0,0 +1,129 @@ +# Briscola all’oratorio + +Implementazione del 26 ottobre 2026. ES modules statici, nessun build step. + +## Partita e comandi + +Il giocatore di carte è un personaggio inventato e provvisorio, seduto a destra alle tavolate +dell’oratorio: **[DA ANDREA: chi è]**. Il dialogo offre «Alla bona», «Seria», «A fassi male»; +dopo una partita conclusa offre la rivincita. `briscola_vinta` ricorda una vittoria e +`briscola_giocata` abilita la rivincita anche dopo sconfitta o patta. Nessuno dei due flag +serve alla soluzione dell’avventura. + +Un clic o tocco su una carta la gioca al rilascio sullo stesso bersaglio. Nessuna carica. +Le frecce e 1–2–3 scelgono, Invio gioca, Esc esce. I tre pulsanti con nome e seme +offrono bersagli aggiuntivi e accesso tramite Tab. I comandi di tiro degli altri minigiochi +rimangono separati; in `MINIGAMES` pressione, rilascio, annullamento e mira sono opzionali. + +Mazzo da 40 carte, 120 punti, distribuzione alternata e mazziere deterministico dal seed. +La briscola è in fondo al mazzo e compresa nel contatore. Chi prende pesca prima e riapre; +non esiste obbligo di seme. La presa resta visibile 1,25 secondi. Solo dopo la ventesima +presa si contano tutte le carte, una ogni 0,35 secondi, mostrando carta ingrandita, +incremento e totale. A 60–60 il risultato è patta. Il risultato resta fino all’uscita. + +## Avversari e taratura + +`observation` espone soltanto la propria mano, le carte pubbliche, i conteggi e l’eventuale +briscola pescata dall’altro. Non passa la mano avversaria, l’ordine del mazzo o il seed della +distribuzione. «Alla bona» sceglie casualmente; «Seria» scarta lisci, conserva briscole e +prende carichi con quelle piccole. «A fassi male» ricostruisce le carte non viste, confronta +le mosse su 40 distribuzioni possibili e simula seguiti giocati con buon senso. Sono ipotesi, +non la distribuzione effettiva. A mazzo finito il complemento delle carte pubbliche e della +propria mano identifica l’altra mano: da quel momento usa minimax esatto fino alla fine. + +Comando riproducibile: `node tools/calibrate_briscola.mjs 1000`. +Semi `Math.imul(i, 2654435761) >>> 0`, i da 1 a 1000, stessi mazzi per ogni livello. +Andrea usa sempre `attentive`, l’euristica di riferimento; dà le carte 496 volte su 1000. + +| Livello | Vittorie Andrea | Vittorie avversario | Patte | Punti medi Andrea | +| --- | ---: | ---: | ---: | ---: | +| Alla bona | 847 (84,7%) | 144 (14,4%) | 9 (0,9%) | 79,159 | +| Seria | 481 (48,1%) | 494 (49,4%) | 25 (2,5%) | 59,952 | +| A fassi male | 359 (35,9%) | 621 (62,1%) | 20 (2,0%) | 55,628 | + +Queste percentuali misurano il confronto con quell’automatismo, non con giocatori umani. + +## Grafica e audio + +Due mazzi, scelti nel dialogo («Con le toscane» / «Con le napoletane»): stesse regole e stessi id, cambiano +nomi e disegni (`DECKS` e `DECK_CARDS` in `briscola.js`; la scelta è il flag `carte_napoletane`). + +- **Toscane** (predefinite): semi francesi cuori, mattoni, fiori, picche; figure gobbo, donna e regio (il regio + sempre con la corona). Numerali senza numeri, semi disposti come nel mazzo vero e capovolti nella metà bassa; + figure intere col seme e la lettera (G, D, R) in alto a sinistra. Riferimento: `assets/raw/carte/toscane-riferimento.png`. +- **Napoletane**: monete, coppe, lame ricurve incrociate, bastoni nodosi; fante, cavallo e re. Valore nell’angolo + e seme scritto per non affidarsi solo al colore. + +Tutto disegnato via canvas, in pixel art originale. +I bersagli della mano sono 84×120 pixel a 640×360. Dorso con serpentello coronato e cornice +simmetrica; tavolino di legno e panno, mano avversaria coperta, mazzo e mucchietti delle prese. + +Sprite generato con lo **strumento immagini integrato**, poi preparato con +`slice_sprites.py --alpha --fixed-grid --cols 2 --rows 2` e `prepare_character.py`. +Pose: `sit`, `talk`, `laugh`, `shuffle`. Foglio originale in +`assets/raw/giocatore-carte-sheet.png`; prompt completo in +`prompts/personaggi/giocatore-carte-sheet.txt` (entrambi esclusi da git). + +Effetti Web Audio `card-slide`, `card-tap`, `card-shuffle`, collegati allo stesso volume, +muto e pausa degli altri effetti. Il colpo accompagna l’arrivo della carta dopo lo scorrimento. +13 nuove battute XTTS (4 Andrea, 9 giocatore), con indice e durate aggiornati. +Per generarle senza GPU/rete, `tools/voci_xtts.py` accetta `XTTS_DEVICE=cpu` e +`XTTS_MODEL_DIR` con la cartella del modello già scaricato; le impostazioni predefinite +rimangono quelle del progetto. Non è stata verificata all’ascolto la pronuncia delle nuove voci. + +## Verifica e limiti della sessione + +**`npm test`: passato.** Regole, determinismo, conservazione delle 40 carte e dei 120 punti, +pescata, ultima briscola, fine mazzo, patta, livelli, accesso negato ai dati nascosti, +minimax confrontato con un oracolo esaustivo, renderer puro, input geometrico, +dialoghi/flag/rivincita e audio. Passano anche i test precedenti e la soluzione completa. + +`npm run browser` e `npm run browser:briscola` sono stati lanciati ma **bloccati dall’ambiente**: +`PermissionError: [Errno 1] Operation not permitted` alla creazione del socket del server. +Anche l’avvio isolato di Chromium fallisce con `sandbox_host_linux.cc:41`, +`shutdown: Operation not permitted`. Non è stato possibile verificare l’interfaccia reale +con Playwright né produrre schermate desktop/telefono. + +Il test `tests/briscola.browser.mjs` è pronto: partite complete con mouse, touch e tastiera +su desktop e telefono verticale, più touch orizzontale; pausa, muto, gesto annullato, +conteggio, risultato e rivincita. Accelera solo le attese tramite `game.update`, senza +giocare carte di Andrea direttamente nel motore. Salva in `/tmp/regolo-shots/briscola-*.png`. +Le misure Web Audio dei tre nuovi suoni sono comprese nel collaudo browser multimedia. + +Anteprime **offline, non schermate browser**, prodotte e ispezionate nella sessione: + +- `/tmp/regolo-shots/briscola-offline-carte.png` +- `/tmp/regolo-shots/briscola-offline-tavolo.png` +- `/tmp/regolo-shots/briscola-offline-risultato.png` + +## File + +Nuovi: `src/engine/briscola.js`, `src/engine/briscola-render.js`, +`assets/characters/giocatore-carte.png`, `assets/characters/giocatore-carte.json`, +`tests/briscola.test.mjs`, `tests/briscola-render.test.mjs`, `tests/briscola.browser.mjs`, +`tools/calibrate_briscola.mjs`, questo documento e 13 MP3 elencati qui sotto. + +Modificati: `src/engine/game.js`, `src/engine/render.js`, `src/engine/soundscape.js`, +`src/main.js`, `src/story/story.js`, `index.html`, `style.css`, `package.json`, +`tests/story.test.mjs`, `tests/multimedia.test.mjs`, `tests/multimedia.browser.mjs`, +`tools/voci.json`, `tools/voci_xtts.py`, `assets/voices/index.json`. + +Nuovi file in `assets/voices/`: + +```text +andrea-6e63dafda1.mp3 +andrea-71f3bff8a0.mp3 +andrea-b851b9ed26.mp3 +andrea-d2f285f610.mp3 +giocatore_carte-12f97003ec.mp3 +giocatore_carte-13af2e2331.mp3 +giocatore_carte-43e76cf11b.mp3 +giocatore_carte-6ce98bce81.mp3 +giocatore_carte-729b3344da.mp3 +giocatore_carte-8dfadb4acc.mp3 +giocatore_carte-9c07caaab4.mp3 +giocatore_carte-a8846bfa7b.mp3 +giocatore_carte-f1f219bd1c.mp3 +``` + +`docs/STATO.md` invariato. Nessun commit, tag o push. diff --git a/docs/STATO.md b/docs/STATO.md index 905472d..84b7b37 100644 --- a/docs/STATO.md +++ b/docs/STATO.md @@ -18,6 +18,13 @@ Online su 50037.manzolo.it tutto fino agli effetti ambientali di Codex. Aperto, ## Dove siamo arrivati +- **Briscola all'oratorio (26 ottobre)**: alle tavolate siede «Il giocatore di carte» (segnaposto, [DA ANDREA: chi è], + sprite e battute provvisorie di Codex). Parlandoci si sceglie il mazzo (toscane o napoletane) e il livello + («Alla bona», «Seria», «A fassi male»), poi briscola a due fedele alle regole, conteggio delle prese a fine + partita e rivincita. Facoltativa: nessun flag serve alla soluzione. Motore `src/engine/briscola.js` (Claude), + disegno `briscola-render.js` (Codex), dettagli e taratura in `docs/BRISCOLA.md`. Prova: `npm run browser:briscola`. + Prossimo: il **tressette a coppie «ai 21»** con busso, striscio e volo (da chiedere ad Andrea: le accuse?). + - **Multimedia (25 ottobre, modifiche locali)**: il libro sfogliabile già presente conserva immagini, battute e riapertura dall'inventario; il fruscio ora segue il volume degli effetti, non quello delle voci. Nuovi paesaggi sonori sintetizzati con Web Audio (`src/engine/soundscape.js`, profili in diff --git a/index.html b/index.html index 171af9f..8710606 100644 --- a/index.html +++ b/index.html @@ -103,6 +103,24 @@
+