This commit is contained in:
@ -202,14 +202,20 @@ struct PreparedGame {
|
||||
corners: [Option<u8>; 4],
|
||||
cardinals: [Option<u8>; 4],
|
||||
corner_first: bool,
|
||||
food_spawns: Vec<Option<FoodSpawn>>,
|
||||
food_spawns: Vec<FoodSpawn>,
|
||||
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
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user