pneuma/src/battlesnake.rs

179 lines
3.7 KiB
Rust

#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct MoveResponse {
#[serde(rename = "move")]
pub move_field: String,
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct StartResponse {
pub color: String,
#[serde(rename = "HeadType")]
pub head_type: String,
#[serde(rename = "TailType")]
pub tail_type: String,
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct SnakeRequest {
pub game: Game,
pub turn: i64,
pub board: Board,
pub you: Snake,
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Game {
pub id: String,
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Board {
pub height: i8,
pub width: i8,
pub food: Vec<Coord>,
pub snakes: Vec<Snake>,
}
impl Board {
pub fn inside(&self, val: &Coord) -> bool {
if val.x < 0 || val.y < 0 {
return false;
}
if val.x > self.width {
return false;
}
if val.y > self.height {
return false;
}
true
}
pub fn is_safe(&self, loc: &Coord) -> bool {
if !self.inside(loc) {return false;}
for sn in &self.snakes {
for bd in &sn.body {
if loc == bd {
return false;
}
}
}
true
}
pub fn safe_neighbors(&self, loc: &Coord) -> Vec<(Coord, usize)> {
let mut result = Vec::<(Coord, usize)>::new();
let left = loc.left();
let right = loc.right();
let up = loc.up();
let down = loc.down();
if self.is_safe(&left) {
result.push((left, 1));
}
if self.is_safe(&right) {
result.push((right, 1));
}
if self.is_safe(&up) {
result.push((up, 1));
}
if self.is_safe(&down) {
result.push((down, 1));
}
result
}
}
#[derive(Default, Debug, Copy, Clone, Eq, Hash, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Coord {
pub x: i8,
pub y: i8,
}
impl Coord {
pub fn left(&self) -> Coord {
Coord {
x: self.x - 1,
y: self.y,
}
}
pub fn right(&self) -> Coord {
Coord{
x: self.x + 1,
y: self.y,
}
}
pub fn up(&self) -> Coord {
Coord{
x: self.x,
y: self.y - 1,
}
}
pub fn down(&self) -> Coord {
Coord{
x: self.x,
y: self.y + 1,
}
}
}
pub struct Line<'a> {
pub start: &'a Coord,
pub end: &'a Coord,
}
impl Line<'_> {
pub fn manhattan(&self) -> u32 {
let abs_x = (self.end.x as i32 - self.start.y as i32).abs();
let abs_y = (self.end.y as i32 - self.start.y as i32).abs();
(abs_x - abs_y) as u32
}
pub fn direction(&self) -> &str {
if self.start.x > self.end.x {
return "left";
}
if self.start.x < self.end.x {
return "right";
}
if self.start.y > self.end.y {
return "up";
}
if self.start.y < self.end.y{
return "down";
}
"what"
}
}
pub fn manhattan<'a>(a: &'a Coord, b: &'a Coord) -> u32 {
Line{
start: &a,
end: &b,
}.manhattan()
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Snake {
pub id: String,
pub name: String,
pub health: usize,
pub body: Vec<Coord>,
}