UNPKG

utilitai

Version:

Utility AI library built with TypeScript

95 lines (80 loc) 2.74 kB
import type { AppraisalFunction, CurveFunction, Appraisal, Action, ScoringFunction, Consideration, Reasoner, Context } from "../types"; /** * This was a PoC for utility theory as a factory function and contains some of the early ideas. It will eventually be removed. */ enum ActionName { Idle, Attack, Flee } // Helper functions export const createAppraisal = ( fn: AppraisalFunction, computeCurve?: CurveFunction, ): Appraisal => ({ evaluate: fn, computeCurve: computeCurve || quadraticCurve, }); export const createConsideration = ( action: Action, appraisals: Appraisal[], scoringMethod: ScoringFunction, bonusFactor?: number, weight?: number, parameters?: Record<string, any>, ): Consideration => ({ action, appraisals, scoringMethod, bonusFactor: bonusFactor || 1, weight: weight || 1, parameters, }); export const createReasoner = (baseConsiderations: Consideration[]): Reasoner => { return { considerations: baseConsiderations, evaluate: (context: Context, dynamicConsiderations: Consideration[] = []) => { let bestScore = -Infinity; let bestAction: Action | null = null; for (const consideration of [ ...baseConsiderations, ...dynamicConsiderations ]) { if (consideration.weight <= 0) continue; const scores = [] as number[]; for (const appraisal of consideration.appraisals) { const score = appraisal.evaluate({ ...context, ...consideration.parameters }); if (score === 0) continue; scores.push(score); } const score = consideration.scoringMethod(scores) * consideration.weight; if (score > bestScore) { bestScore = score; bestAction = consideration.action; } } return bestAction || { name: ActionName.Idle }; }, } }; /* const ScoreAllConsiderations = (considerations: Consideration[], context: Context) => { let cutoff = 0; for (const consideration of considerations) { const bonus = consideration.bonusFactor; if (bonus < cutoff) continue; } } */ // Example scoring methods export const averageScoring: ScoringFunction = (scores) => scores.reduce((sum, score) => sum + score, 0) / scores.length; export const multiplicativeScoring: ScoringFunction = (scores) => scores.reduce((product, score) => product * score, 1); // Example curve functions export const linearCurve: CurveFunction = (score) => score; export const quadraticCurve: CurveFunction = (score) => score * score; export const inverseQuadraticCurve: CurveFunction = (score) => 1 - score * score;