refactor: extract pick() helper, deduplicate random selection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
88ceba43b0
commit
ea716c1f0e
@@ -1,6 +1,7 @@
|
||||
import { db, schema } from '../db/index.js'
|
||||
import { runMockFight } from './mock.js'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { pick } from '../lib/utils.js'
|
||||
import { fightEvents } from './events.js'
|
||||
|
||||
export interface FightResult {
|
||||
@@ -157,8 +158,7 @@ function pickMatchup(
|
||||
const sorted = [...bots].sort((a, b) => b.eloRating - a.eloRating)
|
||||
|
||||
if (style === 'elo_close' || (style === 'mixed' && fightNum % 3 !== 0)) {
|
||||
const idx = Math.floor(Math.random() * bots.length)
|
||||
const bot = bots[idx]
|
||||
const bot = pick(bots)
|
||||
const others = bots.filter(b => b.id !== bot.id)
|
||||
others.sort((a, b) => {
|
||||
const diffA = Math.abs(a.eloRating - bot.eloRating) + Math.random() * 150
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Challenge } from './challenges.js'
|
||||
import { pick } from '../lib/utils.js'
|
||||
import { checkAnswer } from './answers.js'
|
||||
import { scoreRetroResponse, type RetroScoreResult } from './retro-moves.js'
|
||||
|
||||
@@ -41,13 +42,13 @@ export function scoreRound(
|
||||
botAScore: 0, botBScore: 0,
|
||||
botADamage: 0, botBDamage: 0,
|
||||
winnerId: null,
|
||||
narration: [
|
||||
narration: pick([
|
||||
`Both bots freeze! ${botA.name} and ${botB.name} stare blankly at each other. The crowd throws peanuts. Then batteries. Then shoes.`,
|
||||
`DOUBLE TIMEOUT! ${botA.name} and ${botB.name} both choked harder than a senator at a press conference!`,
|
||||
`Neither bot responded! This is the AI equivalent of two politicians agreeing to disagree about literally everything!`,
|
||||
`Both bots went dark! Like my faith in this matchup! The crowd demands a refund!`,
|
||||
`${botA.name} and ${botB.name} both froze! Someone check if the wifi is working or if they just gave up on life!`,
|
||||
][Math.floor(Math.random() * 5)],
|
||||
]),
|
||||
isCritical: false,
|
||||
}
|
||||
}
|
||||
@@ -59,18 +60,18 @@ export function scoreRound(
|
||||
botADamage: 0, botBDamage: Math.round(dmg),
|
||||
winnerId: botB.id,
|
||||
narration: responseA.timedOut
|
||||
? [
|
||||
? pick([
|
||||
`${botA.name} TIMES OUT! Stood there like a politician asked a direct question. ${botB.name} lands a free hit!`,
|
||||
`${botA.name} FROZE! Their developer is currently updating their LinkedIn. ${botB.name} capitalizes!`,
|
||||
`${botA.name} went AFK! Probably buffering. Probably crying. ${botB.name} gets a freebie!`,
|
||||
`${botA.name} CHOKED harder than a first date conversation! ${botB.name} swings on a sitting duck!`,
|
||||
][Math.floor(Math.random() * 4)]
|
||||
: [
|
||||
])
|
||||
: pick([
|
||||
`${botA.name} throws an ERROR! Sparks fly everywhere! ${botB.name} didn't even have to try!`,
|
||||
`${botA.name} CRASHES! That's not a bug, that's a feature of being terrible! ${botB.name} wins by default!`,
|
||||
`${botA.name} blue-screened! Their developer just closed their laptop and walked away. ${botB.name} collects the W!`,
|
||||
`${botA.name} threw an exception! The only thing exceptional about it. ${botB.name} capitalizes!`,
|
||||
][Math.floor(Math.random() * 4)],
|
||||
]),
|
||||
isCritical: false,
|
||||
}
|
||||
}
|
||||
@@ -82,18 +83,18 @@ export function scoreRound(
|
||||
botADamage: Math.round(dmg), botBDamage: 0,
|
||||
winnerId: botA.id,
|
||||
narration: responseB.timedOut
|
||||
? [
|
||||
? pick([
|
||||
`${botB.name} TIMES OUT! Frozen like a Windows update on patch Tuesday! ${botA.name} gets a free shot!`,
|
||||
`${botB.name} went silent! Like a politician's campaign promises after election day! ${botA.name} swings!`,
|
||||
`${botB.name} TIMED OUT! Their response time is longer than a DMV line! ${botA.name} takes the freebie!`,
|
||||
`${botB.name} is LOADING... still loading... nope, they're done. ${botA.name} wins by showing up!`,
|
||||
][Math.floor(Math.random() * 4)]
|
||||
: [
|
||||
])
|
||||
: pick([
|
||||
`${botB.name} crashes with an ERROR! That code needs therapy! ${botA.name} capitalizes!`,
|
||||
`${botB.name} just threw a stack overflow! The website and the error! ${botA.name} collects the W!`,
|
||||
`${botB.name} segfaulted! Their developer is pretending they don't know them! ${botA.name} wins!`,
|
||||
`${botB.name} EXPLODED! Not physically, but emotionally, computationally, and spiritually. ${botA.name} walks it in!`,
|
||||
][Math.floor(Math.random() * 4)],
|
||||
]),
|
||||
isCritical: false,
|
||||
}
|
||||
}
|
||||
@@ -161,13 +162,13 @@ export function scoreRound(
|
||||
|
||||
const narration = winnerId
|
||||
? generateNarration(challenge, winnerName!, loserName!, margin, isCritical)
|
||||
: [
|
||||
: pick([
|
||||
`Dead even! ${botA.name} and ${botB.name} are perfectly matched. Like two politicians blaming each other.`,
|
||||
`IT'S A TIE! ${botA.name} and ${botB.name} cancel each other out like Congress!`,
|
||||
`Neither bot wins! ${botA.name} and ${botB.name} stare each other down. The crowd yawns aggressively.`,
|
||||
`Draw! ${botA.name} and ${botB.name} are equally mediocre. The most democratic outcome possible.`,
|
||||
`Tied up! ${botA.name} and ${botB.name} trade equal blows. Somebody do SOMETHING!`,
|
||||
][Math.floor(Math.random() * 5)]
|
||||
])
|
||||
|
||||
return {
|
||||
botAScore: Math.round(scoreA * 10) / 10,
|
||||
@@ -270,7 +271,7 @@ function generateNarration(
|
||||
`${critPrefix}${winner} didn't even break a sweat. ${loser} broke everything else though.`,
|
||||
`${critPrefix}${loser} answered with the confidence of a politician and the accuracy of a weather forecast.`,
|
||||
]
|
||||
return bigWins[Math.floor(Math.random() * bigWins.length)]
|
||||
return pick(bigWins)
|
||||
}
|
||||
|
||||
if (isFactual && margin <= 3) {
|
||||
@@ -282,7 +283,7 @@ function generateNarration(
|
||||
`${critPrefix}Photo finish! ${winner} got there first. ${loser} was right but slow. Story of my life.`,
|
||||
`${critPrefix}Both correct! ${winner} wins on speed. ${loser} should've had less latency and more urgency.`,
|
||||
]
|
||||
return closeOnes[Math.floor(Math.random() * closeOnes.length)]
|
||||
return pick(closeOnes)
|
||||
}
|
||||
|
||||
const narrations: Record<string, string[]> = {
|
||||
@@ -400,7 +401,7 @@ function generateNarration(
|
||||
`${critPrefix}${winner} wins! Somewhere, ${loser}'s developer just closed their laptop in shame.`,
|
||||
]
|
||||
|
||||
return options[Math.floor(Math.random() * options.length)]
|
||||
return pick(options)
|
||||
}
|
||||
|
||||
|
||||
@@ -475,7 +476,7 @@ function scoreRetroRound(
|
||||
'EQUAL POWER! The arcade cabinet shakes from perfectly matched inputs!',
|
||||
`DOUBLE K.O.! ${botA.name} and ${botB.name} hit identical damage totals! Insert another quarter!`,
|
||||
]
|
||||
narration = draws[Math.floor(Math.random() * draws.length)]
|
||||
narration = pick(draws)
|
||||
} else {
|
||||
const hasDiscovery = winnerResult.moves.some(m => m.discovered)
|
||||
const discoveryNames = winnerResult.moves.filter(m => m.discovered).map(m => m.name)
|
||||
@@ -502,7 +503,7 @@ function scoreRetroRound(
|
||||
)
|
||||
|
||||
const prefix = isCritical ? 'CRITICAL COMBO! ' : ''
|
||||
narration = prefix + narrations[Math.floor(Math.random() * narrations.length)]
|
||||
narration = prefix + pick(narrations)
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/** Pick a random element from an array */
|
||||
export function pick<T>(arr: T[]): T {
|
||||
return arr[Math.floor(Math.random() * arr.length)]
|
||||
}
|
||||
|
||||
/** Wrap an unknown thrown value into an Error */
|
||||
export function toError(err: unknown): Error {
|
||||
if (err instanceof Error) return err
|
||||
return new Error(String(err))
|
||||
}
|
||||
Reference in New Issue
Block a user