-
Notifications
You must be signed in to change notification settings - Fork 0
/
decisionMaker.ts
60 lines (55 loc) · 1.91 KB
/
decisionMaker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { log } from '../../logging/configure-logging'
import { logError } from '../../logging/log-error'
import { ShipEntity } from '../ship/ship.entity'
import { getActor } from './actions/getActor'
import { AgentEntity } from './agent.entity'
import { shipArriving } from './utils/getCurrentFlightTime'
const createDecisionRateMonitor = () => {
const decisionTimestamps: Date[] = []
const recordTimestamp = () => {
decisionTimestamps.push(new Date())
decisionTimestamps.splice(0, decisionTimestamps.length - 10)
}
const getDecisionRate = () => {
if (decisionTimestamps.length < 10) return Infinity
const first = decisionTimestamps[0]
const last = decisionTimestamps[decisionTimestamps.length - 1]
return (last.getTime() - first.getTime()) / 1000
}
return { recordTimestamp, getDecisionRate }
}
export const decisionMaker = async (
ship: ShipEntity,
shouldUpdateWaypoint: boolean,
agent: AgentEntity,
act: Awaited<ReturnType<typeof getActor>>,
decisions: (ship: ShipEntity, agent: AgentEntity) => void,
) => {
const { recordTimestamp, getDecisionRate } = createDecisionRateMonitor()
const makeNextDecision = async (ship: ShipEntity) => {
recordTimestamp()
try {
const { seconds, distance } = shipArriving(ship)
if (seconds <= 0) {
if (shouldUpdateWaypoint) {
await act.updateCurrentWaypoint(ship)
}
await decisions(ship, agent)
} else {
log.info('ship', `${ship.label} is not yet in position. Waiting for arrival ${distance}`)
await act.wait(seconds * 1000)
}
} catch (err) {
logError(`${ship.label} makeDecision`, err)
}
}
// eslint-disable-next-line no-constant-condition
while (true) {
await makeNextDecision(ship)
const decisionRate = getDecisionRate()
if (decisionRate < 2) {
ship.isCommanded = false
throw new Error(`${ship.label}: Decision rate too high`)
}
}
}