allowing fixed moves

This commit is contained in:
Pagwin 2026-06-09 13:32:55 -04:00
parent 7229124bb5
commit 041bf9febc
No known key found for this signature in database
GPG key ID: 81137023740CA260

71
main.py
View file

@ -23,6 +23,44 @@ import printer
# Display in _report divides by 10.
INITIAL = (30, 30, 30, 30)
# fixed_choices = {
# "actions": {
# (city_idx, step): "action_name", # e.g., (0, 2): "collect"
# # ...
# },
# "governors": {
# (city_idx, step, agent_name): bool, # e.g., (1, 1, "provisioner"): True
# # ...
# }
# }
#
# None for nothing
# FIXED_CHOICES = None
FIXED_CHOICES = {
"actions": {
(0, 1): "renovate_h",
(1, 1): "renovate_h",
(2, 1): "renovate_h",
(3, 1): "overwork",
(0, 2): "collect",
(1, 2): "collect",
(2, 2): "overwork",
(3, 2): "upgrade_a",
(0, 3): "collect",
(1, 3): "collect",
(2, 3): "upgrade_a",
(3, 3): "overwork",
(0, 4): "collect",
(1, 4): "collect",
(2, 4): "overwork",
(3, 4): "upgrade_b",
(0, 5): "collect",
(1, 5): "collect",
(2, 5): "upgrade_b",
(3, 5): "overwork",
}
}
# Arrival schedule. Key = step (1..5), value = list of city types that arrive
# at the START of that step. Types: 'H' Hub, 'F' Foundry, 'M' Metropolis, 'N' Monument.
# Total cities across all steps must be <= 7. Arriving cities act that same step.
@ -37,7 +75,7 @@ ARRIVALS = {
1: [
{"type": "F", "adjacent_to": []},
{"type": "F", "adjacent_to": []},
{"type": "F", "adjacent_to": [], "departure_step": 6},
{"type": "F", "adjacent_to": []},
{"type": "H", "adjacent_to": []},
],
2: [],
@ -917,6 +955,7 @@ class Fence(EventAgent):
def solve(
*,
initial=INITIAL,
arrivals=ARRIVALS,
max_res=MAX_RES,
@ -924,6 +963,7 @@ def solve(
time_limit=60.0,
num_workers=8,
verbose=True,
fixed_choices=FIXED_CHOICES,
):
# ---- build the city list -----------------------------------------
@ -1097,6 +1137,11 @@ def solve(
for agent in event_agent_registry:
agent.declare_vars(m, _agent_decl_ctx)
if fixed_choices and "governors" in fixed_choices:
for (city, step, agent_name), value in fixed_choices["governors"].items():
if governor.get((city, step, agent_name)) is not None:
m.Add(governor[city, step, agent_name] == (1 if value else 0))
# ---- per-city logic -----------------------------------------------
for i in range(N):
a_step, a_city = cities[i]
@ -1191,6 +1236,20 @@ def solve(
for action in action_registry:
action.declare_vars(m, i, t, ctx)
# After declaring all action variables for (i,t)
if fixed_choices and "actions" in fixed_choices:
action_key = (i, t)
if action_key in fixed_choices["actions"]:
fixed_action = fixed_choices["actions"][action_key]
# Set the chosen action to 1, others to 0
for action in action_registry:
var = action.selector_var(i, t, ctx)
if var is not None:
if action.name == fixed_action:
m.Add(var == 1)
else:
m.Add(var == 0)
# renovations helper (used by multiple actions)
ren = m.NewBoolVar("")
rH_act = rH.get((i, t))
@ -1473,12 +1532,16 @@ def solve(
solver = cp_model.CpSolver()
solver.parameters.max_time_in_seconds = time_limit
solver.parameters.num_search_workers = num_workers
status = None
if verbose:
status = solver.Solve(
m,
# printer.IntermediateSolutionPrinter(
# {"electrum": finalE, "brass": finalB, "steel": finalS}, scale=0.1
# ),
printer.IntermediateSolutionPrinter(
{"electrum": finalE, "brass": finalB, "steel": finalS}, scale=0.1
),
)
else:
status = solver.Solve(m)
if verbose:
print(f"(resource ceilings used: E<={capE} B<={capB} S<={capS})")