瀏覽代碼

Make DeciderAI the only kind of AI; remove AI pickers

vintage
Fen Dweller 5 年之前
父節點
當前提交
edc918db44
共有 6 個檔案被更改,包括 9 行新增43 行删除
  1. +1
    -1
      src/components/Combat.vue
  2. +1
    -9
      src/components/Statblock.vue
  3. +2
    -29
      src/game/ai.ts
  4. +2
    -2
      src/game/creature.ts
  5. +1
    -0
      src/game/creatures/werewolf.ts
  6. +2
    -2
      src/game/maps/town.ts

+ 1
- 1
src/components/Combat.vue 查看文件

@@ -210,7 +210,7 @@ export default class Combat extends Vue {
} }
}) })


if (!(this.encounter.currentMove.ai instanceof NoAI)) {
if (!(this.encounter.currentMove.ai === null)) {
if (this.encounter.currentMove.side === Side.Heroes) { if (this.encounter.currentMove.side === Side.Heroes) {
this.executedLeft(this.encounter.currentMove.ai.decide(this.encounter.currentMove, this.encounter)) this.executedLeft(this.encounter.currentMove.ai.decide(this.encounter.currentMove, this.encounter))
} else { } else {


+ 1
- 9
src/components/Statblock.vue 查看文件

@@ -60,9 +60,6 @@
<button v-if="subject.perspective === POV.Third" @click.stop="subject.perspective = POV.Second">Second-person</button> <button v-if="subject.perspective === POV.Third" @click.stop="subject.perspective = POV.Second">Second-person</button>
<button v-if="subject.perspective === POV.First" @click.stop="subject.perspective = POV.Third">Third-person</button> <button v-if="subject.perspective === POV.First" @click.stop="subject.perspective = POV.Third">Third-person</button>
<button v-if="subject.perspective === POV.Second" @click.stop="subject.perspective = POV.First">First-person</button> <button v-if="subject.perspective === POV.Second" @click.stop="subject.perspective = POV.First">First-person</button>
<select @change="subject.ai = ais[$event.target.selectedIndex]" class="ai-picker">
<option v-for="(ai, index) in ais" :key="'ai-' + index">{{ ai.name }}</option>
</select>
</div> </div>
</div> </div>
</template> </template>
@@ -71,7 +68,6 @@
import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator' import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator'
import { Creature } from '@/game/creature' import { Creature } from '@/game/creature'
import { POV } from '@/game/language' import { POV } from '@/game/language'
import { NoAI, RandomAI, VoreAI, AI } from '@/game/ai'
import { Stats, Stat, StatIcons, StatDescs, Vigor, VigorIcons, VigorDescs, VoreStatDescs, VoreStatIcons, VisibleStatus } from '@/game/combat' import { Stats, Stat, StatIcons, StatDescs, Vigor, VigorIcons, VigorDescs, VoreStatDescs, VoreStatIcons, VisibleStatus } from '@/game/combat'
import ContainerView from './ContainerView.vue' import ContainerView from './ContainerView.vue'
import tippy, { delegate, createSingleton } from 'tippy.js' import tippy, { delegate, createSingleton } from 'tippy.js'
@@ -83,8 +79,7 @@ import 'tippy.js/dist/tippy.css'
}, },
data () { data () {
return { return {
POV: POV,
ais: [new NoAI(), new RandomAI(), new VoreAI()]
POV: POV
} }
}, },
methods: { methods: {
@@ -156,9 +151,6 @@ export default class Statblock extends Vue {
createSingleton(tippyInstances, { delay: 500, touch: ["hold", 500] }) createSingleton(tippyInstances, { delay: 500, touch: ["hold", 500] })


this.statusChanged([]) this.statusChanged([])

const picker = this.$el.querySelector(".ai-picker") as HTMLSelectElement
picker.selectedIndex = this.$data.ais.findIndex((ai: AI) => ai.name === this.subject.ai.name)
} }
} }
</script> </script>


+ 2
- 29
src/game/ai.ts 查看文件

@@ -6,18 +6,6 @@ import { NoPassDecider, NoReleaseDecider, ChanceDecider, ConsequenceDecider, Con
import { SurrenderEffect } from './combat/effects' import { SurrenderEffect } from './combat/effects'
import { StatusConsequence, DamageConsequence } from './combat/consequences' import { StatusConsequence, DamageConsequence } from './combat/consequences'


export interface AI {
name: string;
decide (actor: Creature, encounter: Encounter): LogEntry;
}

export class NoAI implements AI {
name = "No AI"
decide (actor: Creature, encounter: Encounter): LogEntry {
throw new Error("This AI cannot be used.")
}
}

/** /**
* A Decider determines how favorable an action is to perform. * A Decider determines how favorable an action is to perform.
*/ */
@@ -25,7 +13,7 @@ export interface Decider {
decide: (encounter: Encounter, user: Creature, target: Creature, action: Action) => number; decide: (encounter: Encounter, user: Creature, target: Creature, action: Action) => number;
} }


export class DeciderAI implements AI {
export class AI {
constructor (public name: string, private deciders: Decider[]) { constructor (public name: string, private deciders: Decider[]) {


} }
@@ -74,25 +62,10 @@ export class DeciderAI implements AI {
} }
} }


/**
* The RandomAI is **COMPLETELY** random. Good luck.
*/
export class RandomAI implements AI {
name = "Random AI"
decide (actor: Creature, encounter: Encounter): LogEntry {
const actions = encounter.combatants.flatMap(enemy => actor.validActions(enemy).map(action => ({
target: enemy,
action: action
})))
const chosen = actions[Math.floor(Math.random() * actions.length)]
return chosen.action.try(actor, chosen.target)
}
}

/** /**
* The VoreAI tries to eat opponents, but only if the odds are good enough * The VoreAI tries to eat opponents, but only if the odds are good enough
*/ */
export class VoreAI extends DeciderAI {
export class VoreAI extends AI {
constructor () { constructor () {
super( super(
"Vore AI", "Vore AI",


+ 2
- 2
src/game/creature.ts 查看文件

@@ -4,7 +4,7 @@ import { LogEntry, LogLines, LogLine } from './interface'
import { VoreContainer, VoreType, Container } from './vore' import { VoreContainer, VoreType, Container } from './vore'
import { Item, EquipmentSlot, Equipment, ItemKind, Currency } from './items' import { Item, EquipmentSlot, Equipment, ItemKind, Currency } from './items'
import { PassAction } from './combat/actions' import { PassAction } from './combat/actions'
import { AI, NoAI } from './ai'
import { AI } from './ai'
import { Mortal } from './entity' import { Mortal } from './entity'


export class Creature extends Mortal { export class Creature extends Mortal {
@@ -34,7 +34,7 @@ export class Creature extends Mortal {
side: Side; side: Side;
title = "Lv. 1 Creature"; title = "Lv. 1 Creature";
equipment: {[key in EquipmentSlot]?: Equipment } = {} equipment: {[key in EquipmentSlot]?: Equipment } = {}
ai: AI = new NoAI()
ai: AI|null = null


constructor (name: Noun, kind: Noun, pronouns: Pronoun, stats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, private baseMass: number) { constructor (name: Noun, kind: Noun, pronouns: Pronoun, stats: Stats, public preyPrefs: Set<VoreType>, public predPrefs: Set<VoreType>, private baseMass: number) {
super(name, kind, pronouns, stats) super(name, kind, pronouns, stats)


+ 1
- 0
src/game/creatures/werewolf.ts 查看文件

@@ -27,6 +27,7 @@ export class Werewolf extends Creature {
) )


this.ai = new VoreAI() this.ai = new VoreAI()

this.side = Side.Monsters this.side = Side.Monsters


const stomach = new Stomach(this, 2, new ConstantDamageFormula(new Damage( const stomach = new Stomach(this, 2, new ConstantDamageFormula(new Damage(


+ 2
- 2
src/game/maps/town.ts 查看文件

@@ -8,7 +8,7 @@ import { Creature } from '../creature'
import { DevourAction } from '../combat/actions' import { DevourAction } from '../combat/actions'
import { SurrenderEffect } from '../combat/effects' import { SurrenderEffect } from '../combat/effects'
import moment from 'moment' import moment from 'moment'
import { RandomAI, VoreAI } from '../ai'
import { VoreAI } from '../ai'


function makeParty (): Creature[] { function makeParty (): Creature[] {
const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, { const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, {
@@ -244,7 +244,7 @@ export const Town = (): Place => {
(world, executor) => { (world, executor) => {
const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns) const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns)
enemy.side = Side.Monsters enemy.side = Side.Monsters
enemy.ai = new RandomAI()
enemy.ai = new VoreAI()
const encounter = new Encounter( const encounter = new Encounter(
{ {
name: "Fight some nerd", name: "Fight some nerd",


Loading…
取消
儲存