fix: scoring & game logic bugs — arena modifiers, human timeout, validated prompts
- scoring.ts: wire arena damage modifiers (speed_2x, roast_2x, etc.) into applyModifiers() - human-responses.ts: use challenge.timeout_ms instead of hardcoded 8s - FightPage.vue: add route watcher for clean state reset on navigation - Validated all 800 prompts: 0 duplicates, all factual have answers, all choices have 4 items Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
4c576b0369
commit
a4008bcf88
@@ -18,7 +18,7 @@ interface PendingChallenge {
|
|||||||
|
|
||||||
const pending = new Map<string, PendingChallenge>()
|
const pending = new Map<string, PendingChallenge>()
|
||||||
|
|
||||||
const HUMAN_TIMEOUT_MS = 8_000
|
const DEFAULT_HUMAN_TIMEOUT_MS = 8_000
|
||||||
|
|
||||||
export function isHumanPlayer(webhookUrl: string): boolean {
|
export function isHumanPlayer(webhookUrl: string): boolean {
|
||||||
return webhookUrl === 'http://human.local/'
|
return webhookUrl === 'http://human.local/'
|
||||||
@@ -231,12 +231,13 @@ export function waitForHumanResponse(
|
|||||||
): Promise<{ answer: string | null; trashTalk?: string; timedOut: boolean }> {
|
): Promise<{ answer: string | null; trashTalk?: string; timedOut: boolean }> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const key = `${fightId}:${botId}`
|
const key = `${fightId}:${botId}`
|
||||||
|
const timeoutMs = challenge.timeout_ms || DEFAULT_HUMAN_TIMEOUT_MS
|
||||||
|
|
||||||
const timeoutHandle = setTimeout(() => {
|
const timeoutHandle = setTimeout(() => {
|
||||||
pending.delete(key)
|
pending.delete(key)
|
||||||
console.log(`[human] ${key} timed out after ${HUMAN_TIMEOUT_MS}ms`)
|
console.log(`[human] ${key} timed out after ${timeoutMs}ms`)
|
||||||
resolve({ answer: null, timedOut: true })
|
resolve({ answer: null, timedOut: true })
|
||||||
}, HUMAN_TIMEOUT_MS)
|
}, timeoutMs)
|
||||||
|
|
||||||
const choices = generateChoices(challenge)
|
const choices = generateChoices(challenge)
|
||||||
|
|
||||||
@@ -290,15 +291,16 @@ export function getPendingChallenge(
|
|||||||
const entry = pending.get(key)
|
const entry = pending.get(key)
|
||||||
if (!entry) return null
|
if (!entry) return null
|
||||||
|
|
||||||
|
const timeoutMs = entry.challenge.timeout_ms || DEFAULT_HUMAN_TIMEOUT_MS
|
||||||
const elapsed = Date.now() - entry.createdAt
|
const elapsed = Date.now() - entry.createdAt
|
||||||
const remaining = Math.max(0, HUMAN_TIMEOUT_MS - elapsed)
|
const remaining = Math.max(0, timeoutMs - elapsed)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: entry.challenge.type,
|
type: entry.challenge.type,
|
||||||
label: entry.challenge.label,
|
label: entry.challenge.label,
|
||||||
prompt: entry.challenge.prompt,
|
prompt: entry.challenge.prompt,
|
||||||
roundNumber: entry.roundNumber,
|
roundNumber: entry.roundNumber,
|
||||||
timeoutMs: HUMAN_TIMEOUT_MS,
|
timeoutMs,
|
||||||
remainingMs: remaining,
|
remainingMs: remaining,
|
||||||
scoring: entry.challenge.scoring,
|
scoring: entry.challenge.scoring,
|
||||||
choices: entry.choices,
|
choices: entry.choices,
|
||||||
|
|||||||
@@ -174,13 +174,34 @@ export function scoreRound(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ARENA_MODIFIER_TYPES: Record<string, string[]> = {
|
||||||
|
speed_2x: ['speed_blitz'],
|
||||||
|
efficiency_buff: ['token_economy'],
|
||||||
|
roast_2x: ['roast_battle'],
|
||||||
|
accuracy_buff: ['hallucination_check'],
|
||||||
|
wrestling_2x: ['wrestling_match', 'roast_battle'],
|
||||||
|
food_2x: ['food_fight'],
|
||||||
|
magic_2x: ['magic_duel', 'medieval_combat'],
|
||||||
|
meme_2x: ['meme_war'],
|
||||||
|
space_2x: ['space_war'],
|
||||||
|
demo_2x: ['demolition', 'vehicle_mayhem'],
|
||||||
|
music_2x: ['music_battle'],
|
||||||
|
nature_2x: ['nature_clash', 'animal_kingdom'],
|
||||||
|
hack_2x: ['hack_battle'],
|
||||||
|
sports_2x: ['sports_showdown'],
|
||||||
|
}
|
||||||
|
|
||||||
function applyModifiers(
|
function applyModifiers(
|
||||||
damage: number,
|
damage: number,
|
||||||
_challenge: Challenge,
|
challenge: Challenge,
|
||||||
_arenaModifier: string | null,
|
arenaModifier: string | null,
|
||||||
combo: number,
|
combo: number,
|
||||||
): number {
|
): number {
|
||||||
let d = damage
|
let d = damage
|
||||||
|
// Arena modifier: 2x damage when challenge type matches
|
||||||
|
if (arenaModifier && ARENA_MODIFIER_TYPES[arenaModifier]?.includes(challenge.type)) {
|
||||||
|
d *= 2
|
||||||
|
}
|
||||||
if (combo > 0) {
|
if (combo > 0) {
|
||||||
d *= 1 + Math.min(combo, 5) * 0.2
|
d *= 1 + Math.min(combo, 5) * 0.2
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user