ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/expand2x.C
Revision: 1.7
Committed: Mon Apr 14 22:41:17 2008 UTC (16 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.6: +36 -52 lines
Log Message:
refactor random map gen more

File Contents

# Content
1
2 /*
3 * Expands a layout by 2x in each dimension.
4 * H. S. Teoh
5 * --------------------------------------------------------------------------
6 * $Id: expand2x.C,v 1.6 2008-04-11 21:09:53 root Exp $
7 *
8 * ALGORITHM
9 *
10 * ... (TBW)
11 */
12
13 #include "global.h"
14 #include "random_map.h"
15 #include "rproto.h"
16
17 /* Copy the old tile X into the new one at location (i*2, j*2) and
18 * fill up the rest of the 2x2 result with \0:
19 * X ---> X \0
20 * \0 \0
21 */
22 static void
23 expand_misc (Maze newlayout, int i, int j, Maze layout)
24 {
25 newlayout[i * 2][j * 2] = layout[i][j];
26 /* (Note: no need to reset rest of 2x2 area to \0 because calloc does that
27 * for us.) */
28 }
29
30 /* Returns a bitmap that represents which squares on the right and bottom
31 * edges of a square (i,j) match the given character:
32 * 1 match on (i+1, j)
33 * 2 match on (i, j+1)
34 * 4 match on (i+1, j+1)
35 * and the possible combinations thereof.
36 */
37 static int
38 calc_pattern (char ch, Maze layout, int i, int j)
39 {
40 int pattern = 0;
41
42 if (i + 1 < layout->w && layout[i + 1][j] == ch)
43 pattern |= 1;
44
45 if (j + 1 < layout->h)
46 {
47 if (layout[i][j + 1] == ch)
48 pattern |= 2;
49 if (i + 1 < layout->w && layout[i + 1][j + 1] == ch)
50 pattern |= 4;
51 }
52
53 return pattern;
54 }
55
56 /* Expand a wall. This function will try to sensibly connect the resulting
57 * wall to adjacent wall squares, so that the result won't have disconnected
58 * walls.
59 */
60 static void
61 expand_wall (Maze newlayout, int i, int j, Maze layout)
62 {
63 int wall_pattern = calc_pattern ('#', layout, i, j);
64 int door_pattern = calc_pattern ('D', layout, i, j);
65 int both_pattern = wall_pattern | door_pattern;
66
67 newlayout[i * 2][j * 2] = '#';
68
69 if (i + 1 < layout->w)
70 {
71 if (both_pattern & 1)
72 { /* join walls/doors to the right */
73 /* newlayout[i*2+1][j*2] = '#'; */
74 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
75 }
76 }
77
78 if (j + 1 < layout->h)
79 {
80 if (both_pattern & 2)
81 { /* join walls/doors to the bottom */
82 /* newlayout[i*2][j*2+1] = '#'; */
83 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
84 }
85
86 if (wall_pattern == 7)
87 { /* if orig layout is a 2x2 wall block,
88 * we fill the result with walls. */
89 newlayout[i * 2 + 1][j * 2 + 1] = '#';
90 }
91 }
92 }
93
94 /* This function will try to sensibly connect doors so that they meet up with
95 * adjacent walls. Note that it will also presumptuously delete (ignore) doors
96 * that it doesn't know how to correctly expand.
97 */
98 static void
99 expand_door (Maze newlayout, int i, int j, Maze layout)
100 {
101 int wall_pattern = calc_pattern ('#', layout, i, j);
102 int door_pattern = calc_pattern ('D', layout, i, j);
103 int join_pattern;
104
105 /* Doors "like" to connect to walls more than other doors. If there is
106 * a wall and another door, this door will connect to the wall and
107 * disconnect from the other door. */
108 if (wall_pattern & 3)
109 join_pattern = wall_pattern;
110 else
111 join_pattern = door_pattern;
112
113 newlayout[i * 2][j * 2] = 'D';
114
115 if (i + 1 < layout->w)
116 if (join_pattern & 1)
117 /* there is a door/wall to the right */
118 newlayout[i * 2 + 1][j * 2] = 'D';
119
120 if (j + 1 < layout->h)
121 if (join_pattern & 2)
122 /* there is a door/wall below */
123 newlayout[i * 2][j * 2 + 1] = 'D';
124 }
125
126 void
127 expand2x (Maze layout)
128 {
129 Maze newlayout (layout->w * 2 - 1, layout->h * 2 - 1);
130 newlayout->clear ();
131
132 for (int i = 0; i < layout->w; i++)
133 for (int j = 0; j < layout->h; j++)
134 switch (layout[i][j])
135 {
136 case '#': expand_wall (newlayout, i, j, layout); break;
137 case 'D': expand_door (newlayout, i, j, layout); break;
138 default: expand_misc (newlayout, i, j, layout); break;
139 }
140
141 layout.swap (newlayout);
142 }
143