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, 3 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

# User Rev Content
1 root 1.5
2 elmex 1.1 /*
3     * Expands a layout by 2x in each dimension.
4     * H. S. Teoh
5     * --------------------------------------------------------------------------
6 root 1.7 * $Id: expand2x.C,v 1.6 2008-04-11 21:09:53 root Exp $
7 elmex 1.1 *
8     * ALGORITHM
9     *
10     * ... (TBW)
11     */
12    
13 root 1.6 #include "global.h"
14     #include "random_map.h"
15     #include "rproto.h"
16 elmex 1.1
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 root 1.3 static void
23 root 1.7 expand_misc (Maze newlayout, int i, int j, Maze layout)
24 root 1.3 {
25     newlayout[i * 2][j * 2] = layout[i][j];
26 elmex 1.1 /* (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 root 1.3 static int
38 root 1.7 calc_pattern (char ch, Maze layout, int i, int j)
39 root 1.3 {
40 elmex 1.1 int pattern = 0;
41    
42 root 1.7 if (i + 1 < layout->w && layout[i + 1][j] == ch)
43 elmex 1.1 pattern |= 1;
44    
45 root 1.7 if (j + 1 < layout->h)
46 root 1.3 {
47     if (layout[i][j + 1] == ch)
48     pattern |= 2;
49 root 1.7 if (i + 1 < layout->w && layout[i + 1][j + 1] == ch)
50 root 1.3 pattern |= 4;
51     }
52 elmex 1.1
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 root 1.3 static void
61 root 1.7 expand_wall (Maze newlayout, int i, int j, Maze layout)
62 root 1.3 {
63 root 1.7 int wall_pattern = calc_pattern ('#', layout, i, j);
64     int door_pattern = calc_pattern ('D', layout, i, j);
65 elmex 1.1 int both_pattern = wall_pattern | door_pattern;
66    
67 root 1.3 newlayout[i * 2][j * 2] = '#';
68 root 1.7
69     if (i + 1 < layout->w)
70 root 1.3 {
71     if (both_pattern & 1)
72     { /* join walls/doors to the right */
73 elmex 1.1 /* newlayout[i*2+1][j*2] = '#'; */
74 root 1.3 newlayout[i * 2 + 1][j * 2] = layout[i + 1][j];
75     }
76 elmex 1.1 }
77    
78 root 1.7 if (j + 1 < layout->h)
79 root 1.3 {
80     if (both_pattern & 2)
81     { /* join walls/doors to the bottom */
82 elmex 1.1 /* newlayout[i*2][j*2+1] = '#'; */
83 root 1.3 newlayout[i * 2][j * 2 + 1] = layout[i][j + 1];
84     }
85 elmex 1.1
86 root 1.3 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 elmex 1.1 }
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 root 1.3 static void
99 root 1.7 expand_door (Maze newlayout, int i, int j, Maze layout)
100 root 1.3 {
101 root 1.7 int wall_pattern = calc_pattern ('#', layout, i, j);
102     int door_pattern = calc_pattern ('D', layout, i, j);
103 elmex 1.1 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 root 1.3 if (wall_pattern & 3)
109 root 1.6 join_pattern = wall_pattern;
110 root 1.3 else
111 root 1.6 join_pattern = door_pattern;
112 root 1.3
113     newlayout[i * 2][j * 2] = 'D';
114 root 1.6
115 root 1.7 if (i + 1 < layout->w)
116 root 1.6 if (join_pattern & 1)
117     /* there is a door/wall to the right */
118     newlayout[i * 2 + 1][j * 2] = 'D';
119 root 1.3
120 root 1.7 if (j + 1 < layout->h)
121 root 1.6 if (join_pattern & 2)
122     /* there is a door/wall below */
123     newlayout[i * 2][j * 2 + 1] = 'D';
124 elmex 1.1 }
125 root 1.7
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