124 lines
2.8 KiB
Rust
124 lines
2.8 KiB
Rust
use log::info;
|
|
use rocket::fairing::AdHoc;
|
|
use rocket::http::Status;
|
|
use rocket::serde::{json::Json, Deserialize};
|
|
use rocket::{get, launch, post, routes};
|
|
use serde::Serialize;
|
|
use serde_json::Value;
|
|
use std::collections::HashMap;
|
|
use std::env;
|
|
|
|
mod logic;
|
|
|
|
// API and Response Objects
|
|
// See https://docs.battlesnake.com/api
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
pub struct Game {
|
|
id: String,
|
|
ruleset: HashMap<String, Value>,
|
|
timeout: u32,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
pub struct Board {
|
|
height: u32,
|
|
width: i32,
|
|
food: Vec<Coord>,
|
|
snakes: Vec<Battlesnake>,
|
|
hazards: Vec<Coord>,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
pub struct Battlesnake {
|
|
id: String,
|
|
name: String,
|
|
health: i32,
|
|
body: Vec<Coord>,
|
|
head: Coord,
|
|
length: i32,
|
|
latency: String,
|
|
shout: Option<String>,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
pub struct Coord {
|
|
x: i32,
|
|
y: i32,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
pub struct GameState {
|
|
game: Game,
|
|
turn: i32,
|
|
board: Board,
|
|
you: Battlesnake,
|
|
}
|
|
|
|
#[get("/")]
|
|
fn handle_index() -> Json<Value> {
|
|
Json(logic::info())
|
|
}
|
|
|
|
#[post("/start", format = "json", data = "<start_req>")]
|
|
fn handle_start(start_req: Json<GameState>) -> Status {
|
|
logic::start(
|
|
&start_req.game,
|
|
&start_req.turn,
|
|
&start_req.board,
|
|
&start_req.you,
|
|
);
|
|
|
|
Status::Ok
|
|
}
|
|
|
|
#[post("/move", format = "json", data = "<move_req>")]
|
|
fn handle_move(move_req: Json<GameState>) -> Json<Value> {
|
|
let response = logic::get_move(
|
|
&move_req.game,
|
|
&move_req.turn,
|
|
&move_req.board,
|
|
&move_req.you,
|
|
);
|
|
|
|
Json(response)
|
|
}
|
|
|
|
#[post("/end", format = "json", data = "<end_req>")]
|
|
fn handle_end(end_req: Json<GameState>) -> Status {
|
|
logic::end(&end_req.game, &end_req.turn, &end_req.board, &end_req.you);
|
|
|
|
Status::Ok
|
|
}
|
|
|
|
#[launch]
|
|
fn rocket() -> _ {
|
|
// Lots of web hosting services expect you to bind to the port specified by the `PORT`
|
|
// environment variable. However, Rocket looks at the `ROCKET_PORT` environment variable.
|
|
// If we find a value for `PORT`, we set `ROCKET_PORT` to that value.
|
|
if let Ok(port) = env::var("PORT") {
|
|
env::set_var("ROCKET_PORT", &port);
|
|
}
|
|
|
|
// We default to 'info' level logging. But if the `RUST_LOG` environment variable is set,
|
|
// we keep that value instead.
|
|
if env::var("RUST_LOG").is_err() {
|
|
env::set_var("RUST_LOG", "info");
|
|
}
|
|
|
|
env_logger::init();
|
|
|
|
info!("Starting Battlesnake Server...");
|
|
|
|
rocket::build()
|
|
.attach(AdHoc::on_response("Server ID Middleware", |_, res| {
|
|
Box::pin(async move {
|
|
res.set_raw_header("Server", "battlesnake/github/starter-snake-rust");
|
|
})
|
|
}))
|
|
.mount(
|
|
"/",
|
|
routes![handle_index, handle_start, handle_move, handle_end],
|
|
)
|
|
}
|