Compare commits

..

No commits in common. "9c76df1f69a75848ee7efd241bf878ff2985cb9e" and "f9e34d119a45414e69cfb73982b064141f4f84c4" have entirely different histories.

6 changed files with 24 additions and 75 deletions

22
Cargo.lock generated
View File

@ -173,10 +173,8 @@ version = "2.0.0"
dependencies = [ dependencies = [
"axum", "axum",
"bitvec", "bitvec",
"enum-iterator",
"env_logger", "env_logger",
"log", "log",
"rand",
"serde", "serde",
"tokio", "tokio",
] ]
@ -301,26 +299,6 @@ dependencies = [
"cfg-if", "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]] [[package]]
name = "env_filter" name = "env_filter"
version = "0.1.3" version = "0.1.3"

View File

@ -27,5 +27,3 @@ env_logger = "0.11"
# other # other
bitvec = "1.0" bitvec = "1.0"
enum-iterator = "2.1"
rand = "0.8"

4
battlesnake/Rocket.toml Normal file
View File

@ -0,0 +1,4 @@
[default]
address = "0.0.0.0"
port = 8000
keep_alive = 0

View File

@ -6,8 +6,7 @@ use axum::{
routing::{get, post}, routing::{get, post},
Router, Router,
}; };
use log::{debug, info, warn}; use log::{debug, info};
use rand::prelude::*;
use serde::Serialize; use serde::Serialize;
use tokio::net::TcpListener; use tokio::net::TcpListener;
use types::{ use types::{
@ -63,15 +62,8 @@ async fn start(request: Json<Request>) {
async fn get_move(request: Json<Request>) -> response::Json<Response> { async fn get_move(request: Json<Request>) -> response::Json<Response> {
let board = Board::from(&*request); let board = Board::from(&*request);
info!("got move request: {board}"); 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 { response::Json(Response {
direction: action.unwrap_or(Direction::Up), direction: Direction::Up,
shout: None, shout: None,
}) })
} }

View File

@ -1,4 +1,3 @@
use enum_iterator::Sequence;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub mod simulation; pub mod simulation;
@ -10,19 +9,7 @@ pub struct Coord {
y: u8, y: u8,
} }
impl Coord { #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)]
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 { pub enum Direction {
/// Move in positive y direction /// Move in positive y direction
Up, Up,

View File

@ -1,9 +1,9 @@
use std::{collections::VecDeque, fmt::Display}; use std::{collections::VecDeque, fmt::Display};
use bitvec::prelude::*; use bitvec::prelude::*;
use log::{error, warn}; use log::error;
use super::{wire::Request, Coord, Direction}; use super::{wire::Request, Coord};
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct Board { pub struct Board {
@ -123,31 +123,9 @@ impl Board {
self.hazard[index] self.hazard[index]
} }
pub fn is_free(&self, tile: Coord) -> bool { pub fn is_blocked(&self, tile: Coord) -> bool {
let index = usize::from(self.coord_to_linear(tile)); 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 { fn coord_to_linear(&self, coord: Coord) -> u16 {
@ -162,6 +140,18 @@ struct Snake {
body: VecDeque<Coord>, 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 { impl Snake {
pub fn head(&self) -> Coord { pub fn head(&self) -> Coord {
self.body.front().copied().unwrap_or_else(|| { self.body.front().copied().unwrap_or_else(|| {
@ -171,7 +161,7 @@ impl Snake {
} }
pub fn tail(&self) -> Coord { pub fn tail(&self) -> Coord {
self.body.back().copied().unwrap_or_else(|| { self.body.front().copied().unwrap_or_else(|| {
error!("Snake without a tail: {self:?}"); error!("Snake without a tail: {self:?}");
Coord { x: 0, y: 0 } Coord { x: 0, y: 0 }
}) })