chore(simulation): cargo fmt atlas modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,10 +21,9 @@
|
||||
use crate::atlas::block_irregularity::block_irregularity;
|
||||
use crate::atlas::district_mix::{compute_district_mix, population_tier};
|
||||
use crate::simulation::generator::{
|
||||
BlockPlacement, BlockSkeleton, ComplexityTier, DistrictId, DistrictLayoutMode,
|
||||
DistrictSkeleton, DistrictType, MultiBlockReservation, PoliticalArchetype,
|
||||
BlockPlacement, BlockSkeleton, CityGenerationContext, ComplexityTier, DistrictId,
|
||||
DistrictLayoutMode, DistrictSkeleton, DistrictType, MultiBlockReservation, PoliticalArchetype,
|
||||
ReservationFunction, ReservationId, SettingType, WorldTier, ZoningType,
|
||||
CityGenerationContext,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -76,8 +75,7 @@ pub fn generate_skeleton(
|
||||
let reservations = derive_reservations(tier, economic_role, seed);
|
||||
|
||||
// Build the reservation lookup: block position → reservation id.
|
||||
let mut block_reservation: [[Option<ReservationId>; 4]; 4] =
|
||||
[[None, None, None, None]; 4];
|
||||
let mut block_reservation: [[Option<ReservationId>; 4]; 4] = [[None, None, None, None]; 4];
|
||||
for (idx, res) in reservations.iter().enumerate() {
|
||||
let rid = idx as u64 + 1; // 1-based stable id within this district
|
||||
for &(row, col) in &res.blocks {
|
||||
@@ -92,7 +90,10 @@ pub fn generate_skeleton(
|
||||
// ── Build 4×4 block grid ──────────────────────────────────────────────
|
||||
// Flat district-mix list is already in deterministic order; assign
|
||||
// row-major (row 0 col 0 → row 0 col 3 → row 1 col 0 …).
|
||||
let primary_district_type = mix.districts.first().cloned()
|
||||
let primary_district_type = mix
|
||||
.districts
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or(DistrictType::MixedUse);
|
||||
let blocks = build_block_grid(&mix.districts, &block_reservation, &primary_district_type);
|
||||
|
||||
@@ -190,10 +191,18 @@ fn derive_complexity(world_tier: &WorldTier, pop_tier: u8, population: i64) -> C
|
||||
|
||||
match world_tier {
|
||||
WorldTier::Epicenter | WorldTier::Regional => {
|
||||
if pop_tier >= 1 { ComplexityTier::Full } else { ComplexityTier::Moderate }
|
||||
if pop_tier >= 1 {
|
||||
ComplexityTier::Full
|
||||
} else {
|
||||
ComplexityTier::Moderate
|
||||
}
|
||||
}
|
||||
WorldTier::Backwater | WorldTier::Passage => {
|
||||
if pop_tier >= 1 { ComplexityTier::Moderate } else { ComplexityTier::Minimal }
|
||||
if pop_tier >= 1 {
|
||||
ComplexityTier::Moderate
|
||||
} else {
|
||||
ComplexityTier::Minimal
|
||||
}
|
||||
}
|
||||
WorldTier::Waypoint => ComplexityTier::Minimal,
|
||||
}
|
||||
@@ -245,7 +254,7 @@ fn organic_placements(irregularity: f32, seed: u64) -> [[BlockPlacement; 4]; 4]
|
||||
let raw_x = (lcg.next_u32() % (2 * max_offset as u32 + 1)) as i16 - max_offset;
|
||||
let raw_y = (lcg.next_u32() % (2 * max_offset as u32 + 1)) as i16 - max_offset;
|
||||
let rot = (lcg.next_u32() % 4) as u8; // 0–3 (15° increments, max 45°)
|
||||
// Street width 7500–20000 bps proportional to irregularity.
|
||||
// Street width 7500–20000 bps proportional to irregularity.
|
||||
let width_range = 12_500u32; // 20000 - 7500
|
||||
let width = 7_500u32 + (lcg.next_u32() % (width_range + 1));
|
||||
*item = BlockPlacement {
|
||||
@@ -256,9 +265,7 @@ fn organic_placements(irregularity: f32, seed: u64) -> [[BlockPlacement; 4]; 4]
|
||||
}
|
||||
|
||||
// Safety: BlockPlacement is Copy-able; reshape flat array to [[_; 4]; 4].
|
||||
core::array::from_fn(|row| {
|
||||
core::array::from_fn(|col| flat[row * 4 + col].clone())
|
||||
})
|
||||
core::array::from_fn(|row| core::array::from_fn(|col| flat[row * 4 + col].clone()))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -311,9 +318,9 @@ fn build_block_grid(
|
||||
position: (row as u8, col as u8),
|
||||
zoning,
|
||||
reservation,
|
||||
chunk_layout: String::new(), // stub
|
||||
chunk_layout: String::new(), // stub
|
||||
hosted_sites: Vec::new(),
|
||||
era: String::new(), // stub
|
||||
era: String::new(), // stub
|
||||
era_modifications: Vec::new(),
|
||||
era_cause: None,
|
||||
density_pct: density,
|
||||
@@ -349,7 +356,11 @@ fn density_for_zoning(zoning: &ZoningType) -> u8 {
|
||||
///
|
||||
/// Phase 1 produces skeleton-only reservations — floor_zones and vertical_corridors
|
||||
/// are deferred to Phase 2.
|
||||
fn derive_reservations(pop_tier: u8, economic_role: &str, _seed: u64) -> Vec<MultiBlockReservation> {
|
||||
fn derive_reservations(
|
||||
pop_tier: u8,
|
||||
economic_role: &str,
|
||||
_seed: u64,
|
||||
) -> Vec<MultiBlockReservation> {
|
||||
let mut out = Vec::new();
|
||||
|
||||
// Park: large cities need open space.
|
||||
@@ -398,11 +409,14 @@ struct SkeletonLcg {
|
||||
impl SkeletonLcg {
|
||||
fn new(seed: u64) -> Self {
|
||||
// Mix seed to avoid degenerate state at 0.
|
||||
Self { state: seed.wrapping_add(0x9e37_79b9_7f4a_7c15) }
|
||||
Self {
|
||||
state: seed.wrapping_add(0x9e37_79b9_7f4a_7c15),
|
||||
}
|
||||
}
|
||||
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
self.state = self.state
|
||||
self.state = self
|
||||
.state
|
||||
.wrapping_mul(6364136223846793005)
|
||||
.wrapping_add(1442695040888963407);
|
||||
self.state
|
||||
@@ -516,7 +530,9 @@ mod tests {
|
||||
let ctx = make_context(PoliticalArchetype::Commission, WorldTier::Epicenter);
|
||||
// 100M pop → pop_tier 2 → park reservation.
|
||||
let sk = generate_skeleton(&ctx, 100_000_000, "financial", 1, 300, 42);
|
||||
let has_park = sk.reservations.iter()
|
||||
let has_park = sk
|
||||
.reservations
|
||||
.iter()
|
||||
.any(|r| matches!(r.function, ReservationFunction::Park));
|
||||
assert!(has_park);
|
||||
}
|
||||
@@ -526,7 +542,9 @@ mod tests {
|
||||
let ctx = make_context(PoliticalArchetype::Commission, WorldTier::Regional);
|
||||
// pop_tier 0 but transit_hub → terminal reservation.
|
||||
let sk = generate_skeleton(&ctx, 80_000, "transit_hub", 1, 200, 42);
|
||||
let has_terminal = sk.reservations.iter()
|
||||
let has_terminal = sk
|
||||
.reservations
|
||||
.iter()
|
||||
.any(|r| matches!(r.function, ReservationFunction::Terminal));
|
||||
assert!(has_terminal);
|
||||
}
|
||||
@@ -539,7 +557,10 @@ mod tests {
|
||||
// All park blocks must reference the park reservation (id=1).
|
||||
for &(row, col) in &[(1u8, 2u8), (1, 3), (2, 2), (2, 3)] {
|
||||
let b = &sk.blocks[row as usize][col as usize];
|
||||
assert!(b.reservation.is_some(), "block ({row},{col}) should be reserved");
|
||||
assert!(
|
||||
b.reservation.is_some(),
|
||||
"block ({row},{col}) should be reserved"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,7 +574,10 @@ mod tests {
|
||||
for col in 0..4 {
|
||||
assert_eq!(sk1.blocks[row][col].zoning, sk2.blocks[row][col].zoning);
|
||||
assert_eq!(sk1.blocks[row][col].position, sk2.blocks[row][col].position);
|
||||
assert_eq!(sk1.blocks[row][col].density_pct, sk2.blocks[row][col].density_pct);
|
||||
assert_eq!(
|
||||
sk1.blocks[row][col].density_pct,
|
||||
sk2.blocks[row][col].density_pct
|
||||
);
|
||||
}
|
||||
}
|
||||
assert_eq!(sk1.reservations.len(), sk2.reservations.len());
|
||||
|
||||
Reference in New Issue
Block a user