fix fast validation
All checks were successful
Build / build (push) Successful in 1m51s

This commit is contained in:
2025-06-24 20:49:56 +02:00
parent 263b0642f4
commit 2c2bfd3489

View File

@ -202,14 +202,20 @@ struct PreparedGame {
corners: [Option<u8>; 4], corners: [Option<u8>; 4],
cardinals: [Option<u8>; 4], cardinals: [Option<u8>; 4],
corner_first: bool, corner_first: bool,
food_spawns: Vec<Option<FoodSpawn>>, food_spawns: Vec<FoodSpawn>,
food_chance: u8, food_chance: u8,
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum FoodSpawn { enum FoodSpawn {
/// No food was spawned
None,
/// Some food was spawned because it would go under `min_food` otherwise
Forced { selected: u16, free_spots: u16 }, Forced { selected: u16, free_spots: u16 },
/// Some food was spawned by chance
Random { selected: u16, free_spots: u16 }, Random { selected: u16, free_spots: u16 },
/// No food was spawned because there is no space on the board
Blocked,
} }
impl PreparedGame { impl PreparedGame {
@ -269,9 +275,14 @@ impl PreparedGame {
} }
}) })
.map(|(previous, next)| { .map(|(previous, next)| {
// no new food, no food eaten let mut tmp = next.clone();
if previous.board.food == next.board.food { tmp.board.food.clone_from(&previous.board.food);
return None; let heads: Vec<_> = tmp.board.snakes.iter().map(|snake| snake.head).collect();
tmp.board.food.retain(|coord| !heads.contains(coord));
let free_spots = get_unoccupied_points(&tmp);
if free_spots.is_empty() {
return FoodSpawn::Blocked;
} }
let diff: Vec<_> = next let diff: Vec<_> = next
@ -282,15 +293,9 @@ impl PreparedGame {
.collect(); .collect();
if diff.is_empty() { if diff.is_empty() {
// We didn't spawn any food. It was only eaten // We didn't spawn any food. It was only eaten
return None; return FoodSpawn::None;
} }
let mut tmp = next.clone();
tmp.board.food.clone_from(&previous.board.food);
let heads: Vec<_> = tmp.board.snakes.iter().map(|snake| snake.head).collect();
tmp.board.food.retain(|coord| !heads.contains(coord));
let free_spots = get_unoccupied_points(&tmp);
let selected = free_spots let selected = free_spots
.iter() .iter()
.position(|spot| spot == diff[0]) .position(|spot| spot == diff[0])
@ -299,15 +304,15 @@ impl PreparedGame {
let free_spots = free_spots.len().az(); let free_spots = free_spots.len().az();
if next.board.food.len() == usize::from(food_min) { if next.board.food.len() == usize::from(food_min) {
Some(FoodSpawn::Forced { FoodSpawn::Forced {
selected, selected,
free_spots, free_spots,
}) }
} else { } else {
Some(FoodSpawn::Random { FoodSpawn::Random {
selected, selected,
free_spots, free_spots,
}) }
} }
}) })
.collect(); .collect();
@ -360,16 +365,14 @@ impl PreparedGame {
let rand = get_rand(input_rand, seed, (turn).az()); let rand = get_rand(input_rand, seed, (turn).az());
match spawn { match spawn {
Some( spawn @ (FoodSpawn::Forced {
spawn @ (FoodSpawn::Forced { selected,
selected, free_spots,
free_spots, }
} | FoodSpawn::Random {
| FoodSpawn::Random { selected,
selected, free_spots,
free_spots, }) => {
}),
) => {
if matches!(spawn, FoodSpawn::Random { .. }) if matches!(spawn, FoodSpawn::Random { .. })
&& 100 - rand.int_n(100) >= usize::from(self.food_chance) && 100 - rand.int_n(100) >= usize::from(self.food_chance)
{ {
@ -387,13 +390,17 @@ impl PreparedGame {
} }
correct correct
} }
None => { FoodSpawn::None => {
let correct = 100 - rand.int_n(100) >= usize::from(self.food_chance); let correct = 100 - rand.int_n(100) >= usize::from(self.food_chance);
if log && !correct { if log && !correct {
error!("Food spawned, when none should have been spawned"); error!("Food spawned, when none should have been spawned");
} }
correct correct
} }
FoodSpawn::Blocked => {
// We can't get any info if there isn't even a chance for food
true
}
} }
}) })
} }