Spaces:
Sleeping
Sleeping
import { v, Infer, ObjectType } from 'convex/values'; | |
import { Game } from './game'; | |
import { | |
DAY_DURATION, | |
NIGHT_DURATION, | |
WWOLF_VOTE_DURATION, | |
PLAYER_KILL_VOTE_DURATION, | |
LLM_VOTE_DURATION, | |
} from '../constants'; | |
import { processVotes } from './voting'; | |
type CycleState = 'Day' | 'Night' | 'WerewolfVoting' | 'PlayerKillVoting' | 'LLMsVoting' | 'LobbyState' | |
const stateDurations: { [key in CycleState]: number } = { | |
Day: DAY_DURATION, | |
Night: NIGHT_DURATION, | |
WerewolfVoting: WWOLF_VOTE_DURATION, | |
PlayerKillVoting: PLAYER_KILL_VOTE_DURATION, | |
LLMsVoting: LLM_VOTE_DURATION, | |
LobbyState: Infinity | |
}; | |
const normalCycle: CycleState[] = [ | |
'Day', | |
'Night', | |
'WerewolfVoting', | |
'PlayerKillVoting', | |
]; | |
export const gameCycleSchema = { | |
currentTime: v.number(), | |
cycleState: v.union( | |
v.literal('Day'), | |
v.literal('Night'), | |
v.literal('WerewolfVoting'), | |
v.literal('PlayerKillVoting'), | |
v.literal('LLMsVoting'), | |
v.literal('LobbyState'), | |
), | |
cycleIndex: v.number(), | |
}; | |
export type SerializedGameCycle = ObjectType<typeof gameCycleSchema>; | |
const onStateChange = (prevState: CycleState, newState: CycleState, game: Game, now: number) => { | |
console.log(`state changed: ${ prevState } -> ${ newState }`); | |
if (prevState === 'PlayerKillVoting') { | |
const mostVotedPlayer = processVotes(game.world.votes, [...game.world.players.values()])[0]; | |
// TODO: Kill the player | |
const playerToKill = game.world.players.get(mostVotedPlayer) | |
if (playerToKill != undefined) { | |
playerToKill.kill(game, now) | |
} | |
} | |
if (prevState === 'WerewolfVoting') { | |
const mostVotedPlayer = processVotes(game.world.votes, [...game.world.players.values()])[0]; | |
// TODO: Check if most voted player is werewolf | |
} | |
// TODO: Implement LLM voting | |
}; | |
export class GameCycle { | |
currentTime: number; | |
cycleState: CycleState; | |
cycleIndex: number; | |
constructor(serialized: SerializedGameCycle) { | |
const { currentTime, cycleState, cycleIndex } = serialized; | |
this.currentTime = currentTime; | |
this.cycleState = cycleState; | |
this.cycleIndex = cycleIndex; | |
} | |
// Tick method to increment the counter | |
tick(game: Game, tickDuration: number) { | |
this.currentTime += tickDuration; | |
if (this.currentTime >= stateDurations[this.cycleState]) { | |
const prevState = this.cycleState; | |
this.currentTime = 0; | |
this.cycleIndex = (this.cycleIndex + 1) % normalCycle.length; | |
this.cycleState = normalCycle[this.cycleIndex]; | |
onStateChange(prevState, this.cycleState, game, tickDuration); | |
} | |
} | |
serialize(): SerializedGameCycle { | |
const { currentTime, cycleState, cycleIndex } = this; | |
return { | |
currentTime, | |
cycleState, | |
cycleIndex, | |
}; | |
} | |
} | |