2024-09-02 15:16:32 +02:00

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],
)
}