cogames-agents 0.0.0.7__cp312-cp312-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cogames_agents/__init__.py +0 -0
- cogames_agents/evals/__init__.py +5 -0
- cogames_agents/evals/planky_evals.py +415 -0
- cogames_agents/policy/__init__.py +0 -0
- cogames_agents/policy/evolution/__init__.py +0 -0
- cogames_agents/policy/evolution/cogsguard/__init__.py +0 -0
- cogames_agents/policy/evolution/cogsguard/evolution.py +695 -0
- cogames_agents/policy/evolution/cogsguard/evolutionary_coordinator.py +540 -0
- cogames_agents/policy/nim_agents/__init__.py +20 -0
- cogames_agents/policy/nim_agents/agents.py +98 -0
- cogames_agents/policy/nim_agents/bindings/generated/libnim_agents.dylib +0 -0
- cogames_agents/policy/nim_agents/bindings/generated/nim_agents.py +215 -0
- cogames_agents/policy/nim_agents/cogsguard_agents.nim +555 -0
- cogames_agents/policy/nim_agents/cogsguard_align_all_agents.nim +569 -0
- cogames_agents/policy/nim_agents/common.nim +1054 -0
- cogames_agents/policy/nim_agents/install.sh +1 -0
- cogames_agents/policy/nim_agents/ladybug_agent.nim +954 -0
- cogames_agents/policy/nim_agents/nim_agents.nim +68 -0
- cogames_agents/policy/nim_agents/nim_agents.nims +14 -0
- cogames_agents/policy/nim_agents/nimby.lock +3 -0
- cogames_agents/policy/nim_agents/racecar_agents.nim +844 -0
- cogames_agents/policy/nim_agents/random_agents.nim +68 -0
- cogames_agents/policy/nim_agents/test_agents.py +53 -0
- cogames_agents/policy/nim_agents/thinky_agents.nim +677 -0
- cogames_agents/policy/nim_agents/thinky_eval.py +230 -0
- cogames_agents/policy/scripted_agent/README.md +360 -0
- cogames_agents/policy/scripted_agent/__init__.py +0 -0
- cogames_agents/policy/scripted_agent/baseline_agent.py +1031 -0
- cogames_agents/policy/scripted_agent/cogas/__init__.py +5 -0
- cogames_agents/policy/scripted_agent/cogas/context.py +68 -0
- cogames_agents/policy/scripted_agent/cogas/entity_map.py +152 -0
- cogames_agents/policy/scripted_agent/cogas/goal.py +115 -0
- cogames_agents/policy/scripted_agent/cogas/goals/__init__.py +27 -0
- cogames_agents/policy/scripted_agent/cogas/goals/aligner.py +160 -0
- cogames_agents/policy/scripted_agent/cogas/goals/gear.py +197 -0
- cogames_agents/policy/scripted_agent/cogas/goals/miner.py +441 -0
- cogames_agents/policy/scripted_agent/cogas/goals/scout.py +40 -0
- cogames_agents/policy/scripted_agent/cogas/goals/scrambler.py +174 -0
- cogames_agents/policy/scripted_agent/cogas/goals/shared.py +160 -0
- cogames_agents/policy/scripted_agent/cogas/goals/stem.py +60 -0
- cogames_agents/policy/scripted_agent/cogas/goals/survive.py +100 -0
- cogames_agents/policy/scripted_agent/cogas/navigator.py +401 -0
- cogames_agents/policy/scripted_agent/cogas/obs_parser.py +238 -0
- cogames_agents/policy/scripted_agent/cogas/policy.py +525 -0
- cogames_agents/policy/scripted_agent/cogas/trace.py +69 -0
- cogames_agents/policy/scripted_agent/cogsguard/CLAUDE.md +517 -0
- cogames_agents/policy/scripted_agent/cogsguard/README.md +252 -0
- cogames_agents/policy/scripted_agent/cogsguard/__init__.py +74 -0
- cogames_agents/policy/scripted_agent/cogsguard/aligned_junction_held_investigation.md +152 -0
- cogames_agents/policy/scripted_agent/cogsguard/aligner.py +333 -0
- cogames_agents/policy/scripted_agent/cogsguard/behavior_hooks.py +44 -0
- cogames_agents/policy/scripted_agent/cogsguard/control_agent.py +323 -0
- cogames_agents/policy/scripted_agent/cogsguard/debug_agent.py +533 -0
- cogames_agents/policy/scripted_agent/cogsguard/miner.py +589 -0
- cogames_agents/policy/scripted_agent/cogsguard/options.py +67 -0
- cogames_agents/policy/scripted_agent/cogsguard/parity_metrics.py +36 -0
- cogames_agents/policy/scripted_agent/cogsguard/policy.py +1967 -0
- cogames_agents/policy/scripted_agent/cogsguard/prereq_trace.py +33 -0
- cogames_agents/policy/scripted_agent/cogsguard/role_trace.py +50 -0
- cogames_agents/policy/scripted_agent/cogsguard/roles.py +31 -0
- cogames_agents/policy/scripted_agent/cogsguard/rollout_trace.py +40 -0
- cogames_agents/policy/scripted_agent/cogsguard/scout.py +69 -0
- cogames_agents/policy/scripted_agent/cogsguard/scrambler.py +350 -0
- cogames_agents/policy/scripted_agent/cogsguard/targeted_agent.py +418 -0
- cogames_agents/policy/scripted_agent/cogsguard/teacher.py +224 -0
- cogames_agents/policy/scripted_agent/cogsguard/types.py +381 -0
- cogames_agents/policy/scripted_agent/cogsguard/v2_agent.py +49 -0
- cogames_agents/policy/scripted_agent/common/__init__.py +0 -0
- cogames_agents/policy/scripted_agent/common/geometry.py +24 -0
- cogames_agents/policy/scripted_agent/common/roles.py +34 -0
- cogames_agents/policy/scripted_agent/common/tag_utils.py +48 -0
- cogames_agents/policy/scripted_agent/demo_policy.py +242 -0
- cogames_agents/policy/scripted_agent/pathfinding.py +126 -0
- cogames_agents/policy/scripted_agent/pinky/DESIGN.md +317 -0
- cogames_agents/policy/scripted_agent/pinky/__init__.py +5 -0
- cogames_agents/policy/scripted_agent/pinky/behaviors/__init__.py +17 -0
- cogames_agents/policy/scripted_agent/pinky/behaviors/aligner.py +400 -0
- cogames_agents/policy/scripted_agent/pinky/behaviors/base.py +119 -0
- cogames_agents/policy/scripted_agent/pinky/behaviors/miner.py +632 -0
- cogames_agents/policy/scripted_agent/pinky/behaviors/scout.py +138 -0
- cogames_agents/policy/scripted_agent/pinky/behaviors/scrambler.py +433 -0
- cogames_agents/policy/scripted_agent/pinky/policy.py +570 -0
- cogames_agents/policy/scripted_agent/pinky/services/__init__.py +7 -0
- cogames_agents/policy/scripted_agent/pinky/services/map_tracker.py +808 -0
- cogames_agents/policy/scripted_agent/pinky/services/navigator.py +864 -0
- cogames_agents/policy/scripted_agent/pinky/services/safety.py +189 -0
- cogames_agents/policy/scripted_agent/pinky/state.py +299 -0
- cogames_agents/policy/scripted_agent/pinky/types.py +138 -0
- cogames_agents/policy/scripted_agent/planky/CLAUDE.md +124 -0
- cogames_agents/policy/scripted_agent/planky/IMPROVEMENTS.md +160 -0
- cogames_agents/policy/scripted_agent/planky/NOTES.md +153 -0
- cogames_agents/policy/scripted_agent/planky/PLAN.md +254 -0
- cogames_agents/policy/scripted_agent/planky/README.md +214 -0
- cogames_agents/policy/scripted_agent/planky/STRATEGY.md +100 -0
- cogames_agents/policy/scripted_agent/planky/__init__.py +5 -0
- cogames_agents/policy/scripted_agent/planky/context.py +68 -0
- cogames_agents/policy/scripted_agent/planky/entity_map.py +152 -0
- cogames_agents/policy/scripted_agent/planky/goal.py +107 -0
- cogames_agents/policy/scripted_agent/planky/goals/__init__.py +27 -0
- cogames_agents/policy/scripted_agent/planky/goals/aligner.py +168 -0
- cogames_agents/policy/scripted_agent/planky/goals/gear.py +179 -0
- cogames_agents/policy/scripted_agent/planky/goals/miner.py +416 -0
- cogames_agents/policy/scripted_agent/planky/goals/scout.py +40 -0
- cogames_agents/policy/scripted_agent/planky/goals/scrambler.py +174 -0
- cogames_agents/policy/scripted_agent/planky/goals/shared.py +160 -0
- cogames_agents/policy/scripted_agent/planky/goals/stem.py +49 -0
- cogames_agents/policy/scripted_agent/planky/goals/survive.py +96 -0
- cogames_agents/policy/scripted_agent/planky/navigator.py +388 -0
- cogames_agents/policy/scripted_agent/planky/obs_parser.py +238 -0
- cogames_agents/policy/scripted_agent/planky/policy.py +485 -0
- cogames_agents/policy/scripted_agent/planky/tests/__init__.py +0 -0
- cogames_agents/policy/scripted_agent/planky/tests/conftest.py +66 -0
- cogames_agents/policy/scripted_agent/planky/tests/helpers.py +152 -0
- cogames_agents/policy/scripted_agent/planky/tests/test_aligner.py +24 -0
- cogames_agents/policy/scripted_agent/planky/tests/test_miner.py +30 -0
- cogames_agents/policy/scripted_agent/planky/tests/test_scout.py +15 -0
- cogames_agents/policy/scripted_agent/planky/tests/test_scrambler.py +29 -0
- cogames_agents/policy/scripted_agent/planky/tests/test_stem.py +36 -0
- cogames_agents/policy/scripted_agent/planky/trace.py +69 -0
- cogames_agents/policy/scripted_agent/types.py +239 -0
- cogames_agents/policy/scripted_agent/unclipping_agent.py +461 -0
- cogames_agents/policy/scripted_agent/utils.py +381 -0
- cogames_agents/policy/scripted_registry.py +80 -0
- cogames_agents/py.typed +0 -0
- cogames_agents-0.0.0.7.dist-info/METADATA +98 -0
- cogames_agents-0.0.0.7.dist-info/RECORD +128 -0
- cogames_agents-0.0.0.7.dist-info/WHEEL +6 -0
- cogames_agents-0.0.0.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
import
|
|
2
|
+
std/[random, sets, tables, options, strutils],
|
|
3
|
+
fidget2/measure,
|
|
4
|
+
common
|
|
5
|
+
|
|
6
|
+
const
|
|
7
|
+
DepotTags = ["junction", "junction", "supply_depot"]
|
|
8
|
+
HubTags = ["hub", "hub", "main_nexus"]
|
|
9
|
+
StationTags = ["aligner_station", "scrambler_station", "miner_station", "scout_station"]
|
|
10
|
+
ResourceNames = ["carbon", "oxygen", "germanium", "silicon"]
|
|
11
|
+
ExploreSteps = 8
|
|
12
|
+
DebugEnabled = false
|
|
13
|
+
DebugEvery = 50
|
|
14
|
+
DebugScramblerId = 0
|
|
15
|
+
DebugAlignerId = 1
|
|
16
|
+
DebugMinerId = 2
|
|
17
|
+
|
|
18
|
+
const Offsets4 = [
|
|
19
|
+
Location(x: 1, y: 0),
|
|
20
|
+
Location(x: 0, y: 1),
|
|
21
|
+
Location(x: -1, y: 0),
|
|
22
|
+
Location(x: 0, y: -1),
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
type
|
|
26
|
+
PendingAction = enum
|
|
27
|
+
PendingNone = 0,
|
|
28
|
+
PendingAlign = 1,
|
|
29
|
+
PendingScramble = 2
|
|
30
|
+
|
|
31
|
+
CogsguardAlignAllAgent* = ref object
|
|
32
|
+
agentId*: int
|
|
33
|
+
cfg: Config
|
|
34
|
+
random: Rand
|
|
35
|
+
map: Table[Location, seq[FeatureValue]]
|
|
36
|
+
seen: HashSet[Location]
|
|
37
|
+
unreachables: HashSet[Location]
|
|
38
|
+
location: Location
|
|
39
|
+
bump: bool
|
|
40
|
+
|
|
41
|
+
exploreDirIndex: int
|
|
42
|
+
exploreSteps: int
|
|
43
|
+
|
|
44
|
+
stations: Table[string, Location]
|
|
45
|
+
depots: Table[Location, int] # -1 clips, 0 neutral/unknown, 1 cogs
|
|
46
|
+
extractors: Table[string, seq[Location]]
|
|
47
|
+
extractorRemaining: Table[Location, int]
|
|
48
|
+
hub: Option[Location]
|
|
49
|
+
chest: Option[Location]
|
|
50
|
+
actionIds: Table[string, int]
|
|
51
|
+
|
|
52
|
+
pendingAction: PendingAction
|
|
53
|
+
pendingTarget: Option[Location]
|
|
54
|
+
lastHeart: int
|
|
55
|
+
stepCount: int
|
|
56
|
+
|
|
57
|
+
CogsguardAlignAllPolicy* = ref object
|
|
58
|
+
agents*: seq[CogsguardAlignAllAgent]
|
|
59
|
+
|
|
60
|
+
proc getVibeName(agent: CogsguardAlignAllAgent, vibeId: int): string =
|
|
61
|
+
if vibeId >= 0 and vibeId < agent.cfg.vibeNames.len:
|
|
62
|
+
return agent.cfg.vibeNames[vibeId]
|
|
63
|
+
return "default"
|
|
64
|
+
|
|
65
|
+
proc getActionId(agent: CogsguardAlignAllAgent, name: string): int =
|
|
66
|
+
return agent.actionIds.getOrDefault(name, agent.cfg.actions.noop)
|
|
67
|
+
|
|
68
|
+
proc actionForVibe(agent: CogsguardAlignAllAgent, vibe: string): int =
|
|
69
|
+
let actionName = "change_vibe_" & vibe
|
|
70
|
+
return agent.getActionId(actionName)
|
|
71
|
+
|
|
72
|
+
proc featureValue(
|
|
73
|
+
features: seq[FeatureValue],
|
|
74
|
+
featureId: int
|
|
75
|
+
): int =
|
|
76
|
+
for feature in features:
|
|
77
|
+
if feature.featureId == featureId:
|
|
78
|
+
return feature.value
|
|
79
|
+
return -1
|
|
80
|
+
|
|
81
|
+
proc getTagNames(cfg: Config, features: seq[FeatureValue]): HashSet[string] =
|
|
82
|
+
result = initHashSet[string]()
|
|
83
|
+
for feature in features:
|
|
84
|
+
if feature.featureId == cfg.features.tag:
|
|
85
|
+
if feature.value >= 0 and feature.value < cfg.config.tags.len:
|
|
86
|
+
result.incl(cfg.config.tags[feature.value])
|
|
87
|
+
|
|
88
|
+
proc getAlignment(tagNames: HashSet[string], clipped: int): int =
|
|
89
|
+
if "collective:cogs" in tagNames or "cogs" in tagNames:
|
|
90
|
+
return 1
|
|
91
|
+
if "collective:clips" in tagNames or "clips" in tagNames:
|
|
92
|
+
return -1
|
|
93
|
+
if clipped > 0:
|
|
94
|
+
return -1
|
|
95
|
+
return 0
|
|
96
|
+
|
|
97
|
+
proc isResourceExtractor(tagName: string): bool =
|
|
98
|
+
for resource in ResourceNames:
|
|
99
|
+
if resource & "_extractor" in tagName:
|
|
100
|
+
return true
|
|
101
|
+
if resource & "_chest" in tagName:
|
|
102
|
+
return true
|
|
103
|
+
return false
|
|
104
|
+
|
|
105
|
+
proc updateDiscoveries(agent: CogsguardAlignAllAgent, visible: Table[Location, seq[FeatureValue]]) =
|
|
106
|
+
for location, features in visible:
|
|
107
|
+
let tagNames = getTagNames(agent.cfg, features)
|
|
108
|
+
if tagNames.len == 0:
|
|
109
|
+
continue
|
|
110
|
+
|
|
111
|
+
let absoluteLoc = Location(x: location.x + agent.location.x, y: location.y + agent.location.y)
|
|
112
|
+
let clipped = featureValue(features, agent.cfg.features.clipped)
|
|
113
|
+
let alignment = getAlignment(tagNames, clipped)
|
|
114
|
+
|
|
115
|
+
for tagName in tagNames.items:
|
|
116
|
+
for stationName in StationTags.items:
|
|
117
|
+
if tagName == stationName:
|
|
118
|
+
agent.stations[stationName] = absoluteLoc
|
|
119
|
+
if tagName in HubTags:
|
|
120
|
+
agent.hub = some(absoluteLoc)
|
|
121
|
+
if tagName in DepotTags:
|
|
122
|
+
agent.depots[absoluteLoc] = alignment
|
|
123
|
+
|
|
124
|
+
if tagName == "chest" and not tagName.isResourceExtractor():
|
|
125
|
+
agent.chest = some(absoluteLoc)
|
|
126
|
+
|
|
127
|
+
if tagName.isResourceExtractor():
|
|
128
|
+
for resource in ResourceNames:
|
|
129
|
+
if resource & "_extractor" in tagName or resource & "_chest" in tagName:
|
|
130
|
+
var locations = agent.extractors.getOrDefault(resource, @[])
|
|
131
|
+
if absoluteLoc notin locations:
|
|
132
|
+
locations.add(absoluteLoc)
|
|
133
|
+
agent.extractors[resource] = locations
|
|
134
|
+
|
|
135
|
+
let remaining = featureValue(features, agent.cfg.features.remainingUses)
|
|
136
|
+
if remaining != -1:
|
|
137
|
+
agent.extractorRemaining[absoluteLoc] = remaining
|
|
138
|
+
|
|
139
|
+
proc updateMap(agent: CogsguardAlignAllAgent, visible: Table[Location, seq[FeatureValue]]) {.measure.} =
|
|
140
|
+
if agent.map.len == 0:
|
|
141
|
+
agent.map = visible
|
|
142
|
+
agent.location = Location(x: 0, y: 0)
|
|
143
|
+
for x in -5 .. 5:
|
|
144
|
+
for y in -5 .. 5:
|
|
145
|
+
agent.seen.incl(Location(x: x, y: y))
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
var newLocation = agent.location
|
|
149
|
+
let lastAction = agent.cfg.getLastAction(visible)
|
|
150
|
+
if lastAction == agent.cfg.actions.moveNorth:
|
|
151
|
+
newLocation.y -= 1
|
|
152
|
+
elif lastAction == agent.cfg.actions.moveSouth:
|
|
153
|
+
newLocation.y += 1
|
|
154
|
+
elif lastAction == agent.cfg.actions.moveWest:
|
|
155
|
+
newLocation.x -= 1
|
|
156
|
+
elif lastAction == agent.cfg.actions.moveEast:
|
|
157
|
+
newLocation.x += 1
|
|
158
|
+
|
|
159
|
+
block bumpCheck:
|
|
160
|
+
agent.bump = false
|
|
161
|
+
for x in -5 .. 5:
|
|
162
|
+
for y in -5 .. 5:
|
|
163
|
+
let visibleLocation = Location(x: x, y: y)
|
|
164
|
+
let mapLocation = Location(x: x + newLocation.x, y: y + newLocation.y)
|
|
165
|
+
if mapLocation notin agent.seen:
|
|
166
|
+
continue
|
|
167
|
+
var visibleTag = agent.cfg.getTag(visible, visibleLocation)
|
|
168
|
+
if visibleTag == agent.cfg.tags.agent:
|
|
169
|
+
visibleTag = -1
|
|
170
|
+
var mapTag = agent.cfg.getTag(agent.map, mapLocation)
|
|
171
|
+
if mapTag == agent.cfg.tags.agent:
|
|
172
|
+
mapTag = -1
|
|
173
|
+
if visibleTag != mapTag:
|
|
174
|
+
newLocation = agent.location
|
|
175
|
+
agent.bump = true
|
|
176
|
+
break bumpCheck
|
|
177
|
+
|
|
178
|
+
agent.location = newLocation
|
|
179
|
+
for x in -5 .. 5:
|
|
180
|
+
for y in -5 .. 5:
|
|
181
|
+
let visibleLocation = Location(x: x, y: y)
|
|
182
|
+
let mapLocation = Location(x: x + agent.location.x, y: y + agent.location.y)
|
|
183
|
+
agent.map[mapLocation] = visible.getOrDefault(visibleLocation, @[])
|
|
184
|
+
agent.seen.incl(mapLocation)
|
|
185
|
+
|
|
186
|
+
proc moveTo(agent: CogsguardAlignAllAgent, target: Location): int =
|
|
187
|
+
if agent.location == target:
|
|
188
|
+
return agent.cfg.actions.noop
|
|
189
|
+
let action = agent.cfg.aStar(agent.location, target, agent.map)
|
|
190
|
+
if action.isSome():
|
|
191
|
+
return action.get()
|
|
192
|
+
if DebugEnabled and (agent.agentId == DebugScramblerId or agent.agentId == DebugAlignerId or agent.agentId == DebugMinerId) and agent.stepCount mod DebugEvery == 0:
|
|
193
|
+
echo "[align-all] astar failed id=", agent.agentId,
|
|
194
|
+
" loc=(", agent.location.x, ",", agent.location.y, ")",
|
|
195
|
+
" target=(", target.x, ",", target.y, ")"
|
|
196
|
+
return agent.cfg.actions.noop
|
|
197
|
+
|
|
198
|
+
proc stepAction(agent: CogsguardAlignAllAgent, fromLoc, toLoc: Location): int =
|
|
199
|
+
if toLoc.x == fromLoc.x + 1 and toLoc.y == fromLoc.y:
|
|
200
|
+
return agent.cfg.actions.moveEast
|
|
201
|
+
if toLoc.x == fromLoc.x - 1 and toLoc.y == fromLoc.y:
|
|
202
|
+
return agent.cfg.actions.moveWest
|
|
203
|
+
if toLoc.y == fromLoc.y - 1 and toLoc.x == fromLoc.x:
|
|
204
|
+
return agent.cfg.actions.moveNorth
|
|
205
|
+
if toLoc.y == fromLoc.y + 1 and toLoc.x == fromLoc.x:
|
|
206
|
+
return agent.cfg.actions.moveSouth
|
|
207
|
+
return agent.cfg.actions.noop
|
|
208
|
+
|
|
209
|
+
proc explore(agent: CogsguardAlignAllAgent): int =
|
|
210
|
+
let unseen = agent.cfg.getNearbyUnseen(agent.location, agent.map, agent.seen, agent.unreachables)
|
|
211
|
+
if unseen.isSome():
|
|
212
|
+
let action = agent.moveTo(unseen.get())
|
|
213
|
+
if action != agent.cfg.actions.noop:
|
|
214
|
+
return action
|
|
215
|
+
agent.unreachables.incl(unseen.get())
|
|
216
|
+
|
|
217
|
+
if agent.exploreSteps < ExploreSteps:
|
|
218
|
+
let offset = Offsets4[agent.exploreDirIndex]
|
|
219
|
+
let nextLoc = agent.location + offset
|
|
220
|
+
if agent.cfg.isWalkable(agent.map, nextLoc):
|
|
221
|
+
agent.exploreSteps += 1
|
|
222
|
+
return agent.stepAction(agent.location, nextLoc)
|
|
223
|
+
|
|
224
|
+
for i in 1 .. 4:
|
|
225
|
+
let idx = (agent.exploreDirIndex + i) mod 4
|
|
226
|
+
let offset = Offsets4[idx]
|
|
227
|
+
let nextLoc = agent.location + offset
|
|
228
|
+
if agent.cfg.isWalkable(agent.map, nextLoc):
|
|
229
|
+
agent.exploreDirIndex = idx
|
|
230
|
+
agent.exploreSteps = 1
|
|
231
|
+
return agent.stepAction(agent.location, nextLoc)
|
|
232
|
+
|
|
233
|
+
return agent.cfg.actions.noop
|
|
234
|
+
|
|
235
|
+
proc nearestLocation(
|
|
236
|
+
agent: CogsguardAlignAllAgent,
|
|
237
|
+
locations: seq[Location]
|
|
238
|
+
): Option[Location] =
|
|
239
|
+
var bestDist = high(int)
|
|
240
|
+
var best: Option[Location] = none(Location)
|
|
241
|
+
for loc in locations:
|
|
242
|
+
let dist = manhattan(agent.location, loc)
|
|
243
|
+
if dist < bestDist:
|
|
244
|
+
bestDist = dist
|
|
245
|
+
best = some(loc)
|
|
246
|
+
return best
|
|
247
|
+
|
|
248
|
+
proc nearestDepot(agent: CogsguardAlignAllAgent, alignmentFilter: int): Option[Location] =
|
|
249
|
+
var candidates: seq[Location] = @[]
|
|
250
|
+
for loc, alignment in agent.depots:
|
|
251
|
+
if alignment == alignmentFilter:
|
|
252
|
+
candidates.add(loc)
|
|
253
|
+
if candidates.len == 0:
|
|
254
|
+
return none(Location)
|
|
255
|
+
return agent.nearestLocation(candidates)
|
|
256
|
+
|
|
257
|
+
proc moveToOrExplore(agent: CogsguardAlignAllAgent, target: Option[Location]): int =
|
|
258
|
+
if target.isSome():
|
|
259
|
+
return agent.moveTo(target.get())
|
|
260
|
+
return agent.explore()
|
|
261
|
+
|
|
262
|
+
proc returnToHubSearch(agent: CogsguardAlignAllAgent): int =
|
|
263
|
+
if agent.hub.isSome():
|
|
264
|
+
let hubLoc = agent.hub.get()
|
|
265
|
+
if manhattan(agent.location, hubLoc) > 2:
|
|
266
|
+
return agent.moveTo(hubLoc)
|
|
267
|
+
return agent.explore()
|
|
268
|
+
|
|
269
|
+
proc nearestAlignedDepot(agent: CogsguardAlignAllAgent): Option[Location] =
|
|
270
|
+
if agent.hub.isSome():
|
|
271
|
+
return agent.hub
|
|
272
|
+
return agent.nearestDepot(1)
|
|
273
|
+
|
|
274
|
+
proc doDeposit(agent: CogsguardAlignAllAgent): int =
|
|
275
|
+
let depot = agent.nearestAlignedDepot()
|
|
276
|
+
return agent.moveToOrExplore(depot)
|
|
277
|
+
|
|
278
|
+
proc doGather(agent: CogsguardAlignAllAgent): int =
|
|
279
|
+
var candidates: seq[Location] = @[]
|
|
280
|
+
for resource in ResourceNames:
|
|
281
|
+
for loc in agent.extractors.getOrDefault(resource, @[]):
|
|
282
|
+
let remaining = agent.extractorRemaining.getOrDefault(loc, 1)
|
|
283
|
+
if remaining != 0:
|
|
284
|
+
candidates.add(loc)
|
|
285
|
+
|
|
286
|
+
if candidates.len == 0:
|
|
287
|
+
return agent.explore()
|
|
288
|
+
|
|
289
|
+
let target = agent.nearestLocation(candidates)
|
|
290
|
+
if target.isSome():
|
|
291
|
+
return agent.moveTo(target.get())
|
|
292
|
+
return agent.explore()
|
|
293
|
+
|
|
294
|
+
proc actMiner(
|
|
295
|
+
agent: CogsguardAlignAllAgent,
|
|
296
|
+
cargo: int,
|
|
297
|
+
invMiner: int
|
|
298
|
+
): int =
|
|
299
|
+
if invMiner == 0:
|
|
300
|
+
if "miner_station" in agent.stations:
|
|
301
|
+
return agent.moveToOrExplore(some(agent.stations["miner_station"]))
|
|
302
|
+
return agent.returnToHubSearch()
|
|
303
|
+
|
|
304
|
+
let capacity = max(4, 40 * invMiner)
|
|
305
|
+
if cargo >= capacity - 2:
|
|
306
|
+
return agent.doDeposit()
|
|
307
|
+
return agent.doGather()
|
|
308
|
+
|
|
309
|
+
proc roleForAgent(agentId: int): string =
|
|
310
|
+
case agentId
|
|
311
|
+
of 0:
|
|
312
|
+
return "scrambler"
|
|
313
|
+
of 1:
|
|
314
|
+
return "aligner"
|
|
315
|
+
of 2, 3, 4:
|
|
316
|
+
return "miner"
|
|
317
|
+
else:
|
|
318
|
+
return "scout"
|
|
319
|
+
|
|
320
|
+
proc maybeMarkPending(
|
|
321
|
+
agent: CogsguardAlignAllAgent,
|
|
322
|
+
target: Location,
|
|
323
|
+
actionKind: PendingAction,
|
|
324
|
+
invHeart: int,
|
|
325
|
+
action: int
|
|
326
|
+
) =
|
|
327
|
+
if action == agent.cfg.actions.noop:
|
|
328
|
+
return
|
|
329
|
+
if manhattan(agent.location, target) == 1:
|
|
330
|
+
agent.pendingAction = actionKind
|
|
331
|
+
agent.pendingTarget = some(target)
|
|
332
|
+
agent.lastHeart = invHeart
|
|
333
|
+
|
|
334
|
+
proc attemptAlign(
|
|
335
|
+
agent: CogsguardAlignAllAgent,
|
|
336
|
+
target: Location,
|
|
337
|
+
invHeart: int
|
|
338
|
+
): int =
|
|
339
|
+
if agent.location == target:
|
|
340
|
+
return agent.explore()
|
|
341
|
+
let action = agent.moveTo(target)
|
|
342
|
+
agent.maybeMarkPending(target, PendingAlign, invHeart, action)
|
|
343
|
+
return action
|
|
344
|
+
|
|
345
|
+
proc attemptScramble(
|
|
346
|
+
agent: CogsguardAlignAllAgent,
|
|
347
|
+
target: Location,
|
|
348
|
+
invHeart: int
|
|
349
|
+
): int =
|
|
350
|
+
if agent.location == target:
|
|
351
|
+
return agent.explore()
|
|
352
|
+
let action = agent.moveTo(target)
|
|
353
|
+
agent.maybeMarkPending(target, PendingScramble, invHeart, action)
|
|
354
|
+
return action
|
|
355
|
+
|
|
356
|
+
proc parseVisible(
|
|
357
|
+
numTokens: int,
|
|
358
|
+
sizeToken: int,
|
|
359
|
+
rawObservation: pointer
|
|
360
|
+
): Table[Location, seq[FeatureValue]] =
|
|
361
|
+
let observations = cast[ptr UncheckedArray[uint8]](rawObservation)
|
|
362
|
+
for token in 0 ..< numTokens:
|
|
363
|
+
let locationPacked = observations[token * sizeToken]
|
|
364
|
+
let featureId = observations[token * sizeToken + 1]
|
|
365
|
+
let value = observations[token * sizeToken + 2]
|
|
366
|
+
if locationPacked == 255 and featureId == 255 and value == 255:
|
|
367
|
+
break
|
|
368
|
+
var location: Location
|
|
369
|
+
if locationPacked != 0xFF:
|
|
370
|
+
location.y = (locationPacked shr 4).int - 5
|
|
371
|
+
location.x = (locationPacked and 0x0F).int - 5
|
|
372
|
+
if location notin result:
|
|
373
|
+
result[location] = @[]
|
|
374
|
+
result[location].add(FeatureValue(featureId: featureId.int, value: value.int))
|
|
375
|
+
|
|
376
|
+
proc step*(
|
|
377
|
+
agent: CogsguardAlignAllAgent,
|
|
378
|
+
numAgents: int,
|
|
379
|
+
numTokens: int,
|
|
380
|
+
sizeToken: int,
|
|
381
|
+
rawObservation: pointer,
|
|
382
|
+
numActions: int,
|
|
383
|
+
agentAction: ptr int32
|
|
384
|
+
) {.measure.} =
|
|
385
|
+
try:
|
|
386
|
+
discard numAgents
|
|
387
|
+
discard numActions
|
|
388
|
+
|
|
389
|
+
agent.stepCount += 1
|
|
390
|
+
let visible = parseVisible(numTokens, sizeToken, rawObservation)
|
|
391
|
+
agent.updateMap(visible)
|
|
392
|
+
agent.updateDiscoveries(visible)
|
|
393
|
+
|
|
394
|
+
let vibeId = agent.cfg.getVibe(visible, Location(x: 0, y: 0))
|
|
395
|
+
let vibeName = agent.getVibeName(vibeId)
|
|
396
|
+
|
|
397
|
+
let invHeart = agent.cfg.getInventory(visible, agent.cfg.features.invHeart)
|
|
398
|
+
let invInfluence = agent.cfg.getInventory(visible, agent.cfg.features.invInfluence)
|
|
399
|
+
let invAligner = agent.cfg.getInventory(visible, agent.cfg.features.invAligner)
|
|
400
|
+
let invScrambler = agent.cfg.getInventory(visible, agent.cfg.features.invScrambler)
|
|
401
|
+
let invMiner = agent.cfg.getInventory(visible, agent.cfg.features.invMiner)
|
|
402
|
+
let invCarbon = agent.cfg.getInventory(visible, agent.cfg.features.invCarbon)
|
|
403
|
+
let invOxygen = agent.cfg.getInventory(visible, agent.cfg.features.invOxygen)
|
|
404
|
+
let invGermanium = agent.cfg.getInventory(visible, agent.cfg.features.invGermanium)
|
|
405
|
+
let invSilicon = agent.cfg.getInventory(visible, agent.cfg.features.invSilicon)
|
|
406
|
+
let cargo = invCarbon + invOxygen + invGermanium + invSilicon
|
|
407
|
+
|
|
408
|
+
if agent.pendingAction != PendingNone and invHeart < agent.lastHeart:
|
|
409
|
+
if agent.pendingTarget.isSome():
|
|
410
|
+
let target = agent.pendingTarget.get()
|
|
411
|
+
if agent.pendingAction == PendingAlign:
|
|
412
|
+
agent.depots[target] = 1
|
|
413
|
+
elif agent.pendingAction == PendingScramble:
|
|
414
|
+
agent.depots[target] = 0
|
|
415
|
+
agent.pendingAction = PendingNone
|
|
416
|
+
agent.pendingTarget = none(Location)
|
|
417
|
+
|
|
418
|
+
agent.lastHeart = invHeart
|
|
419
|
+
|
|
420
|
+
var action = agent.cfg.actions.noop
|
|
421
|
+
|
|
422
|
+
let targetScramble = agent.nearestDepot(-1)
|
|
423
|
+
let targetAlign = agent.nearestDepot(0)
|
|
424
|
+
let role = roleForAgent(agent.agentId)
|
|
425
|
+
|
|
426
|
+
if DebugEnabled and (agent.agentId == DebugScramblerId or agent.agentId == DebugAlignerId or agent.agentId == DebugMinerId) and agent.stepCount mod DebugEvery == 0:
|
|
427
|
+
var clipsDepots = 0
|
|
428
|
+
var neutralDepots = 0
|
|
429
|
+
var cogsDepots = 0
|
|
430
|
+
for _, alignment in agent.depots:
|
|
431
|
+
if alignment == -1:
|
|
432
|
+
clipsDepots += 1
|
|
433
|
+
elif alignment == 0:
|
|
434
|
+
neutralDepots += 1
|
|
435
|
+
elif alignment == 1:
|
|
436
|
+
cogsDepots += 1
|
|
437
|
+
let hasScramblerStation = "scrambler_station" in agent.stations
|
|
438
|
+
let hasAlignerStation = "aligner_station" in agent.stations
|
|
439
|
+
let hasMinerStation = "miner_station" in agent.stations
|
|
440
|
+
let chestDist = if agent.chest.isSome(): manhattan(agent.location, agent.chest.get()) else: -1
|
|
441
|
+
let hubDist = if agent.hub.isSome(): manhattan(agent.location, agent.hub.get()) else: -1
|
|
442
|
+
let minerCapacity = max(4, 40 * invMiner)
|
|
443
|
+
echo "[align-all] step=", agent.stepCount,
|
|
444
|
+
" id=", agent.agentId,
|
|
445
|
+
" role=", role,
|
|
446
|
+
" vibe=", vibeName,
|
|
447
|
+
" loc=(", agent.location.x, ",", agent.location.y, ")",
|
|
448
|
+
" heart=", invHeart,
|
|
449
|
+
" infl=", invInfluence,
|
|
450
|
+
" gearA=", invAligner,
|
|
451
|
+
" gearS=", invScrambler,
|
|
452
|
+
" gearM=", invMiner,
|
|
453
|
+
" cargo=", cargo, "/", minerCapacity,
|
|
454
|
+
" depots=", clipsDepots, "/", neutralDepots, "/", cogsDepots,
|
|
455
|
+
" chest=", agent.chest.isSome(),
|
|
456
|
+
" hub=", agent.hub.isSome(),
|
|
457
|
+
" stations(a/s/m)=", hasAlignerStation, "/", hasScramblerStation, "/", hasMinerStation,
|
|
458
|
+
" dist(chest/hub)=", chestDist, "/", hubDist,
|
|
459
|
+
" targetA=", targetAlign.isSome(),
|
|
460
|
+
" targetS=", targetScramble.isSome()
|
|
461
|
+
|
|
462
|
+
if role == "scrambler":
|
|
463
|
+
if vibeName != "scrambler":
|
|
464
|
+
action = agent.actionForVibe("scrambler")
|
|
465
|
+
elif invScrambler == 0:
|
|
466
|
+
if "scrambler_station" in agent.stations:
|
|
467
|
+
action = agent.moveToOrExplore(some(agent.stations["scrambler_station"]))
|
|
468
|
+
else:
|
|
469
|
+
action = agent.returnToHubSearch()
|
|
470
|
+
elif invHeart == 0:
|
|
471
|
+
if agent.chest.isSome():
|
|
472
|
+
action = agent.moveToOrExplore(agent.chest)
|
|
473
|
+
else:
|
|
474
|
+
action = agent.returnToHubSearch()
|
|
475
|
+
elif targetScramble.isSome():
|
|
476
|
+
action = agent.attemptScramble(targetScramble.get(), invHeart)
|
|
477
|
+
else:
|
|
478
|
+
action = agent.explore()
|
|
479
|
+
elif role == "aligner":
|
|
480
|
+
if vibeName != "aligner":
|
|
481
|
+
action = agent.actionForVibe("aligner")
|
|
482
|
+
elif invAligner == 0:
|
|
483
|
+
if "aligner_station" in agent.stations:
|
|
484
|
+
action = agent.moveToOrExplore(some(agent.stations["aligner_station"]))
|
|
485
|
+
else:
|
|
486
|
+
action = agent.returnToHubSearch()
|
|
487
|
+
elif invHeart == 0:
|
|
488
|
+
if agent.chest.isSome():
|
|
489
|
+
action = agent.moveToOrExplore(agent.chest)
|
|
490
|
+
else:
|
|
491
|
+
action = agent.returnToHubSearch()
|
|
492
|
+
elif invInfluence == 0:
|
|
493
|
+
if agent.hub.isSome():
|
|
494
|
+
action = agent.moveToOrExplore(agent.hub)
|
|
495
|
+
else:
|
|
496
|
+
action = agent.returnToHubSearch()
|
|
497
|
+
elif targetAlign.isSome():
|
|
498
|
+
action = agent.attemptAlign(targetAlign.get(), invHeart)
|
|
499
|
+
else:
|
|
500
|
+
action = agent.explore()
|
|
501
|
+
elif role == "miner":
|
|
502
|
+
if vibeName != "miner":
|
|
503
|
+
action = agent.actionForVibe("miner")
|
|
504
|
+
else:
|
|
505
|
+
action = agent.actMiner(cargo, invMiner)
|
|
506
|
+
else:
|
|
507
|
+
if vibeName != "scout":
|
|
508
|
+
action = agent.actionForVibe("scout")
|
|
509
|
+
else:
|
|
510
|
+
action = agent.explore()
|
|
511
|
+
|
|
512
|
+
agentAction[] = action.int32
|
|
513
|
+
except:
|
|
514
|
+
echo getCurrentException().getStackTrace()
|
|
515
|
+
echo getCurrentExceptionMsg()
|
|
516
|
+
quit()
|
|
517
|
+
|
|
518
|
+
proc newCogsguardAlignAllAgent*(agentId: int, environmentConfig: string): CogsguardAlignAllAgent =
|
|
519
|
+
var config = parseConfig(environmentConfig)
|
|
520
|
+
result = CogsguardAlignAllAgent(agentId: agentId, cfg: config)
|
|
521
|
+
result.random = initRand(agentId)
|
|
522
|
+
result.map = initTable[Location, seq[FeatureValue]]()
|
|
523
|
+
result.seen = initHashSet[Location]()
|
|
524
|
+
result.unreachables = initHashSet[Location]()
|
|
525
|
+
result.location = Location(x: 0, y: 0)
|
|
526
|
+
result.exploreDirIndex = 0
|
|
527
|
+
result.exploreSteps = 0
|
|
528
|
+
result.stations = initTable[string, Location]()
|
|
529
|
+
result.depots = initTable[Location, int]()
|
|
530
|
+
result.extractors = initTable[string, seq[Location]]()
|
|
531
|
+
result.extractorRemaining = initTable[Location, int]()
|
|
532
|
+
result.hub = none(Location)
|
|
533
|
+
result.chest = none(Location)
|
|
534
|
+
result.actionIds = initTable[string, int]()
|
|
535
|
+
for id, name in config.config.actions:
|
|
536
|
+
result.actionIds[name] = id
|
|
537
|
+
result.pendingAction = PendingNone
|
|
538
|
+
result.pendingTarget = none(Location)
|
|
539
|
+
result.lastHeart = 0
|
|
540
|
+
result.stepCount = 0
|
|
541
|
+
|
|
542
|
+
proc newCogsguardAlignAllPolicy*(environmentConfig: string): CogsguardAlignAllPolicy =
|
|
543
|
+
let cfg = parseConfig(environmentConfig)
|
|
544
|
+
var agents: seq[CogsguardAlignAllAgent] = @[]
|
|
545
|
+
for id in 0 ..< cfg.config.numAgents:
|
|
546
|
+
agents.add(newCogsguardAlignAllAgent(id, environmentConfig))
|
|
547
|
+
CogsguardAlignAllPolicy(agents: agents)
|
|
548
|
+
|
|
549
|
+
proc stepBatch*(
|
|
550
|
+
policy: CogsguardAlignAllPolicy,
|
|
551
|
+
agentIds: pointer,
|
|
552
|
+
numAgentIds: int,
|
|
553
|
+
numAgents: int,
|
|
554
|
+
numTokens: int,
|
|
555
|
+
sizeToken: int,
|
|
556
|
+
rawObservations: pointer,
|
|
557
|
+
numActions: int,
|
|
558
|
+
rawActions: pointer
|
|
559
|
+
) =
|
|
560
|
+
let ids = cast[ptr UncheckedArray[int32]](agentIds)
|
|
561
|
+
let obsArray = cast[ptr UncheckedArray[uint8]](rawObservations)
|
|
562
|
+
let actionArray = cast[ptr UncheckedArray[int32]](rawActions)
|
|
563
|
+
let obsStride = numTokens * sizeToken
|
|
564
|
+
|
|
565
|
+
for i in 0 ..< numAgentIds:
|
|
566
|
+
let idx = int(ids[i])
|
|
567
|
+
let obsPtr = cast[pointer](obsArray[idx * obsStride].addr)
|
|
568
|
+
let actPtr = cast[ptr int32](actionArray[idx].addr)
|
|
569
|
+
step(policy.agents[idx], numAgents, numTokens, sizeToken, obsPtr, numActions, actPtr)
|