refactor map generation into its own file

This commit is contained in:
Michael Zhang 2023-12-30 04:39:55 -05:00
parent 74b4c64023
commit eb9dca70a6
5 changed files with 69 additions and 31 deletions

1
Cargo.lock generated
View file

@ -266,6 +266,7 @@ dependencies = [
"names",
"petgraph 0.6.4",
"prisma-client-rust",
"rand 0.8.5",
"serde",
"serde_json",
"tokio",

View file

@ -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"

View file

@ -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<GameCoreState> {
pub struct Map {
pub star_systems: HashMap<StarSystemId, StarSystemCoreState>,
pub hyperlanes: UnGraphMap<usize, ()>,
}
pub fn generate_map() -> Result<Map> {
// 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::<f64>() > 0.7
}
})
.collect();
Ok(Map {
star_systems,
hyperlanes,
hyperlanes: final_hyperlanes,
})
}

View file

@ -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<GameCoreState> {
// 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,
})
}

View file

@ -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};