#![feature(proc_macro_hygiene)] extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; extern crate async_std; extern crate futures; extern crate mozaic; extern crate rand; extern crate tracing; extern crate tracing_futures; extern crate tracing_subscriber; #[macro_use] extern crate rocket; extern crate rocket_contrib; use tracing_subscriber::{EnvFilter, FmtSubscriber}; use std::net::SocketAddr; use std::{env, time}; use mozaic::modules::types::*; use mozaic::modules::{game, StepLock}; use futures::executor::ThreadPool; use futures::future::FutureExt; use mozaic::graph; use mozaic::modules::*; mod planetwars; mod routes; mod util; use rocket_contrib::templates::{Template, Engines}; use rocket_contrib::templates::tera::{self, Value}; use std::collections::HashMap; const COLOURS: [&'static str; 9] = ["grey", "blue", "cyan", "green", "yellow", "orange", "red", "pink", "purple"]; fn calc_viewbox(value: Value, _: HashMap) -> tera::Result { let mut min_x = std::f64::MAX; let mut min_y = std::f64::MAX; let mut max_x = std::f64::MIN; let mut max_y = std::f64::MIN; for v in value.as_array().unwrap() { let x = v.get("x").and_then(|v| v.as_f64()).unwrap(); let y = v.get("y").and_then(|v| v.as_f64()).unwrap(); if x < min_x { min_x = x; } if x > max_x { max_x = x; } if y < min_y { min_y = y; } if y > max_y { max_y = y; } } return Ok(Value::String(format!("{} {} {} {}", min_x - 3., min_y - 3., (max_x - min_x) + 6., (max_y - min_y) + 6.))); } fn get_colour(value: Value, _: HashMap) -> tera::Result { return Ok(Value::String(COLOURS[value.as_u64().unwrap_or(0) as usize].to_string())); } fn main() { let mut routes = Vec::new(); routes::fuel(&mut routes); let tera = Template::custom(|engines: &mut Engines| { engines.tera.register_filter("calc_viewbox", calc_viewbox); engines.tera.register_filter("get_colour", get_colour); }); rocket::ignite() .attach(tera) .mount("/", routes) .launch() .unwrap(); } // // Load the config and start the game. // #[async_std::main] // async fn main() { // let args: Vec = env::args().collect(); // let name = args[0].clone(); // match run(args).await { // None => print_info(&name), // _ => {} // }; // } fn build_builder( pool: ThreadPool, number_of_clients: u64, max_turns: u64, map: &str, location: &str, ) -> game::Builder { let config = planetwars::Config { map_file: map.to_string(), max_turns: max_turns, }; let game = planetwars::PlanetWarsGame::new(config.create_game(number_of_clients as usize), location); let players: Vec = (0..number_of_clients).collect(); game::Builder::new(players.clone(), game).with_step_lock( StepLock::new(players.clone(), pool.clone()) .with_timeout(std::time::Duration::from_secs(1)), ) } async fn run(args: Vec) -> Option<()> { let fut = graph::set_default(); let sub = FmtSubscriber::builder() .with_env_filter(EnvFilter::from_default_env()) .finish(); tracing::subscriber::set_global_default(sub).unwrap(); let addr = "127.0.0.1:9142".parse::().unwrap(); let map = args.get(1)?; let number_of_clients = args .get(2) .map(|x| x.parse().expect("Client number should be a number")) .unwrap_or(1); let location = args.get(3).map(|x| x.as_str()).unwrap_or("game.json"); let max_turns: u64 = args .get(4) .map(|x| x.parse().expect("Max turns should be a number")) .unwrap_or(500); let pool = ThreadPool::new().ok()?; pool.spawn_ok(fut.map(|_| ())); let (gmb, handle) = game::Manager::builder(pool.clone()); let ep = TcpEndpoint::new(addr, pool.clone()); let gmb = gmb.add_endpoint(ep, "TCP endpoint"); let mut gm = gmb.build(); let game_builder = build_builder(pool.clone(), number_of_clients, max_turns, map, location); std::thread::sleep(time::Duration::from_millis(3000)); let mut current_game = gm.start_game(game_builder).await.unwrap(); // loop { // match gm.get_state(current_game).await { // None => { // println!("Game finished, let's play a new one"); // let game_builder = // build_builder(pool.clone(), number_of_clients, max_turns, map, location); // current_game = gm.start_game(game_builder).await.unwrap(); // } // Some(state) => { // println!("{:?}", state); // } // } // std::thread::sleep(time::Duration::from_millis(3000)); // } handle.await; std::thread::sleep(time::Duration::from_millis(100)); Some(()) } // fn print_info(name: &str) { // println!( // "Usage: {} map_location [number_of_clients [output [max_turns]]]", // name // ); // }