diff --git a/battlesnake/src/bin/seed-cracker.rs b/battlesnake/src/bin/seed-cracker.rs index 5f431e7..e008e3b 100644 --- a/battlesnake/src/bin/seed-cracker.rs +++ b/battlesnake/src/bin/seed-cracker.rs @@ -202,14 +202,20 @@ struct PreparedGame { corners: [Option; 4], cardinals: [Option; 4], corner_first: bool, - food_spawns: Vec>, + food_spawns: Vec, food_chance: u8, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] 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 }, + /// Some food was spawned by chance Random { selected: u16, free_spots: u16 }, + /// No food was spawned because there is no space on the board + Blocked, } impl PreparedGame { @@ -269,9 +275,14 @@ impl PreparedGame { } }) .map(|(previous, next)| { - // no new food, no food eaten - if previous.board.food == next.board.food { - return 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); + + if free_spots.is_empty() { + return FoodSpawn::Blocked; } let diff: Vec<_> = next @@ -282,15 +293,9 @@ impl PreparedGame { .collect(); if diff.is_empty() { // 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 .iter() .position(|spot| spot == diff[0]) @@ -299,15 +304,15 @@ impl PreparedGame { let free_spots = free_spots.len().az(); if next.board.food.len() == usize::from(food_min) { - Some(FoodSpawn::Forced { + FoodSpawn::Forced { selected, free_spots, - }) + } } else { - Some(FoodSpawn::Random { + FoodSpawn::Random { selected, free_spots, - }) + } } }) .collect(); @@ -360,16 +365,14 @@ impl PreparedGame { let rand = get_rand(input_rand, seed, (turn).az()); match spawn { - Some( - spawn @ (FoodSpawn::Forced { - selected, - free_spots, - } - | FoodSpawn::Random { - selected, - free_spots, - }), - ) => { + spawn @ (FoodSpawn::Forced { + selected, + free_spots, + } + | FoodSpawn::Random { + selected, + free_spots, + }) => { if matches!(spawn, FoodSpawn::Random { .. }) && 100 - rand.int_n(100) >= usize::from(self.food_chance) { @@ -387,13 +390,17 @@ impl PreparedGame { } correct } - None => { + FoodSpawn::None => { let correct = 100 - rand.int_n(100) >= usize::from(self.food_chance); if log && !correct { error!("Food spawned, when none should have been spawned"); } correct } + FoodSpawn::Blocked => { + // We can't get any info if there isn't even a chance for food + true + } } }) }