diff --git a/battlesnake/src/logic.rs b/battlesnake/src/logic.rs index 0967765..94a607b 100644 --- a/battlesnake/src/logic.rs +++ b/battlesnake/src/logic.rs @@ -30,7 +30,8 @@ use crate::{ // info is called when you create your Battlesnake on play.battlesnake.com // and controls your Battlesnake's appearance // TIP: If you open your Battlesnake URL in a browser you should see this data -#[must_use] pub fn info() -> Value { +#[must_use] +pub fn info() -> Value { info!("INFO"); json!({ diff --git a/battlesnake/src/main.rs b/battlesnake/src/main.rs index c8b5868..8d26b99 100644 --- a/battlesnake/src/main.rs +++ b/battlesnake/src/main.rs @@ -3,12 +3,7 @@ use battlesnake::{logic, Action, GameState}; use log::{error, info}; use rocket::{ - fairing::AdHoc, - get, - http::Status, - launch, post, routes, - serde::json::Json, - tokio::task, + fairing::AdHoc, get, http::Status, launch, post, routes, serde::json::Json, tokio::task, }; use serde_json::Value; use std::env; diff --git a/battlesnake/src/simulation.rs b/battlesnake/src/simulation.rs index 164a22a..85ddb4a 100644 --- a/battlesnake/src/simulation.rs +++ b/battlesnake/src/simulation.rs @@ -14,7 +14,13 @@ pub struct SnakeToken { } impl SnakeToken { - #[must_use] pub fn from_board(board: &crate::Board) -> BTreeMap { + /// create a token map from the current game board. + /// + /// # Panics + /// + /// This function panics when there are more than 256 snakes on the board. + #[must_use] + pub fn from_board(board: &crate::Board) -> BTreeMap { board .snakes .iter() @@ -52,7 +58,8 @@ pub struct Board { } impl Board { - #[must_use] pub fn from_game_board( + #[must_use] + pub fn from_game_board( board: &crate::Board, token_map: &BTreeMap, turn: i32, @@ -86,16 +93,19 @@ impl Board { } } - #[must_use] pub const fn turn(&self) -> i32 { + #[must_use] + pub const fn turn(&self) -> i32 { self.turn } #[allow(clippy::cast_sign_loss)] - #[must_use] pub const fn spaces(&self) -> usize { + #[must_use] + pub const fn spaces(&self) -> usize { self.height as usize * self.width as usize } - #[must_use] pub fn alive_snakes(&self) -> usize { + #[must_use] + pub fn alive_snakes(&self) -> usize { self.snakes.len() } @@ -103,7 +113,8 @@ impl Board { self.snakes.keys().copied() } - #[must_use] pub fn snake_length(&self, token: SnakeToken) -> Option { + #[must_use] + pub fn snake_length(&self, token: SnakeToken) -> Option { self.snakes.get(&token).map(|snake| snake.body.len()) } @@ -196,7 +207,8 @@ impl Board { } } - #[must_use] pub fn possible_actions(&self) -> BTreeMap> { + #[must_use] + pub fn possible_actions(&self) -> BTreeMap> { let mut actions: BTreeMap<_, BTreeSet<_>> = self .snakes .keys() @@ -236,11 +248,12 @@ impl Board { .iter() .sorted_unstable_by(|(_, snake1), (_, snake2)| snake2.health.cmp(&snake1.health)) .map(|(token, snake)| { - if actions[token].len() == 1 { - ( - snake.body.len(), - Some(snake.head().move_to(*actions[token].first().unwrap())), - ) + let actions = &actions[token]; + if actions.len() == 1 { + let Some(action) = actions.first() else { + unreachable!() + }; + (snake.body.len(), Some(snake.head().move_to(*action))) } else { (snake.body.len(), None) } @@ -272,11 +285,14 @@ pub struct Battlesnake { } impl Battlesnake { - #[must_use] pub fn from_game_snake(snake: &crate::Battlesnake) -> Self { + #[must_use] + pub fn from_game_snake(snake: &crate::Battlesnake) -> Self { let body: VecDeque<_> = snake.body.iter().copied().collect(); - debug_assert_eq!(body.len(), usize::try_from(snake.length).unwrap()); + debug_assert_eq!(Ok(body.len()), usize::try_from(snake.length)); debug_assert!(snake.health <= crate::MAX_HEALTH); - let health = u8::try_from(snake.health).expect("max health is 100"); + let Ok(health) = u8::try_from(snake.health.min(100)) else { + unreachable!() + }; Self { health, body } } @@ -295,8 +311,9 @@ impl Battlesnake { self.health = self.health.saturating_sub(1); } - #[must_use] pub fn head(&self) -> &Coord { + #[must_use] + pub fn head(&self) -> &Coord { debug_assert!(!self.body.is_empty()); - self.body.front().expect("not empty") + self.body.front().unwrap_or_else(|| unreachable!()) } }