Compare commits
No commits in common. "9c76df1f69a75848ee7efd241bf878ff2985cb9e" and "f9e34d119a45414e69cfb73982b064141f4f84c4" have entirely different histories.
9c76df1f69
...
f9e34d119a
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -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"
|
||||||
|
@ -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
4
battlesnake/Rocket.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[default]
|
||||||
|
address = "0.0.0.0"
|
||||||
|
port = 8000
|
||||||
|
keep_alive = 0
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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 }
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user