Use rust implementation of maze generator in engine transitional_engine
authorunC0Rr
Tue, 10 Sep 2024 18:21:31 +0200
branchtransitional_engine
changeset 16062 1860852892c0
parent 16061 31cc1e450273
child 16063 09beeec033ba
Use rust implementation of maze generator in engine
hedgewars/uLand.pas
hedgewars/uLandUtils.pas
rust/landgen/src/maze.rs
rust/lib-hwengine-future/src/lib.rs
rust/mapgen/src/lib.rs
rust/mapgen/src/template/mod.rs
--- a/hedgewars/uLand.pas	Tue Sep 10 13:56:51 2024 +0200
+++ b/hedgewars/uLand.pas	Tue Sep 10 18:21:31 2024 +0200
@@ -32,7 +32,7 @@
 implementation
 uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture,
      uVariables, uUtils, uCommands, adler32, uDebug, uLandPainted, uTextures,
-     uLandGenMaze, uPhysFSLayer, uScript, uLandGenPerlin,
+     uPhysFSLayer, uScript, uLandGenPerlin,
      uLandUtils, uRenderUtils;
 
 var digest: shortstring;
@@ -794,7 +794,7 @@
         WriteLnToConsole('Generating land...');
         case cMapGen of
             mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
-            mgMaze  : begin ResizeLand(4096,2048); GenMaze; end;
+            mgMaze  : GenerateMazeLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
             mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
             mgDrawn : GenDrawnMap;
             mgForts : begin GameFlags:= (GameFlags or gfDivideTeams); MakeFortsMap(); end;
@@ -950,7 +950,7 @@
     WriteLnToConsole('Generating preview...');
     case cMapGen of
         mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
-        mgMaze: begin ResizeLand(4096,2048); GenMaze; end;
+        mgMaze: GenerateMazeLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
         mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
         mgDrawn: begin GenDrawnMap; end;
         mgForts: MakeFortsPreview();
@@ -1010,7 +1010,7 @@
     WriteLnToConsole('Generating preview...');
     case cMapGen of
         mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
-        mgMaze: begin ResizeLand(4096,2048); GenMaze; end;
+        mgMaze: GenerateMazeLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
         mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
         mgDrawn: begin GenDrawnMap; end;
         mgForts: MakeFortsPreview;
--- a/hedgewars/uLandUtils.pas	Tue Sep 10 13:56:51 2024 +0200
+++ b/hedgewars/uLandUtils.pas	Tue Sep 10 18:21:31 2024 +0200
@@ -4,6 +4,7 @@
 
 procedure GenerateOutlineTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
 procedure GenerateWfcTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
+procedure GenerateMazeLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
 procedure ResizeLand(width, height: LongWord);
 procedure DisposeLand();
 procedure InitWorldEdges();
@@ -38,6 +39,7 @@
 
 function  generate_outline_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external;
 function  generate_wfc_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external;
+function  generate_maze_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external;
 procedure apply_theme(game_field: pointer; data_path, theme_name: PChar); cdecl; external;
 
 var gameField: pointer;
@@ -127,6 +129,31 @@
     initScreenSpaceVars();
 end;
 
+procedure GenerateMazeLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
+begin
+    seed[byte(seed[0]) + 1]:= #0;
+    templateType[byte(templateType[0]) + 1]:= #0;
+
+    gameField:= generate_maze_game_field(featureSize, @seed[1], @templateType[1], PChar(dataPath));
+    get_game_field_parameters(gameField, LAND_WIDTH, LAND_HEIGHT, playWidth, playHeight);
+
+    MaxHedgehogs:= 32;
+    hasGirders:= true;
+
+    leftX:= (LAND_WIDTH - playWidth) div 2;
+    rightX:= Pred(leftX + playWidth);
+    topY:= LAND_HEIGHT - playHeight;
+    cWaterLine:= LAND_HEIGHT;
+
+    // let's assume those are powers of two
+    LAND_WIDTH_MASK:= not(LAND_WIDTH-1);
+    LAND_HEIGHT_MASK:= not(LAND_HEIGHT-1);
+
+    SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
+
+    initScreenSpaceVars();
+end;
+
 procedure ResizeLand(width, height: LongWord);
 var potW, potH: LongInt;
 begin
--- a/rust/landgen/src/maze.rs	Tue Sep 10 13:56:51 2024 +0200
+++ b/rust/landgen/src/maze.rs	Tue Sep 10 18:21:31 2024 +0200
@@ -4,12 +4,12 @@
 use land2d::Land2D;
 
 pub struct MazeTemplate {
-    width: usize,
-    height: usize,
-    cell_size: usize,
-    inverted: bool,
-    distortion_limiting_factor: u32,
-    braidness: usize,
+    pub width: usize,
+    pub height: usize,
+    pub cell_size: usize,
+    pub inverted: bool,
+    pub distortion_limiting_factor: u32,
+    pub braidness: usize,
 }
 
 pub struct MazeLandGenerator {
@@ -48,7 +48,7 @@
         let mut step_done = vec![false; num_steps];
         let mut last_cell = vec![Point::diag(0); num_steps];
         let mut came_from_pos = vec![0; num_steps];
-        let mut came_from = vec![vec![Point::diag(0); num_cells.area()]; num_steps];
+        let mut came_from = vec![vec![Point::diag(0); num_steps]; num_cells.area()];
 
         let mut done = false;
         let mut seen_list = vec![vec![None as Option<usize>; seen_cells.width]; seen_cells.height];
@@ -66,22 +66,21 @@
                 / num_steps;
             last_cell[current_step] = Point::new(
                 (x + current_step * seen_cells.width / num_steps) as i32,
-                random_numbers.next().unwrap_or_default() as i32 / num_steps as i32,
+                random_numbers.next().unwrap_or_default() as i32 % seen_cells.height as i32,
             );
         }
 
         let see_cell = |current_step: usize, start_dir: Point, seen_list: &mut Vec<Vec<Option<usize>>>, x_walls: &mut Vec<Vec<bool>>, y_walls: &mut Vec<Vec<bool>>,
                         last_cell: &mut Vec<Point>, came_from: &mut Vec<Vec<Point>>, came_from_pos: &mut Vec<i32>| {
+            let mut dir = start_dir;
             loop {
-                let p = last_cell[current_step];
-                seen_list[p.y as usize][p.x as usize] = Some(current_step);
-
-                let mut dir = start_dir;
+                let p = dbg!(last_cell[current_step]);
+                seen_list[p.y as usize][p.x as usize] = Some(dbg!(current_step));
 
                 let next_dir_clockwise = true;//random_numbers.next().unwrap_or_default() % 2 == 0;
 
                 for _ in 0..5 {
-                    let sp = p + dir;
+                    let sp = dbg!(p) + dbg!(dir);
                     let when_seen =
                         if sp.x < 0
                             || sp.x >= seen_cells.width as i32
@@ -130,9 +129,10 @@
                             if dir.x == 1 {
                                 y_walls[p.y as usize][p.x as usize] = false;
                             }
-                            last_cell[current_step] = p + dir;
+                            last_cell[current_step] = dbg!(sp);
                             came_from_pos[current_step] += 1;
                             came_from[came_from_pos[current_step] as usize][current_step] = p;
+                            return true;
                         }
                         _ => {
                             return true;
@@ -277,7 +277,7 @@
 
         OutlinePoints {
             islands,
-            fill_points: vec![],
+            fill_points: vec![Point::new(1, 1 + off_y)],
             size: *size,
             play_box,
             intersections_box,
--- a/rust/lib-hwengine-future/src/lib.rs	Tue Sep 10 13:56:51 2024 +0200
+++ b/rust/lib-hwengine-future/src/lib.rs	Tue Sep 10 18:21:31 2024 +0200
@@ -2,6 +2,7 @@
 
 use landgen::{
     outline_template_based::outline_template::OutlineTemplate,
+    maze::MazeTemplate,
     wavefront_collapse::generator::TemplateDescription as WfcTemplate, LandGenerationParameters,
     LandGenerator,
 };
@@ -126,6 +127,45 @@
 }
 
 #[no_mangle]
+pub extern "C" fn generate_maze_game_field(
+    feature_size: u32,
+    seed: *const i8,
+    template_type: *const i8,
+    data_path: *const i8,
+) -> *mut GameField {
+    let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+    let data_path = Path::new(&data_path);
+
+    let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap();
+    let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap();
+
+    let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes());
+
+    let map_gen = MapGenerator::<MazeTemplate>::new(data_path);
+    let distance_divisor = feature_size.pow(2) / 8 + 10;
+    let params = LandGenerationParameters::new(0u16, 0x8000u16, distance_divisor, false, false);
+    let template = MazeTemplate {
+        width: 4096,
+        height: 2048,
+        cell_size: 80,
+        inverted: false,
+        distortion_limiting_factor: 100,
+        braidness: 10,
+    };
+    let landgen = map_gen.build_generator(template);
+    let collision = landgen.generate_land(&params, &mut random_numbers_gen);
+    let size = collision.size().size();
+
+    let game_field = Box::new(GameField {
+        collision,
+        pixels: land2d::Land2D::new(&size, 0),
+        landgen_parameters: Some(params),
+    });
+
+    Box::leak(game_field)
+}
+
+#[no_mangle]
 pub extern "C" fn apply_theme(
     game_field: &mut GameField,
     data_path: *const i8,
--- a/rust/mapgen/src/lib.rs	Tue Sep 10 13:56:51 2024 +0200
+++ b/rust/mapgen/src/lib.rs	Tue Sep 10 18:21:31 2024 +0200
@@ -4,6 +4,8 @@
 use self::theme::Theme;
 use crate::template::outline::TemplateCollectionDesc as OutlineTemplateCollectionDesc;
 use crate::template::wavefront_collapse::TemplateCollectionDesc as WfcTemplateCollectionDesc;
+use crate::template::maze::TemplateCollectionDesc as MazeTemplateCollectionDesc;
+
 use std::path::{Path, PathBuf};
 
 use land2d::Land2D;
@@ -187,7 +189,7 @@
             .map(|(size, indices)| {
                 (
                     TemplateType(size),
-                    indices.iter().map(|i| (&templates[*i]).into()).collect(),
+                    indices.indices.iter().map(|i| (&templates[*i]).into()).collect(),
                 )
             })
             .collect();
--- a/rust/mapgen/src/template/mod.rs	Tue Sep 10 13:56:51 2024 +0200
+++ b/rust/mapgen/src/template/mod.rs	Tue Sep 10 18:21:31 2024 +0200
@@ -1,2 +1,3 @@
 pub mod outline;
 pub mod wavefront_collapse;
+pub mod maze;