Difficoltà alle bocce e al biliardo, scelta nel dialogo con l'avversario: «Alla bona», «Seria», «A fassi male». Tarata con partite simulate contro un giocatore attento: al biliardo vince 9 su 12, circa 4 su 10 e quasi mai; alle bocce 72%, 50% e 35% delle mani. Battute nuove per Mariano e l'Ingegnere, test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ks2K99uqCZjAxvy7Rdj1R
This commit is contained in:
2026-10-25 23:46:46 +01:00
co-authored by Claude Opus 5.5
parent bd66ea45ad
commit 94e9da4009
25 changed files with 136 additions and 34 deletions
+14 -5
View File
@@ -19,8 +19,16 @@ export const powerFor = distance => clamp((distance - 8) / 96, 0, 1);
export const moving = c => [c.jack, ...c.balls].some(b => Math.hypot(b.vu, b.vw) > EPS);
export const closest = (c, who) => c.balls.filter(b => b.who === who).sort((a, b) => gap(a, c.jack) - gap(b, c.jack))[0];
export function newBocce(seed = Date.now() >>> 0) {
const c = { step: 'aim', t: 0, age: 0, seed, balls: [], turn: 0, current: 'player', power: 0.5,
// Quanto è bravo Mariano: quanto si allarga il suo tiro e quanto spesso prova a bocciare la boccia migliore.
// «A fassi male» è il campione vero del pallaio.
export const LEVELS = {
bona: { spread: 3, attack: 0.1 },
seria: { spread: 1.15, attack: 0.4 },
male: { spread: 0.22, attack: 0.85 },
};
export function newBocce(seed = Date.now() >>> 0, def = {}) {
const level = LEVELS[def.level] ? def.level : 'seria';
const c = { step: 'aim', t: 0, age: 0, seed, level, skill: LEVELS[level], balls: [], turn: 0, current: 'player', power: 0.5,
holding: false, holdTime: 0, accumulator: 0, events: [], trails: [], travel: 0, lastThrower: null };
c.jack = { u: 45 + random(c) * 18, w: (random(c) - 0.5) * 5, vu: 0, vw: 0, r: JACK, mass: 0.1, jack: true, spin: 0 };
c.aim = { u: c.jack.u, w: c.jack.w };
@@ -134,10 +142,11 @@ function nextTurn(c) {
function cpuThrow(c) {
// Mariano cerca un accosto libero; con un avversario attaccato al pallino può
// tentare di spostarlo. Usa gli stessi lanci e la stessa fisica del giocatore.
const other = closest(c, 'player'), attack = other && gap(other, c.jack) < 0.6 && random(c) < 0.45;
const k = c.skill ?? LEVELS.male;
const other = closest(c, 'player'), attack = other && gap(other, c.jack) < 0.6 && random(c) < k.attack;
const target = attack ? other : c.jack;
const u = clamp(target.u + deviation(c) * (attack ? 0.5 : 2.2), 10, LANE - 2);
const w = clamp(target.w + deviation(c) * (attack ? 0.18 : 0.8), -HALF + BALL, HALF - BALL);
const u = clamp(target.u + deviation(c) * (attack ? 0.5 : 2.2) * k.spread, 10, LANE - 2);
const w = clamp(target.w + deviation(c) * (attack ? 0.18 : 0.8) * k.spread, -HALF + BALL, HALF - BALL);
launch(c, 'cpu', u, w, Math.hypot(u, w) + (attack ? 14 : -0.35));
}
export function update(c, dt) {