From eb9dca70a69e62393f60c5bd0058e76308f22593 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sat, 30 Dec 2023 04:39:55 -0500 Subject: [PATCH] refactor map generation into its own file --- Cargo.lock | 1 + backend/Cargo.toml | 1 + backend/src/{generate.rs => generate/map.rs} | 56 +++++++++----------- backend/src/generate/mod.rs | 40 ++++++++++++++ backend/src/state/game.rs | 2 +- 5 files changed, 69 insertions(+), 31 deletions(-) rename backend/src/{generate.rs => generate/map.rs} (59%) create mode 100644 backend/src/generate/mod.rs diff --git a/Cargo.lock b/Cargo.lock index e90b9ac..167c461 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,6 +266,7 @@ dependencies = [ "names", "petgraph 0.6.4", "prisma-client-rust", + "rand 0.8.5", "serde", "serde_json", "tokio", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 0673470..deb04d0 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -16,3 +16,4 @@ tokio = { version = "1.35.1", features = ["full"] } serde_json = "1.0.108" petgraph = "0.6.4" names = "0.14.0" +rand = "0.8.5" diff --git a/backend/src/generate.rs b/backend/src/generate/map.rs similarity index 59% rename from backend/src/generate.rs rename to backend/src/generate/map.rs index 642c437..ca11915 100644 --- a/backend/src/generate.rs +++ b/backend/src/generate/map.rs @@ -1,22 +1,19 @@ use std::{collections::HashMap, f64::consts::PI}; use anyhow::Result; -use chrono::Utc; -use names::Generator as NameGenerator; -use petgraph::{graph::UnGraph, graphmap::UnGraphMap}; +use petgraph::{ + algo::min_spanning_tree, data::FromElements, graphmap::UnGraphMap, +}; use triangle::{triangulate, Point, TrianglulateOpts}; -use crate::{ - prisma::PrismaClient, - state::{ - EmpireCoreState, EmpireId, GameCoreState, StarSystemCoreState, - StarSystemId, UniverseId, - }, -}; +use crate::state::{StarSystemCoreState, StarSystemId}; -pub async fn generate_initial_game_state( - client: &PrismaClient, -) -> Result { +pub struct Map { + pub star_systems: HashMap, + pub hyperlanes: UnGraphMap, +} + +pub fn generate_map() -> Result { // Generate a new triangulation let result = { // Generate a circle of points @@ -38,18 +35,6 @@ pub async fn generate_initial_game_state( )? }; - // Generate a new universe ID - let universe = client.universe().create(json!({}), vec![]).exec().await?; - - // Generate some empires - let mut empires = HashMap::new(); - let name_generator = NameGenerator::default(); - for (idx, name) in name_generator.take(10).enumerate() { - let id = EmpireId(idx as i32); - let empire = EmpireCoreState { id, name }; - empires.insert(id, empire); - } - // Format the star systems let mut star_systems = HashMap::new(); for (idx, point) in result.point_list.into_iter().enumerate() { @@ -69,11 +54,22 @@ pub async fn generate_initial_game_state( hyperlanes.add_edge(indexes[1], indexes[2], ()); } - Ok(GameCoreState { - universe_id: UniverseId(universe.id), - current_instant: Utc::now(), - empires, + // Let's just drop some random % of hyperlanes + let min_hyperlanes = + UnGraphMap::from_elements(min_spanning_tree(&hyperlanes)); + let final_hyperlanes = hyperlanes + .all_edges() + .filter(|edge| { + if min_hyperlanes.contains_edge(edge.0, edge.1) { + true + } else { + rand::random::() > 0.7 + } + }) + .collect(); + + Ok(Map { star_systems, - hyperlanes, + hyperlanes: final_hyperlanes, }) } diff --git a/backend/src/generate/mod.rs b/backend/src/generate/mod.rs new file mode 100644 index 0000000..9756d53 --- /dev/null +++ b/backend/src/generate/mod.rs @@ -0,0 +1,40 @@ +mod map; + +use std::collections::HashMap; + +use anyhow::Result; +use chrono::Utc; +use names::Generator as NameGenerator; + +use crate::{ + prisma::PrismaClient, + state::{EmpireCoreState, EmpireId, GameCoreState, UniverseId}, +}; + +use self::map::generate_map; + +pub async fn generate_initial_game_state( + client: &PrismaClient, +) -> Result { + // Generate a new universe ID + let universe = client.universe().create(json!({}), vec![]).exec().await?; + + // Generate some empires + let mut empires = HashMap::new(); + let name_generator = NameGenerator::default(); + for (idx, name) in name_generator.take(10).enumerate() { + let id = EmpireId(idx as i32); + let empire = EmpireCoreState { id, name }; + empires.insert(id, empire); + } + + let map = generate_map()?; + + Ok(GameCoreState { + universe_id: UniverseId(universe.id), + current_instant: Utc::now(), + empires, + star_systems: map.star_systems, + hyperlanes: map.hyperlanes, + }) +} diff --git a/backend/src/state/game.rs b/backend/src/state/game.rs index e225afb..ab3567a 100644 --- a/backend/src/state/game.rs +++ b/backend/src/state/game.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use anyhow::Result; use chrono::{DateTime, Utc}; -use petgraph::{graph::UnGraph, graphmap::UnGraphMap}; +use petgraph::graphmap::UnGraphMap; use crate::prisma::{empire, star_system, star_system_edges, PrismaClient};