--- a/hedgewars/uLandGenMaze.pas Tue Nov 10 18:16:35 2015 +0100
+++ b/hedgewars/uLandGenMaze.pas Tue Nov 10 20:43:13 2015 +0100
@@ -8,7 +8,7 @@
implementation
-uses uRandom, uLandOutline, uLandTemplates, uVariables, uFloat, uConsts;
+uses uRandom, uLandOutline, uLandTemplates, uVariables, uFloat, uConsts, uLandGenTemplateBased, uUtils;
type direction = record x, y: LongInt; end;
const DIR_N: direction = (x: 0; y: -1);
@@ -16,7 +16,6 @@
DIR_S: direction = (x: 0; y: 1);
DIR_W: direction = (x: -1; y: 0);
-
operator = (const a, b: direction) c: Boolean;
begin
c := (a.x = b.x) and (a.y = b.y);
@@ -27,28 +26,43 @@
large_cell_size = 256;
braidness = 10;
-var x, y: LongInt;
- cellsize: LongInt; //selected by the user in the gui
- seen_cells_x, seen_cells_y: LongInt; //number of cells that can be visited by the generator, that is every second cell in x and y direction. the cells between there are walls that will be removed when we move from one cell to another
- num_edges_x, num_edges_y: LongInt; //number of resulting edges that need to be vertexificated
- num_cells_x, num_cells_y: LongInt; //actual number of cells, depending on cell size
- seen_list: array of array of LongInt;
- xwalls: array of array of Boolean;
- ywalls: array of array of Boolean;
- x_edge_list: array of array of Boolean;
- y_edge_list: array of array of Boolean;
- maze: array of array of Boolean;
- pa: TPixAr;
- num_vertices: LongInt;
- off_y: LongInt;
- num_steps: LongInt;
- current_step: LongInt;
- step_done: array of Boolean;
- done: Boolean;
- last_cell: array of record x, y: LongInt; end;
- came_from: array of array of record x, y: LongInt; end;
+type
+ cell_t = record x,y : LongInt
+ end;
+
+var x, y : LongInt;
+ cellsize : LongInt; //selected by the user in the gui
+ seen_cells_x, seen_cells_y : LongInt; //number of cells that can be visited by the generator, that is every second cell in x and y direction. the cells between there are walls that will be removed when we move from one cell to another
+ num_edges_x, num_edges_y : LongInt; //number of resulting edges that need to be vertexificated
+ num_cells_x, num_cells_y : LongInt; //actual number of cells, depending on cell size
+
+
+ seen_list : array of array of LongInt;
+ xwalls : array of array of Boolean;
+ ywalls : array of array of Boolean;
+ x_edge_list : array of array of Boolean;
+ y_edge_list : array of array of Boolean;
+ maze : array of array of Boolean;
+
+ pa : TPixAr;
+ num_vertices : LongInt;
+ off_y : LongInt;
+ num_steps : LongInt;
+ current_step : LongInt;
+
+ step_done : array of Boolean;
+
+ done : Boolean;
+
+{ last_cell : array 0..3 of record x, y :LongInt ; end;
+ came_from : array of array of record x, y: LongInt; end;
+ came_from_pos : array of LongInt;
+}
+ last_cell : array of cell_t;
+ came_from : array of array of cell_t;
came_from_pos: array of LongInt;
- maze_inverted: Boolean;
+
+ maze_inverted : Boolean;
function when_seen(x: LongInt; y: LongInt): LongInt;
begin
@@ -104,11 +118,11 @@
begin
//we have already seen the target cell, decide if we should remove the wall anyway
//(or put a wall there if maze_inverted, but we are not doing that right now)
- if not maze_inverted and (GetRandom(braidness) = 0) then
+ if (not maze_inverted) and (GetRandom(braidness) = 0) then
//or just warn that inverted+braid+indestructible terrain != good idea
begin
case dir.x of
-
+
-1:
if x > 0 then
ywalls[x-1, y] := false;
@@ -178,46 +192,56 @@
last_cell[current_step].x := came_from[current_step, came_from_pos[current_step]].x;
last_cell[current_step].y := came_from[current_step, came_from_pos[current_step]].y;
came_from_pos[current_step] := came_from_pos[current_step] - 1;
-
+
if came_from_pos[current_step] >= 0 then
- see_cell
-
+ see_cell()
+
else
step_done[current_step] := true;
end;
end;
procedure add_vertex(x, y: LongInt);
-var tmp_x, tmp_y: LongInt;
-begin
-if x = NTPX then
+var tmp_x, tmp_y, nx, ny: LongInt;
begin
- if pa.ar[num_vertices - 6].x = NTPX then
+ if x = NTPX then
begin
- num_vertices := num_vertices - 6;
+ if pa.ar[num_vertices - 6].x = NTPX then
+ begin
+ num_vertices := num_vertices - 6;
+ end
+ else
+ begin
+ pa.ar[num_vertices].x := NTPX;
+ pa.ar[num_vertices].y := 0;
+ end
end
else
begin
- pa.ar[num_vertices].x := NTPX;
- pa.ar[num_vertices].y := 0;
- end
-end
-else
-begin
- if maze_inverted or (x mod 2 = 0) then
- tmp_x := cellsize
- else
- tmp_x := cellsize * 2 div 3;
-
- if maze_inverted or (y mod 2 = 0) then
- tmp_y := cellsize
- else
- tmp_y := cellsize * 2 div 3;
+ if maze_inverted or (x mod 2 = 0) then
+ tmp_x := cellsize
+ else
+ tmp_x := cellsize * 2 div 3;
+
+ if maze_inverted or (y mod 2 = 0) then
+ tmp_y := cellsize
+ else
+ tmp_y := cellsize * 2 div 3;
- pa.ar[num_vertices].x := (x-1)*cellsize + tmp_x;
- pa.ar[num_vertices].y := (y-1)*cellsize + tmp_y + off_y;
-end;
-num_vertices := num_vertices + 1;
+ nx:= (x-1)*cellsize + tmp_x;
+ ny:= (y-1)*cellsize + tmp_y + off_y;
+
+ if num_vertices > 2 then
+ if ((pa.ar[num_vertices - 2].x = pa.ar[num_vertices - 1].x) and (pa.ar[num_vertices - 1].x = nx))
+ or ((pa.ar[num_vertices - 2].y = pa.ar[num_vertices - 1].y) and (pa.ar[num_vertices - 1].y = ny))
+ then
+ dec(num_vertices);
+
+ pa.ar[num_vertices].x := nx;
+ pa.ar[num_vertices].y := ny;
+ end;
+
+ num_vertices := num_vertices + 1;
end;
procedure add_edge(x, y: LongInt; dir: direction);
@@ -251,78 +275,91 @@
else
dir := DIR_N;
-if (dir = DIR_N) and is_x_edge(x, y) then
- begin
- x_edge_list[x, y] := false;
- add_vertex(x+1, y);
- add_edge(x, y-1, DIR_N);
- break;
- end;
+ if (dir = DIR_N) and is_x_edge(x, y) then
+ begin
+ x_edge_list[x, y] := false;
+ add_vertex(x+1, y);
+ add_edge(x, y-1, DIR_N);
+ break;
+ end;
-if (dir = DIR_E) and is_y_edge(x+1, y) then
- begin
- y_edge_list[x+1, y] := false;
- add_vertex(x+2, y+1);
- add_edge(x+1, y, DIR_E);
- break;
- end;
+ if (dir = DIR_E) and is_y_edge(x+1, y) then
+ begin
+ y_edge_list[x+1, y] := false;
+ add_vertex(x+2, y+1);
+ add_edge(x+1, y, DIR_E);
+ break;
+ end;
-if (dir = DIR_S) and is_x_edge(x, y+1) then
- begin
- x_edge_list[x, y+1] := false;
- add_vertex(x+1, y+2);
- add_edge(x, y+1, DIR_S);
- break;
- end;
+ if (dir = DIR_S) and is_x_edge(x, y+1) then
+ begin
+ x_edge_list[x, y+1] := false;
+ add_vertex(x+1, y+2);
+ add_edge(x, y+1, DIR_S);
+ break;
+ end;
-if (dir = DIR_W) and is_y_edge(x, y) then
- begin
- y_edge_list[x, y] := false;
- add_vertex(x, y+1);
- add_edge(x-1, y, DIR_W);
- break;
+ if (dir = DIR_W) and is_y_edge(x, y) then
+ begin
+ y_edge_list[x, y] := false;
+ add_vertex(x, y+1);
+ add_edge(x-1, y, DIR_W);
+ break;
+ end;
end;
-end;
end;
procedure GenMaze;
+var i: Longword;
begin
case cTemplateFilter of
0: begin
- cellsize := small_cell_size;
- maze_inverted := false;
- end;
+ cellsize := small_cell_size;
+ maze_inverted := false;
+ minDistance:= max(cFeatureSize*8,32);
+ dabDiv:= 150;
+ end;
1: begin
- cellsize := medium_cell_size;
- maze_inverted := false;
- end;
+ cellsize := medium_cell_size;
+ minDistance:= max(cFeatureSize*6,20);
+ maze_inverted := false;
+ dabDiv:= 100;
+ end;
2: begin
- cellsize := large_cell_size;
- maze_inverted := false;
- end;
+ cellsize := large_cell_size;
+ minDistance:= max(cFeatureSize*5,12);
+ maze_inverted := false;
+ dabDiv:= 90;
+ end;
3: begin
- cellsize := small_cell_size;
- maze_inverted := true;
- end;
+ cellsize := small_cell_size;
+ minDistance:= max(cFeatureSize*8,32);
+ maze_inverted := true;
+ dabDiv:= 130;
+ end;
4: begin
- cellsize := medium_cell_size;
- maze_inverted := true;
- end;
+ cellsize := medium_cell_size;
+ minDistance:= max(cFeatureSize*6,20);
+ maze_inverted := true;
+ dabDiv:= 100;
+ end;
5: begin
- cellsize := large_cell_size;
- maze_inverted := true;
+ cellsize := large_cell_size;
+ minDistance:= max(cFeatureSize*5,12);
+ maze_inverted := true;
+ dabDiv:= 85;
+ end;
end;
-end;
num_cells_x := LAND_WIDTH div cellsize;
if not odd(num_cells_x) then
num_cells_x := num_cells_x - 1; //needs to be odd
-
+
num_cells_y := LAND_HEIGHT div cellsize;
if not odd(num_cells_y) then
num_cells_y := num_cells_y - 1;
-
+
num_edges_x := num_cells_x - 1;
num_edges_y := num_cells_y - 1;
@@ -333,19 +370,23 @@
num_steps := 3 //TODO randomize, between 3 and 5?
else
num_steps := 1;
-
+
SetLength(step_done, num_steps);
SetLength(last_cell, num_steps);
SetLength(came_from_pos, num_steps);
SetLength(came_from, num_steps, num_cells_x*num_cells_y);
+
done := false;
for current_step := 0 to num_steps - 1 do
+ begin
step_done[current_step] := false;
came_from_pos[current_step] := 0;
-
+ end;
+
current_step := 0;
+
SetLength(seen_list, seen_cells_x, seen_cells_y);
SetLength(xwalls, seen_cells_x, seen_cells_y - 1);
SetLength(ywalls, seen_cells_x - 1, seen_cells_y);
@@ -353,6 +394,7 @@
SetLength(y_edge_list, num_cells_x, num_edges_y);
SetLength(maze, num_cells_x, num_cells_y);
+
num_vertices := 0;
playHeight := num_cells_y * cellsize;
@@ -402,14 +444,14 @@
begin
done := true;
for current_step := 0 to num_steps-1 do
- begin
+ begin
if not step_done[current_step] then
- begin
+ begin
see_cell;
done := false;
+ end;
end;
end;
-end;
for x := 0 to seen_cells_x - 1 do
for y := 0 to seen_cells_y - 1 do
@@ -454,15 +496,34 @@
pa.count := num_vertices;
-RandomizePoints(pa);
-BezierizeEdge(pa, _0_25);
-RandomizePoints(pa);
-BezierizeEdge(pa, _0_25);
+leftX:= 0;
+rightX:= playWidth;
+topY:= off_y;
+
+// fill point
+pa.ar[pa.Count].x:= 1;
+pa.ar[pa.Count].y:= 1 + off_y;
+
+{
+for i:= 0 to pa.Count - 1 do
+ begin
+ system.writeln(pa.ar[i].x, ', ', pa.ar[i].y);
+ end;
+}
+
+// divide while it divides
+repeat
+ i:= pa.Count;
+ DivideEdges(1, pa)
+until i = pa.Count;
+
+// make it smooth
+BezierizeEdge(pa, _0_2);
DrawEdge(pa, 0);
if maze_inverted then
- FillLand(1, 1+off_y)
+ FillLand(1, 1 + off_y, 0, 0)
else
begin
x := 0;
@@ -470,7 +531,7 @@
x := x + 1;
while Land[cellsize div 2 + cellsize + off_y, x] = 0 do
x := x + 1;
- FillLand(x+1, cellsize div 2 + cellsize + off_y);
+ FillLand(x+1, cellsize div 2 + cellsize + off_y, 0, 0);
end;
MaxHedgehogs:= 32;
@@ -478,9 +539,7 @@
hasGirders:= false
else
hasGirders := true;
-leftX:= 0;
-rightX:= playWidth;
-topY:= off_y;
+
hasBorder := false;
end;