mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
fix(floor): #8
This commit is contained in:
parent
c4dcedd723
commit
c587371544
4
justfile
4
justfile
@ -17,3 +17,7 @@ web-dev:
|
|||||||
# Run web release
|
# Run web release
|
||||||
web-release:
|
web-release:
|
||||||
trunk serve --release --no-default-features
|
trunk serve --release --no-default-features
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
test:
|
||||||
|
RUSTC_WRAPPER=sccache RUST_BACKTRACE=full cargo nextest run --no-default-features --all-targets
|
||||||
|
|||||||
@ -39,8 +39,18 @@ impl MazeConfig {
|
|||||||
let seed = seed.unwrap_or_else(|| thread_rng().gen());
|
let seed = seed.unwrap_or_else(|| thread_rng().gen());
|
||||||
let mut rng = StdRng::seed_from_u64(seed);
|
let mut rng = StdRng::seed_from_u64(seed);
|
||||||
|
|
||||||
let start_pos = generate_pos(radius, &mut rng);
|
// Generate start and end positions ensuring they're different
|
||||||
let end_pos = generate_pos(radius, &mut rng);
|
let mut start_pos;
|
||||||
|
let mut end_pos;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
start_pos = generate_pos(radius, &mut rng);
|
||||||
|
end_pos = generate_pos(radius, &mut rng);
|
||||||
|
|
||||||
|
if start_pos != end_pos {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Start pos: (q={}, r={}). End pos: (q={}, r={})",
|
"Start pos: (q={}, r={}). End pos: (q={}, r={})",
|
||||||
@ -75,8 +85,192 @@ impl Default for MazeConfig {
|
|||||||
|
|
||||||
fn generate_pos<R: Rng>(radius: u16, rng: &mut R) -> Hex {
|
fn generate_pos<R: Rng>(radius: u16, rng: &mut R) -> Hex {
|
||||||
let radius = radius as i32;
|
let radius = radius as i32;
|
||||||
Hex::new(
|
loop {
|
||||||
rng.gen_range(-radius..radius),
|
let q = rng.gen_range(-radius..=radius);
|
||||||
rng.gen_range(-radius..radius),
|
let r = rng.gen_range(-radius..=radius);
|
||||||
)
|
|
||||||
|
let s = -q - r; // Calculate third coordinate (axial coordinates: q + r + s = 0)
|
||||||
|
|
||||||
|
// Check if the position is within the hexagonal radius
|
||||||
|
// Using the formula: max(abs(q), abs(r), abs(s)) <= radius
|
||||||
|
if q.abs().max(r.abs()).max(s.abs()) <= radius {
|
||||||
|
return Hex::new(q, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use rstest::*;
|
||||||
|
|
||||||
|
fn is_within_radius(hex: Hex, radius: u16) -> bool {
|
||||||
|
let q = hex.x;
|
||||||
|
let r = hex.y;
|
||||||
|
let s = -q - r;
|
||||||
|
q.abs().max(r.abs()).max(s.abs()) <= radius as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[fixture]
|
||||||
|
fn test_radius() -> Vec<u16> {
|
||||||
|
vec![1, 2, 5, 8]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(1)]
|
||||||
|
#[case(2)]
|
||||||
|
#[case(5)]
|
||||||
|
#[case(8)]
|
||||||
|
fn maze_config_new(#[case] radius: u16) {
|
||||||
|
let orientation = HexOrientation::Flat;
|
||||||
|
let seed = Some(12345);
|
||||||
|
let global_config = GlobalMazeConfig::default();
|
||||||
|
|
||||||
|
let config = MazeConfig::new(radius, orientation, seed, &global_config);
|
||||||
|
|
||||||
|
assert_eq!(config.radius, radius);
|
||||||
|
assert_eq!(config.seed, 12345);
|
||||||
|
assert_eq!(config.layout.orientation, orientation);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
is_within_radius(config.start_pos, radius),
|
||||||
|
"Start pos {:?} outside radius {}",
|
||||||
|
config.start_pos,
|
||||||
|
radius
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
is_within_radius(config.end_pos, radius),
|
||||||
|
"End pos {:?} outside radius {}",
|
||||||
|
config.end_pos,
|
||||||
|
radius
|
||||||
|
);
|
||||||
|
assert_ne!(config.start_pos, config.end_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(100)]
|
||||||
|
fn maze_config_default(#[case] iterations: u32) {
|
||||||
|
for _ in 0..iterations {
|
||||||
|
let config = MazeConfig::default();
|
||||||
|
|
||||||
|
assert_eq!(config.radius, 8);
|
||||||
|
assert_eq!(config.layout.orientation, HexOrientation::Flat);
|
||||||
|
assert!(is_within_radius(config.start_pos, 8));
|
||||||
|
assert!(is_within_radius(config.end_pos, 8));
|
||||||
|
assert_ne!(config.start_pos, config.end_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
fn maze_config_default_with_seeds() {
|
||||||
|
let test_seeds = [
|
||||||
|
None,
|
||||||
|
Some(0),
|
||||||
|
Some(1),
|
||||||
|
Some(12345),
|
||||||
|
Some(u64::MAX),
|
||||||
|
Some(thread_rng().gen()),
|
||||||
|
];
|
||||||
|
|
||||||
|
for seed in test_seeds {
|
||||||
|
let config =
|
||||||
|
MazeConfig::new(8, HexOrientation::Flat, seed, &GlobalMazeConfig::default());
|
||||||
|
|
||||||
|
assert_eq!(config.radius, 8);
|
||||||
|
assert_eq!(config.layout.orientation, HexOrientation::Flat);
|
||||||
|
assert!(is_within_radius(config.start_pos, 8));
|
||||||
|
assert!(is_within_radius(config.end_pos, 8));
|
||||||
|
assert_ne!(config.start_pos, config.end_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(1.0)]
|
||||||
|
#[case(2.0)]
|
||||||
|
#[case(5.0)]
|
||||||
|
fn maze_config_update(#[case] new_size: f32) {
|
||||||
|
let mut config = MazeConfig::default();
|
||||||
|
let global_config = GlobalMazeConfig {
|
||||||
|
hex_size: new_size,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
|
||||||
|
config.update(&global_config);
|
||||||
|
|
||||||
|
assert_eq!(config.layout.hex_size.x, new_size);
|
||||||
|
assert_eq!(config.layout.hex_size.y, new_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(5, 1)]
|
||||||
|
#[case(5, 12345)]
|
||||||
|
#[case(8, 67890)]
|
||||||
|
fn generate_pos_with_seed(#[case] radius: u16, #[case] seed: u64) {
|
||||||
|
let mut rng = StdRng::seed_from_u64(seed);
|
||||||
|
|
||||||
|
for _ in 0..10 {
|
||||||
|
let pos = generate_pos(radius, &mut rng);
|
||||||
|
assert!(
|
||||||
|
is_within_radius(pos, radius),
|
||||||
|
"Position {:?} outside radius {}",
|
||||||
|
pos,
|
||||||
|
radius
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn different_seeds_different_positions() {
|
||||||
|
let config1 = MazeConfig::new(
|
||||||
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
Some(1),
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
);
|
||||||
|
let config2 = MazeConfig::new(
|
||||||
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
Some(2),
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ne!(config1.start_pos, config2.start_pos);
|
||||||
|
assert_ne!(config1.end_pos, config2.end_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn same_seed_same_positions() {
|
||||||
|
let seed = Some(12345);
|
||||||
|
let config1 = MazeConfig::new(8, HexOrientation::Flat, seed, &GlobalMazeConfig::default());
|
||||||
|
let config2 = MazeConfig::new(8, HexOrientation::Flat, seed, &GlobalMazeConfig::default());
|
||||||
|
|
||||||
|
assert_eq!(config1.start_pos, config2.start_pos);
|
||||||
|
assert_eq!(config1.end_pos, config2.end_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn orientation_pointy() {
|
||||||
|
let config = MazeConfig::new(
|
||||||
|
8,
|
||||||
|
HexOrientation::Pointy,
|
||||||
|
None,
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
);
|
||||||
|
assert_eq!(config.layout.orientation, HexOrientation::Pointy);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hex_size_zero() {
|
||||||
|
let config = MazeConfig::new(
|
||||||
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
None,
|
||||||
|
&GlobalMazeConfig {
|
||||||
|
hex_size: 0.0,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert_eq!(config.layout.hex_size.x, 0.0);
|
||||||
|
assert_eq!(config.layout.hex_size.y, 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user