hgbot/src/lib/game.ts
2023-03-22 16:57:39 -05:00

100 lines
2.0 KiB
TypeScript

import { Embed, MessageCreateOptions, MessagePayload, MessagePayloadOption } from "discord.js"
export interface MessageSink {
SendMessage(v:MessageCreateOptions):Promise<void>
}
export const ConsoleMessageSink: MessageSink = {
async SendMessage(v) {
console.log(v)
},
}
export interface RandomSource {
Range(start:number, stop:number):number
}
export const DefaultRandom:RandomSource = {
Range(start, stop) {
const ans = (stop - start) * Math.random() + start
return ans
}
}
export interface ActionFactory {
next(game: Game): Action
}
// an action is in charge of the entire state transition
export interface Action {
Before?(game:Game):MessageCreateOptions[]
Play?(game:Game):MessageCreateOptions[]
After?(game:Game):MessageCreateOptions[]
}
export const PlayActions = async (game:Game, actions:Action[]) => {
for(let i = 0; i < actions.length; i++) {
const a = actions[i];
[a.Before,a.Play,a.After].forEach(async (x)=>{
if(x){
const msgs = x(game)
msgs.forEach(async (msg)=>{
await game.sink.SendMessage(msg).catch(console.log)
})
}
});
}
}
// track game state
export class Game {
// players in the game
players: {[index: string]:Player}
rng: RandomSource
sink:MessageSink
constructor() {
this.players = {}
this.rng = DefaultRandom
this.sink = ConsoleMessageSink
}
}
// player class tracks a players stats through out the game
export class Player {
// display name of character
name: string
// if health reaches 0 ur dead
health: number
// chance you are selected for combat
visibility: number
// chance you will win your next combat
power: number
constructor(name:string) {
this.health = 100
this.visibility = 50
this.power = 50
this.name = name
}
// bool is whether or not player is dead after damage
damage(v:number):boolean{
this.health = this.health - v
if(this.health <= 0) {
this.health = 0
return true
}
return false
}
alive() {
return this.health > 0
}
}