This commit is contained in:
		
							
								
								
									
										22
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										22
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -173,8 +173,10 @@ version = "2.0.0" | ||||
| dependencies = [ | ||||
|  "axum", | ||||
|  "bitvec", | ||||
|  "enum-iterator", | ||||
|  "env_logger", | ||||
|  "log", | ||||
|  "rand", | ||||
|  "serde", | ||||
|  "tokio", | ||||
| ] | ||||
| @@ -299,6 +301,26 @@ dependencies = [ | ||||
|  "cfg-if", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "enum-iterator" | ||||
| version = "2.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" | ||||
| dependencies = [ | ||||
|  "enum-iterator-derive", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "enum-iterator-derive" | ||||
| version = "1.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "env_filter" | ||||
| version = "0.1.3" | ||||
|   | ||||
| @@ -27,3 +27,5 @@ env_logger = "0.11" | ||||
|  | ||||
| # other | ||||
| bitvec = "1.0" | ||||
| enum-iterator = "2.1" | ||||
| rand = "0.8" | ||||
|   | ||||
| @@ -6,7 +6,8 @@ use axum::{ | ||||
|     routing::{get, post}, | ||||
|     Router, | ||||
| }; | ||||
| use log::{debug, info}; | ||||
| use log::{debug, info, warn}; | ||||
| use rand::prelude::*; | ||||
| use serde::Serialize; | ||||
| use tokio::net::TcpListener; | ||||
| use types::{ | ||||
| @@ -62,8 +63,15 @@ async fn start(request: Json<Request>) { | ||||
| async fn get_move(request: Json<Request>) -> response::Json<Response> { | ||||
|     let board = Board::from(&*request); | ||||
|     info!("got move request: {board}"); | ||||
|     let actions = board.valid_actions(0).collect::<Vec<_>>(); | ||||
|     info!("valid actions: {:?}", actions); | ||||
|     let action = actions.choose(&mut thread_rng()).copied(); | ||||
|     if action.is_none() { | ||||
|         warn!("unable to find a valid action"); | ||||
|     } | ||||
|     info!("chose {action:?}"); | ||||
|     response::Json(Response { | ||||
|         direction: Direction::Up, | ||||
|         direction: action.unwrap_or(Direction::Up), | ||||
|         shout: None, | ||||
|     }) | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| use enum_iterator::Sequence; | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| pub mod simulation; | ||||
| @@ -9,7 +10,19 @@ pub struct Coord { | ||||
|     y: u8, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)] | ||||
| impl Coord { | ||||
|     pub fn apply(self, direction: Direction) -> Option<Self> { | ||||
|         match direction { | ||||
|             Direction::Up => self.y.checked_add(1).map(|y| Self { y, x: self.x }), | ||||
|             Direction::Down => self.y.checked_sub(1).map(|y| Self { y, x: self.x }), | ||||
|             Direction::Left => self.x.checked_sub(1).map(|x| Self { x, y: self.y }), | ||||
|             Direction::Right => self.x.checked_add(1).map(|x| Self { x, y: self.y }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Sequence)] | ||||
| #[serde(rename_all = "lowercase")] | ||||
| pub enum Direction { | ||||
|     /// Move in positive y direction | ||||
|     Up, | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| use std::{collections::VecDeque, fmt::Display}; | ||||
|  | ||||
| use bitvec::prelude::*; | ||||
| use log::error; | ||||
| use log::{error, warn}; | ||||
|  | ||||
| use super::{wire::Request, Coord}; | ||||
| use super::{wire::Request, Coord, Direction}; | ||||
|  | ||||
| #[derive(Debug, PartialEq, Eq, Clone)] | ||||
| pub struct Board { | ||||
| @@ -123,9 +123,31 @@ impl Board { | ||||
|         self.hazard[index] | ||||
|     } | ||||
|  | ||||
|     pub fn is_blocked(&self, tile: Coord) -> bool { | ||||
|     pub fn is_free(&self, tile: Coord) -> bool { | ||||
|         let index = usize::from(self.coord_to_linear(tile)); | ||||
|         !self.free[index] | ||||
|         self.free[index] | ||||
|     } | ||||
|  | ||||
|     pub fn valid_actions(&self, id: u8) -> impl Iterator<Item = Direction> + use<'_> { | ||||
|         let head = self | ||||
|             .snakes | ||||
|             .binary_search_by_key(&id, |snake| snake.id) | ||||
|             .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>() | ||||
|             .filter_map(move |direction| { | ||||
|                 head.and_then(|head| head.apply(direction)) | ||||
|                     .map(|tile| (direction, tile)) | ||||
|             }) | ||||
|             .filter(|(_, tile)| tile.x < self.width && tile.y < self.height) | ||||
|             .filter(|(_, tile)| self.is_free(*tile)) | ||||
|             .map(|(direction, _)| direction) | ||||
|     } | ||||
|  | ||||
|     fn coord_to_linear(&self, coord: Coord) -> u16 { | ||||
| @@ -140,18 +162,6 @@ struct Snake { | ||||
|     body: VecDeque<Coord>, | ||||
| } | ||||
|  | ||||
| impl PartialOrd for Snake { | ||||
|     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||||
|         Some(self.cmp(other)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Ord for Snake { | ||||
|     fn cmp(&self, other: &Self) -> std::cmp::Ordering { | ||||
|         self.id.cmp(&other.id) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Snake { | ||||
|     pub fn head(&self) -> Coord { | ||||
|         self.body.front().copied().unwrap_or_else(|| { | ||||
| @@ -161,7 +171,7 @@ impl Snake { | ||||
|     } | ||||
|  | ||||
|     pub fn tail(&self) -> Coord { | ||||
|         self.body.front().copied().unwrap_or_else(|| { | ||||
|         self.body.back().copied().unwrap_or_else(|| { | ||||
|             error!("Snake without a tail: {self:?}"); | ||||
|             Coord { x: 0, y: 0 } | ||||
|         }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user