skip calculating index from id when index already present
All checks were successful
Build / build (push) Successful in 1m59s

This commit is contained in:
Max Känner 2025-01-21 22:40:01 +01:00
parent ea96a0eb0d
commit 108aeaa49d

View File

@ -204,25 +204,19 @@ impl Board {
} }
pub fn valid_actions(&self, id: u8) -> impl Iterator<Item = Direction> + use<'_> { pub fn valid_actions(&self, id: u8) -> impl Iterator<Item = Direction> + use<'_> {
let head = self let index = self.snakes.binary_search_by_key(&id, |snake| snake.id).ok();
.snakes if index.is_none() {
.binary_search_by_key(&id, |snake| snake.id) warn!("Asked for a snake that doesn't exist");
.ok()
.map(|index| self.snakes[index].head());
if head.is_none() {
warn!(
"Asked for an action for a snake that doesn't exist: {id} not in {:?}",
self.snakes
);
} }
enum_iterator::all::<Direction>() index
.filter_map(move |direction| { .into_iter()
head.and_then(|head| head.apply(direction)) .flat_map(|index| self.valid_actions_index(index))
.map(|tile| (direction, tile)) }
})
.filter(|(_, tile)| tile.x < self.width && tile.y < self.height) pub fn random_actions(
.filter(|(_, tile)| self.is_free(*tile)) &self,
.map(|(direction, _)| direction) ) -> impl Iterator<Item = (u8, impl Iterator<Item = Direction> + use<'_>)> {
(0..self.snakes.len()).map(|index| (self.snakes[index].id, self.valid_actions_index(index)))
} }
pub fn simulate_random<T>(&mut self, stop: impl Fn(&Self) -> Option<T>) -> T { pub fn simulate_random<T>(&mut self, stop: impl Fn(&Self) -> Option<T>) -> T {
@ -245,12 +239,21 @@ impl Board {
self.turn += 1; self.turn += 1;
} }
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)
}
fn move_standard(&mut self, actions: &[(u8, Direction)]) { fn move_standard(&mut self, actions: &[(u8, Direction)]) {
for i in 0..self.snakes.len() { for i in 0..self.snakes.len() {
let snake = &self.snakes[i]; let snake = &self.snakes[i];
let action = actions.iter().find(|(id, _)| *id == snake.id).map_or_else( let action = actions.iter().find(|(id, _)| *id == snake.id).map_or_else(
|| { || {
self.valid_actions(snake.id) self.valid_actions_index(i)
.choose(&mut thread_rng()) .choose(&mut thread_rng())
.unwrap_or(Direction::Up) .unwrap_or(Direction::Up)
}, },