This commit is contained in:
parent
c5097ec417
commit
1d527a89cd
@ -224,7 +224,7 @@ impl Board {
|
||||
|
||||
#[must_use]
|
||||
pub fn is_free(&self, tile: Coord) -> bool {
|
||||
if !(tile.x < self.width && tile.y < self.height) {
|
||||
if !self.is_in_bounds(tile) {
|
||||
return false;
|
||||
}
|
||||
let index = self.coord_to_linear(tile);
|
||||
@ -286,10 +286,7 @@ impl Board {
|
||||
fn valid_actions_index(&self, index: usize) -> impl Iterator<Item = Direction> + use<'_> {
|
||||
let head = self.snakes[index].head();
|
||||
enum_iterator::all::<Direction>()
|
||||
.map(move |direction| (direction, head.wrapping_apply(direction)))
|
||||
.filter(|(_, tile)| self.is_in_bounds(*tile))
|
||||
.filter(|(_, tile)| self.is_free(*tile))
|
||||
.map(|(direction, _)| direction)
|
||||
.filter(move |direction| self.is_free(head.wrapping_apply(*direction)))
|
||||
}
|
||||
|
||||
fn move_standard(&mut self, actions: &[(u8, Direction)]) {
|
||||
@ -432,44 +429,57 @@ impl Board {
|
||||
}
|
||||
|
||||
fn spawn_food(&mut self) {
|
||||
let num_food = self.food.count_ones();
|
||||
let needed_food = if num_food < usize::from(self.min_food) {
|
||||
usize::from(self.min_food) - num_food
|
||||
} else {
|
||||
usize::from(
|
||||
self.food_spawn_chance > 0 && rng().random_range(0..100) < self.food_spawn_chance,
|
||||
)
|
||||
};
|
||||
let food_needed = self.check_food_needing_placement();
|
||||
|
||||
if needed_food == 0 {
|
||||
return;
|
||||
if food_needed > 0 {
|
||||
self.place_food_randomly(food_needed);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_food_needing_placement(&self) -> u16 {
|
||||
let min_food = self.min_food;
|
||||
let food_spawn_chance = self.food_spawn_chance;
|
||||
let num_current_food = u16::try_from(self.food.count_ones()).unwrap_or(u16::MAX);
|
||||
|
||||
if num_current_food < min_food {
|
||||
return min_food - num_current_food;
|
||||
}
|
||||
if food_spawn_chance > 0 && (100 - rng().random_range(0..100)) < food_spawn_chance {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let food_spots = self
|
||||
0
|
||||
}
|
||||
|
||||
fn place_food_randomly(&mut self, amount: u16) {
|
||||
let tails: Vec<_> = self
|
||||
.snakes
|
||||
.iter()
|
||||
.map(|snake| self.coord_to_linear(snake.tail()))
|
||||
.collect();
|
||||
let possible_moves: Vec<_> = self
|
||||
.snakes
|
||||
.iter()
|
||||
.flat_map(|snake| {
|
||||
let head = snake.head();
|
||||
enum_iterator::all::<Direction>()
|
||||
.map(move |direction| head.wrapping_apply(direction))
|
||||
.filter(|tile| self.is_in_bounds(*tile))
|
||||
.map(|tile| self.coord_to_linear(tile))
|
||||
})
|
||||
.collect();
|
||||
let unoccupied_points = self
|
||||
.free
|
||||
.iter()
|
||||
.by_vals()
|
||||
.enumerate()
|
||||
.filter_map(|(i, free)| free.then_some(i))
|
||||
.filter(|i| {
|
||||
self.snakes
|
||||
.iter()
|
||||
.all(|snake| self.coord_to_linear(snake.tail()) != *i)
|
||||
})
|
||||
.filter(|i| {
|
||||
self.snakes
|
||||
.iter()
|
||||
.flat_map(|snake| {
|
||||
let head = snake.head();
|
||||
enum_iterator::all::<Direction>()
|
||||
.map(move |direction| head.wrapping_apply(direction))
|
||||
.filter(|tile| self.is_in_bounds(*tile))
|
||||
})
|
||||
.all(|action| *i != self.coord_to_linear(action))
|
||||
})
|
||||
.filter(|i| !self.food[*i])
|
||||
.choose_multiple(&mut rng(), needed_food);
|
||||
for index in food_spots {
|
||||
self.food.set(index, true);
|
||||
.zip(self.hazard.iter().by_vals())
|
||||
.filter_map(|((i, free), hazard)| (!hazard && free).then_some(i))
|
||||
.filter(|i| !tails.contains(i))
|
||||
.filter(|i| !possible_moves.contains(i));
|
||||
|
||||
for food_spot in unoccupied_points.choose_multiple(&mut rng(), usize::from(amount)) {
|
||||
self.food.set(food_spot, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user