Also prune while queueing

This commit is contained in:
2023-01-28 22:21:33 +01:00
parent 5ea0f6fa6f
commit c35858239f

View File

@@ -107,6 +107,7 @@ impl BluePrint {
}) = todo.pop() }) = todo.pop()
{ {
let ideal_from_now = ideal(time_left as u32); let ideal_from_now = ideal(time_left as u32);
// Need to check again because we might've gotten a better result in the meantime.
if u32::from(best - got) >= ideal_from_now { if u32::from(best - got) >= ideal_from_now {
continue; continue;
} }
@@ -116,19 +117,8 @@ impl BluePrint {
todo.len() todo.len()
); );
} }
'element: for element in 0..4 { for (element, &costs) in self.costs.iter().enumerate() {
let mut min_to_build = 0; let Some(min_to_build) = self.until_buildable(costs, resources, machines) else { break };
for ((&cost, &avail), &machine) in
self.costs[element].iter().zip(&resources).zip(&machines)
{
if cost > avail {
if machine == 0 {
continue 'element;
} else {
min_to_build = min_to_build.max((cost - avail + machine - 1) / machine);
}
}
}
// +1 because we need a turn to build // +1 because we need a turn to build
let built_after = min_to_build + 1; let built_after = min_to_build + 1;
@@ -136,13 +126,18 @@ impl BluePrint {
continue; continue;
} }
let resources_after = array::from_fn(|i| { let resources_after =
resources[i] + machines[i] * built_after - self.costs[element][i] array::from_fn(|i| resources[i] + machines[i] * built_after - costs[i]);
});
let time_after = time_left - built_after; let time_after = time_left - built_after;
if element == Mineral::Geode as usize { if element == Mineral::Geode as usize {
let new_got = got + time_after; let new_got = got + time_after;
best = best.max(new_got);
if u32::from(best - new_got) >= ideal(time_after.into()) {
continue;
}
todo.push(State { todo.push(State {
missed, missed,
got: new_got, got: new_got,
@@ -153,7 +148,9 @@ impl BluePrint {
best = best.max(new_got); best = best.max(new_got);
} else { } else {
if machines[element] >= max_needed[element] { if machines[element] >= max_needed[element]
|| u32::from(best - got) >= ideal(time_after.into())
{
continue; continue;
} }
@@ -174,6 +171,22 @@ impl BluePrint {
best best
} }
#[inline]
fn until_buildable(&self, costs: [u8; 3], resources: [u8; 3], machines: [u8; 3]) -> Option<u8> {
let mut min_to_build = 0;
for ((&cost, &avail), &machine) in costs.iter().zip(&resources).zip(&machines) {
if cost > avail {
if machine == 0 {
return None;
} else {
min_to_build = min_to_build.max((cost - avail + machine - 1) / machine);
}
}
}
Some(min_to_build)
}
fn max_needed(&self) -> [u8; 3] { fn max_needed(&self) -> [u8; 3] {
let mut max_needed = [0; 3]; let mut max_needed = [0; 3];