Skip to content

Commit

Permalink
refactor: preview agent
Browse files Browse the repository at this point in the history
  • Loading branch information
chase-moskal committed Aug 2, 2024
1 parent 7974db6 commit d656625
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 45 deletions.
26 changes: 18 additions & 8 deletions s/terminal/parts/planner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,39 @@ import {TransformNode} from "@babylonjs/core"

import {Assets} from "./assets.js"
import {Selectacon} from "./selectacon.js"
import {Agent} from "../../logic/agent.js"
import {Choice} from "../../logic/state.js"
import {PreviewAgent} from "./preview-agent.js"
import {Trashbin} from "../../tools/trashbin.js"
import {SubmitTurnFn} from "../../logic/arbiter.js"
import {Proposer} from "../../logic/simulation/proposer.js"

/** interface for the user to sketch a plan for their turn */
export class Planner {
#planbin = new Trashbin()
#renderbin = new Trashbin()

proposer: Proposer
choices: Choice.Any[] = []

constructor(private options: {
agent: Agent
assets: Assets
agent: PreviewAgent // uses a preview agent instead of just an agent
selectacon: Selectacon
submitTurn: SubmitTurnFn
}) {

this.proposer = new Proposer(options.agent)

this.#planbin.disposer(
options.selectacon.selection.on(() => this.render())
)
}

reset() {
this.proposer = new Proposer(this.options.agent)
this.choices = []
}

#spawn(fn: () => TransformNode, place: Vec2) {
const {agent} = this.options
const instance = fn()
Expand All @@ -37,8 +48,8 @@ export class Planner {

render() {
this.#renderbin.dispose()
const {proposer} = this
const {agent, selectacon, assets} = this.options
const {proposer} = agent
const selection = selectacon.selection.value

if (selection) {
Expand Down Expand Up @@ -75,20 +86,19 @@ export class Planner {
const {agent} = this.options
if (agent.conclusion)
return false
const fn = agent.proposer.choosers[choice.kind] as any
const fn = this.proposer.choosers[choice.kind] as any
const report = fn(choice)
if (report) {
agent.addChoice(choice)
this.choices.push(choice)
report.commit()
return true
}
return false
}

executePlan() {
const {agent, submitTurn} = this.options
submitTurn({choices: agent.choices})
agent.reset()
this.options.submitTurn({choices: this.choices})
this.reset()
}

dispose() {
Expand Down
31 changes: 7 additions & 24 deletions s/terminal/parts/preview-agent.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@

import {clone} from "@benev/slate"

import {ref} from "../../tools/ref.js"
import {Agent} from "../../logic/agent.js"
import {Choice} from "../../logic/state.js"
import {Proposer} from "../../logic/simulation/proposer.js"

/** helps us preview the effects of a proposed turn */
export class PreviewAgent extends Agent {
proposer: Proposer
readonly #choices = ref<Choice.Any[]>([])

constructor(public baseAgent: Agent) {
super(clone(baseAgent.state))
this.proposer = new Proposer(this)
}

reset() {
this.state = clone(this.baseAgent.state)
this.#choices.value = []
this.proposer = new Proposer(this)
}
export function setupPreviewAgent(baseAgent: Agent, onReset: () => void) {
const agent = new Agent(clone(baseAgent.state))
const dispose = baseAgent.stateRef.on(reset)

get choices() {
return this.#choices.value
function reset() {
agent.state = clone(baseAgent.state)
onReset()
}

addChoice(choice: Choice.Any) {
this.#choices.value = [...this.#choices.value, choice]
}
return {agent, reset, dispose}
}

12 changes: 7 additions & 5 deletions s/terminal/parts/user-inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {World} from "./world.js"
import {Planner} from "./planner.js"
import {CameraRig} from "./camera-rig.js"
import {Selectacon} from "./selectacon.js"
import {PreviewAgent} from "./preview-agent.js"
import {Agent} from "../../logic/agent.js"
import {Trashbin} from "../../tools/trashbin.js"
import {DragQueen} from "../../tools/drag-queen.js"
import {handlePrimaryClick} from "./handle-primary-click.js"
Expand All @@ -17,14 +17,15 @@ export class UserInputs {
dispose = this.#trashbin.dispose

constructor(private options: {
agent: PreviewAgent
agent: Agent
world: World
planner: Planner
cameraRig: CameraRig
selectacon: Selectacon
resetPreview: () => void
}) {

const {agent, planner, cameraRig} = options
const {planner, cameraRig, resetPreview} = options
const {canvas} = options.world
const dr = this.#trashbin.disposer

Expand All @@ -38,8 +39,9 @@ export class UserInputs {
// ctrl+z wipe turn plan
dr(ev(window, {
keydown: (event: KeyboardEvent) => {
if (event.code === "KeyZ" && event.ctrlKey)
agent.reset()
if (event.code === "KeyZ" && event.ctrlKey) {
resetPreview()
}
},
}))

Expand Down
22 changes: 14 additions & 8 deletions s/terminal/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,36 @@ import {Selectacon} from "./parts/selectacon.js"
import {SubmitTurnFn} from "../logic/arbiter.js"
import {UserInputs} from "./parts/user-inputs.js"
import {makeBasicVisuals} from "./parts/basics.js"
import {PreviewAgent} from "./parts/preview-agent.js"
import {setupPreviewAgent} from "./parts/preview-agent.js"

export async function makeGameTerminal(

// actual state from the arbiter
baseAgent: Agent,

// submit the player's turn to the arbiter
submitTurn: SubmitTurnFn,
) {

export async function makeGameTerminal(baseAgent: Agent, submitTurn: SubmitTurnFn) {
const trashbin = new Trashbin()
const d = trashbin.disposable
const dr = trashbin.disposer
const {dispose} = trashbin

const agent = new PreviewAgent(baseAgent)
dr(baseAgent.stateRef.on(() => agent.reset()))
const {agent, reset: resetPreview} = d(
setupPreviewAgent(baseAgent, () => planner.reset())
)

const {world, assets} = d(await makeBasicVisuals())
d(assets.board.border())

const cameraRig = d(new CameraRig({world}))
const tiler = d(new Tiler({agent, world, assets}))
const rosters = d(new Rosters({agent, world, assets}))
const selectacon = d(new Selectacon({agent, world, assets, tiler, rosters}))
const units = d(makeUnitVisuals(agent, assets))
const planner = d(new Planner({agent, assets, selectacon, submitTurn}))

d(new Hovering({world, selectacon}))
d(new UserInputs({agent, world, planner, selectacon, cameraRig}))
d(new UserInputs({agent, world, planner, selectacon, cameraRig, resetPreview}))

function render() {
rosters.render()
Expand All @@ -44,7 +51,6 @@ export async function makeGameTerminal(baseAgent: Agent, submitTurn: SubmitTurnF

tiler.render()
render()

world.gameloop.start()
dr(agent.stateRef.on(render))

Expand Down

0 comments on commit d656625

Please sign in to comment.