basic brain

This commit is contained in:
2026-03-30 16:31:19 +02:00
parent d2435eee7f
commit 3faab5e206
8 changed files with 179 additions and 95 deletions

View File

@@ -1,23 +1,9 @@
import { Chibi } from "../../../types/chibi/chibi";
import { EChibiInteraction } from "../../../types/chibi/chibi-interaction";
import { ChibiState, isState, STATE_AWAKE, STATE_EATING, STATE_GRUMBLING, STATE_IDLE, STATE_SLEEPING, STATES } from "../../../types/chibi/chibi-state";
import { ChibiState, STATE_AWAKE, STATE_EATING, STATE_GRUMBLING, STATE_IDLE, STATE_SLEEPING } from "../../../types/chibi/chibi-state";
import { EChibiStateName } from "../../../types/chibi/chibi-state-name";
import { Food } from "../../../types/food";
import { RandomOutcome, RandomService } from "../../random.service";
import { IBrain } from "../brain";
export type InteractionMap = { [key in EChibiStateName]: InteractionRecord | undefined }
export type ChibiInteraction<T = null> = {
name: EChibiInteraction;
payload: T;
}
type InteractionResolutionFunction = (interaction: ChibiInteraction<any>) => ChibiState;
type InteractionRecord = Partial<Record<EChibiInteraction, InteractionResolutionFunction>>;
type ResolutionFunction = () => ChibiState | undefined;
type ResolutionMap = { [key in EChibiStateName]: ResolutionFunction | undefined }
import { RandomOutcome, } from "../../random.service";
import { BasicBrain, ChibiInteraction, InteractionMap, ResolutionMap } from "../basic.brain";
const MAX_TIME_AWAKE: number = 10;
@@ -27,21 +13,12 @@ const SADNESS_FROM_NEGLECT: number = 50;
const MAX_DURATION_GRUMBLE: number = 1;
const MAX_DURATION_EATING: number = 1;
export class Aperio implements IBrain {
export class Aperio extends BasicBrain {
private randomService!: RandomService;
private chibi!: Chibi;
private readonly defaultState: EChibiStateName = EChibiStateName.Sleeping;
private previousState: EChibiStateName = this.defaultState;
private hasBeenAwakeFor: number = 0;
private timeSinceLastInteraction: number = 0;
private timeInCurrentState: number = 0;
private lastConsumedFoods: string[] = [];
private preferredFoods: string[] = [];
private interactionMap: InteractionMap = {
protected override interactionMap: InteractionMap = {
[EChibiStateName.Sleeping]: {
[EChibiInteraction.WakeUp]: (interaction: ChibiInteraction): ChibiState => this.wakeUp(interaction),
},
@@ -60,7 +37,7 @@ export class Aperio implements IBrain {
[EChibiStateName.Depressed]: undefined,
[EChibiStateName.Tired]: undefined
}
private resolutionMap: ResolutionMap = {
protected override resolutionMap: ResolutionMap = {
[EChibiStateName.Sleeping]: (): ChibiState | undefined => this.resolveSleeping(),
[EChibiStateName.Awake]: (): ChibiState | undefined => this.resolveAwake(),
[EChibiStateName.Snoring]: undefined,
@@ -76,62 +53,6 @@ export class Aperio implements IBrain {
[EChibiStateName.Tired]: undefined
}
get state(): ChibiState {
return STATES[this.chibi.currentStateName];
}
init(chibi: Chibi, randomService: RandomService): void {
this.randomService = randomService;
this.chibi = chibi;
}
exist(): void {
this.timeInCurrentState++;
const resolution = this.matchResolution(this.resolutionMap, STATES[this.chibi.currentStateName]);
if (resolution) {
const newState = resolution();
if (newState && newState != STATES[this.chibi.currentStateName]) {
this.changeState(newState);
}
}
}
resolveInteraction(interaction: ChibiInteraction): void {
this.timeSinceLastInteraction = 0;
const resolution = this.matchInteraction(this.interactionMap, interaction.name, STATES[this.chibi.currentStateName]);
console.log('resolution', resolution);
console.log(`${this.chibi.name} should ${interaction.name} with payload: ${interaction.payload}`);
if (resolution) {
this.changeState(resolution(interaction));
}
}
isAwake(): boolean {
return isState(this.state, EChibiStateName.Awake);
}
matchInteraction(map: InteractionMap, interaction: EChibiInteraction, state: ChibiState): InteractionResolutionFunction | undefined {
const directMatch = map?.[state.name]?.[interaction];
if (directMatch) {
return directMatch;
}
if (state.parent) {
return this.matchInteraction(map, interaction, state.parent);
}
return undefined;
}
matchResolution(map: ResolutionMap, state: ChibiState): ResolutionFunction | undefined {
const directMatch = map?.[state.name];
if (directMatch) {
return directMatch;
}
if (state.parent) {
return this.matchResolution(map, state.parent);
}
return undefined;
}
// resolvers
// functions which automatically resolve based on the existence cycle
@@ -189,12 +110,6 @@ export class Aperio implements IBrain {
this.chibi.happyness.current = this.chibi.happyness.current - (neglectTime * sadness);
}
private changeState(state: ChibiState): void {
this.previousState = this.state.name;
this.chibi.currentStateName = state.name;
this.timeInCurrentState = 0;
}
/*
visiting caethya will wake her up and go into lovey-dovey mode