Il flipper coi due ponti (le rampe che si incrociano sopra la tavola, i PONTI se fatti di fila), i punti ×10 come sui flipper degli anni 2000, il tabellone a punti luminosi con le cifre che corrono e le scritte che lampeggiano, e un clic sul River che entra e va al flipper (Andrea)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GiECd9RWGMKV7n3K1mdy8T
This commit is contained in:
+26
-7
@@ -55,11 +55,11 @@ test('la pallina persa: tre palline, poi il risultato; il salvataggio vale una v
|
||||
put(c, { x: 320, y: 320, vx: 0, vy: 200 }); run(c, 1);
|
||||
}
|
||||
assert.equal(c.step, 'result'); assert.equal(c.result.winner, 'cpu'); assert.ok(!m.canThrow(c));
|
||||
assert.match(m.status(c), /Ne servivano 10000/);
|
||||
assert.match(m.status(c), /Ne servivano 120000/);
|
||||
const d = m.newFlipper(5, { level: 'bona' });
|
||||
m.launch(d, 0.9); assert.ok(m.saveLeft(d) > 7); put(d, { x: 320, y: 320, vx: 0, vy: 200 }); run(d, 1);
|
||||
assert.ok(m.waiting(d) && d.balls === 3, 'salvata: la pallina torna sulla molla');
|
||||
assert.match(d.line ?? '', /salvata/);
|
||||
assert.match(d.line ?? '', /SALVATA/);
|
||||
m.launch(d, 0.9); assert.equal(m.saveLeft(d), 0); put(d, { x: 320, y: 320, vx: 0, vy: 200 }); run(d, 1);
|
||||
assert.equal(d.balls, 2, 'la seconda volta è persa davvero');
|
||||
// Lo stesso quarto di secondo, a passi piccoli o in un fotogramma solo: stesso esito (Codex).
|
||||
@@ -139,7 +139,7 @@ test('comandi: la molla si carica e si lancia lasciando; annullare non lancia; d
|
||||
// Spazio: carica e lancia; Invio: lancia con la forza del cursore; a partita finita i tasti non sono suoi.
|
||||
const d = m.newFlipper(9); assert.ok(m.key(d, ' ', true)); run(d, 0.3); assert.ok(d.holding); m.key(d, ' ', false); assert.ok(!m.waiting(d));
|
||||
const e = m.newFlipper(10); assert.ok(m.setPower(e, 0.5)); assert.equal(m.button(e), 'Lancia'); m.key(e, 'Enter', true); assert.ok(!m.waiting(e)); assert.equal(m.button(e), 'In gioco…');
|
||||
e.step = 'result'; e.result = { winner: 'cpu', score: 0, goal: 10000 }; assert.ok(!m.key(e, ' ', true) && !m.key(e, 'Enter', true));
|
||||
e.step = 'result'; e.result = { winner: 'cpu', score: 0, goal: 120000 }; assert.ok(!m.key(e, ' ', true) && !m.key(e, 'Enter', true));
|
||||
});
|
||||
|
||||
test('il traguardo è acquisito appena raggiunto: anche uscendo prima, si vince; la trattenuta sul flipper non viene scossa', () => {
|
||||
@@ -149,7 +149,7 @@ test('il traguardo è acquisito appena raggiunto: anche uscendo prima, si vince;
|
||||
assert.match(m.status(c), /record/);
|
||||
const g = new Game(story); g.go('via_provinciale'); settle(g);
|
||||
g.act('use', 'river'); settle(g); g.choose(g.options().findIndex(o => o.text.startsWith('Una partita alla bona'))); settle(g);
|
||||
g.closeup.score = 7000; g.closeup.result = { winner: 'player', score: 7000, goal: 6000 };
|
||||
g.closeup.score = 70000; g.closeup.result = { winner: 'player', score: 70000, goal: 60000 };
|
||||
g.closeupClose(); settle(g);
|
||||
assert.ok(g.state.flags.flipper_vinto, 'uscito dopo il traguardo: vinto');
|
||||
// La pallina trattenuta sul flipper alzato resta lì (niente scossa): è una mossa del giocatore.
|
||||
@@ -158,6 +158,24 @@ test('il traguardo è acquisito appena raggiunto: anche uscendo prima, si vince;
|
||||
assert.ok(h.ball && !h.ball.waiting && h.ball.y > 280 && h.ball.x < 320, `ancora sul flipper (${h.ball?.x.toFixed(0)}, ${h.ball?.y.toFixed(0)})`);
|
||||
});
|
||||
|
||||
test('i ponti: imboccati forte si sale e si scende dall\'altra parte (e la pallina non urta la tavola sotto); piano si ricasca; tutti e due di fila, i PONTI', () => {
|
||||
const c = m.newFlipper(13, { level: 'bona' }); m.launch(c, 0.9); c.score = 0;
|
||||
put(c, { x: 247, y: 250, vx: 0, vy: -420 });
|
||||
let onRamp = 0, top = 999; for (let i = 0; i < 150; i++) { m.update(c, 1 / 60); if (c.ball.ramp) { onRamp++; top = Math.min(top, c.ball.y); } }
|
||||
assert.ok(onRamp > 20, 'è salita sul ponte'); assert.ok(top < 50, 'fin sopra la tavola');
|
||||
assert.ok(!c.ball.ramp && c.ball.x > 380, `scesa dall'altra parte (${c.ball.x.toFixed(0)}, ${c.ball.y.toFixed(0)})`);
|
||||
assert.equal(c.score, m.SCORE.ramp); assert.match(c.line, /PONTE SINISTRO/); assert.ok(c.ramps[0].lit > 0);
|
||||
assert.ok(c.events.some(e => e.kind === 'flipper-rampa'));
|
||||
// Il secondo ponte subito dopo: i PONTI.
|
||||
put(c, { x: 393, y: 250, vx: 0, vy: -420, ramp: null }); run(c, 2.5);
|
||||
assert.equal(c.score, 3 * m.SCORE.ramp - m.SCORE.ramp + m.SCORE.ponti, `i ponti (${c.score})`); assert.match(c.line ?? '', /PONTI/);
|
||||
// Troppo piano: non ci arriva, ricasca dall'imbocco senza punti.
|
||||
const d = m.newFlipper(14, { level: 'bona' }); m.launch(d, 0.9); d.score = 0;
|
||||
put(d, { x: 247, y: 250, vx: 0, vy: -300 }); let climbed = false; for (let i = 0; i < 90; i++) { m.update(d, 1 / 60); if (d.ball.ramp) climbed = true; }
|
||||
assert.ok(!d.ball.ramp && d.ball.y > 236, 'ricaduta'); assert.equal(d.score % m.SCORE.ramp === 0 && d.score >= m.SCORE.ramp, false, 'niente punti del ponte');
|
||||
void climbed;
|
||||
});
|
||||
|
||||
test('giocando con attenzione, alla bona si arriva al traguardo; nessuna partita si incastra', () => {
|
||||
let won = 0;
|
||||
for (let seed = 1; seed <= 8; seed++) {
|
||||
@@ -177,13 +195,14 @@ test('il disegno del flipper non cambia lo stato', () => {
|
||||
draw(); assert.ok(calls.some(([op, img]) => op === 'drawImage' && img === bg));
|
||||
assert.ok(calls.some(([op, t]) => op === 'fillText' && t === 'FLIPPER DEL RIVER'));
|
||||
m.launch(c, 0.8); run(c, 1); calls.length = 0; draw();
|
||||
assert.ok(calls.some(([op, t]) => op === 'fillText' && /^SALVATA \d s$/.test(t)), 'il salvataggio si vede');
|
||||
c.step = 'result'; c.result = { winner: 'player', score: 7000, goal: 6000 }; calls.length = 0; draw();
|
||||
assert.ok(calls.filter(([op]) => op === 'fillRect').length > 300, 'il tabellone a punti luminosi');
|
||||
c.step = 'result'; c.result = { winner: 'player', score: 70000, goal: 60000 }; calls.length = 0; draw();
|
||||
assert.ok(calls.some(([op, t]) => op === 'fillText' && t === 'TRAGUARDO FATTO!'));
|
||||
});
|
||||
|
||||
test('al River: «Usa» o «Apri» il bar, il livello, la partita; uscendo senza traguardo, la battuta di chi lascia', () => {
|
||||
test('al River: un clic sul bar (o «Usa», «Apri»), il livello, la partita; uscendo senza traguardo, la battuta di chi lascia', () => {
|
||||
const g = new Game(story); g.go('via_provinciale'); settle(g);
|
||||
assert.equal(g.hotspot('river').default, 'open');
|
||||
g.act('use', 'river'); settle(g);
|
||||
assert.ok(g.options().some(o => o.text === 'Una partita seria.'));
|
||||
g.choose(g.options().findIndex(o => o.text === 'Una partita seria.')); settle(g);
|
||||
|
||||
Reference in New Issue
Block a user