11package Map ;
22
3+ import Constants .Directions ;
4+ import Map .NonRoad .Cornfield ;
35import Map .NonRoad .House ;
46import Car .Car ;
7+ import Map .NonRoad .Mall ;
8+ import Map .NonRoad .Office ;
9+ import Map .Road .Road ;
10+ import Map .Road .TrafficLight ;
511
12+ import java .util .ArrayDeque ;
613import java .util .ArrayList ;
7- import java .util .HashMap ;
8- import java .util .Random ;
14+ import java .util .Arrays ;
15+ import java .util .Queue ;
916
1017/**
1118 * @author arshsab
1219 * @since 10 2014
1320 */
1421
1522public class DensityBasedMapGenerator implements MapGenerator {
16- private final Tile [][] grid ;
23+ private static final double DENSITY = 0.34 ;
1724
18- public DensityBasedMapGenerator (Tile [][] grid ) {
19- this .grid = grid ;
25+ private final int length ;
26+ private final int cars ;
27+ private final double [][] densities ;
28+
29+ public DensityBasedMapGenerator (int length , int cars ) {
30+ this (length , cars , new double [length ][length ]);
31+ }
32+
33+ public DensityBasedMapGenerator (int length , int cars , double [][] densities ) {
34+ this .length = length ;
35+ this .cars = cars ;
36+ this .densities = densities ;
2037 }
2138
2239 @ Override
2340 public Map generateMap () {
24- Map map = new Map (grid , new ArrayList <Car >());
41+ Tile [][] grid = new Tile [length ][length ];
42+
43+ for (int i = 0 ; i < grid .length ; i ++) {
44+ for (int j = 0 ; j < grid [i ].length ; j ++) {
45+ grid [i ][j ] = new House (i , j );
46+ }
47+ }
48+
49+ Map m = new Map (grid , new ArrayList <Car >());
50+
51+ final int val = length / 4 ;
52+
53+ for (int t = 0 ; t < 12 ; t ++) {
54+ for (int i = 0 ; i < length ; i += 4 ){
55+ int start = (int ) (Math .random () * length / 2 ) * 2 ;
56+ int width = (int ) (Math .random () * (length - start - val ) / 2 ) * 2 + val ;
57+
58+ width = Math .min (width , length - start - 1 );
59+
60+ if (Math .random () < (densities [start ][i ] + densities [start + width ][i ]) / 2 ) {
61+ m .createHorizontalRoad (start , i , width , 2 , 4 );
62+ }
63+ }
64+
65+ for (int i = 0 ; i < length ; i += 4 ){
66+ int start = (int ) (Math .random () * length / 2 ) * 2 ;
67+ int width = (int ) (Math .random () * (length - start - val ) / 2 ) * 2 + val ;
68+
69+ width = Math .min (width , length - start - 1 );
70+
71+
72+ if (Math .random () < (densities [start ][i ] + densities [start + width ][i ]) / 2 ) {
73+ m .createVerticalRoad (i , start , width , 2 , 4 );
74+ }
75+ }
76+ }
77+
78+
79+ if (removeIslands (m ) >= 4 )
80+ return generateMap ();
81+
82+
83+ ArrayList <Road > roads = new ArrayList <Road >();
2584
85+ for (Tile [] a : grid ) {
86+ for (Tile b : a ) {
87+ if (b instanceof Road && !(b instanceof TrafficLight )) {
88+ for (int i = 0 ; i < (int ) (densities [b .getX ()][b .getY ()] * 100 ); i ++)
89+ roads .add ((Road ) b );
90+ }
91+ }
92+ }
93+
94+ for (int i = 0 ; i < cars ; i ++) {
95+ Road start , end ;
96+
97+ do {
98+ start = roads .get ((int ) (roads .size () * Math .random ()));
99+ end = roads .get ((int ) (roads .size () * Math .random ()));
100+ } while (start == end );
101+
102+ m .placeCar (new Car (start .x , start .y , end .x , end .y , m ));
103+ }
26104
27- int [][] visits = simulatePaths (1000 , grid );
105+ for (int i = 0 ; i < grid .length ; i ++) {
106+ for (int j = 0 ; j < grid [i ].length ; j ++) {
107+ if (grid [i ][j ] instanceof Road ) continue ;
28108
29- convertPaths (visits , grid );
109+ int fixed = (int ) Math .round (densities [i ][j ] / .25 );
110+
111+ switch (fixed ) {
112+ case 0 :
113+ grid [i ][j ] = new Cornfield (i , j );
114+ break ;
115+ case 1 :
116+ grid [i ][j ] = new House (i , j );
117+ break ;
118+ case 2 :
119+ grid [i ][j ] = new Mall (i , j );
120+ break ;
121+ case 3 :
122+ grid [i ][j ] = new Office (i , j );
123+ break ;
124+ }
125+ }
126+ }
127+
128+ return m ;
129+ }
30130
31- return map ;
131+ public void spot (int x , int y ) {
132+ spot (x , y , 1.0 );
32133 }
33134
135+ private void spot (int x , int y , double a ) {
136+ if (0 <= x && x < length &&
137+ 0 <= y && y < length &&
138+ densities [x ][y ] == 0.0 &&
139+ a > 0.0 ) {
34140
35- private int [][] simulatePaths (int iterations , Tile [][] grid ) {
36- throw new RuntimeException ("todo" );
141+ densities [x ][y ] += a ;
142+ densities [x ][y ] = Math .min (densities [x ][y ], 1.0 );
143+
144+
145+ for (int i = 0 ; i < 4 ; i ++) {
146+ int altX = x + Directions .dx [i ];
147+ int altY = y + Directions .dy [i ];
148+
149+ spot (altX , altY , a - 0.03 );
150+ }
151+ }
37152 }
38153
39- private void convertPaths (int [][] visits , Tile [][] grid ) {
40- throw new RuntimeException ("todo" );
154+ private int removeIslands (Map m ) {
155+ int [][] dp = new int [length ][length ];
156+
157+ int num = 1 ;
158+
159+ for (int [] arr : dp ) {
160+ Arrays .fill (arr , Integer .MAX_VALUE );
161+ }
162+
163+ int max = -1 ;
164+ int total = 0 ;
165+ int maxNum = 0 ;
166+ for (int i = 0 ; i < dp .length ; i ++) {
167+ for (int j = 0 ; j < dp [i ].length ; j ++) {
168+ if (m .grid [i ][j ] instanceof House ) {
169+ dp [i ][j ] = 0 ;
170+ } else if (dp [i ][j ] > num ) {
171+ int count = floodfill (m , dp , num , i , j );
172+
173+ total += count ;
174+
175+ if (count > max ) {
176+ max = count ;
177+ maxNum = num ;
178+ }
179+
180+ ++num ;
181+
182+ }
183+ }
184+ }
185+
186+ for (int i = 0 ; i < dp .length ; i ++) {
187+ for (int j = 0 ; j < dp [i ].length ; j ++) {
188+ if (dp [i ][j ] != maxNum ) {
189+ m .grid [i ][j ] = new House (i , j );
190+ }
191+ }
192+ }
193+
194+ return num ;
41195 }
42196
43- public static void main (String [] args ) {
44- Tile [][] tile = new Tile [10 ][10 ];
45- for (int i = 0 ; i < 10 ; i ++){
46- for (int j = 0 ; j < 10 ; j ++){
47- tile [i ][j ] = new House (i , j );
197+ private int floodfill (Map m , int [][] dp , int val , int x , int y ) {
198+ Queue <Coord > q = new ArrayDeque <Coord >();
199+
200+ q .add (new Coord (x , y ));
201+
202+ dp [x ][y ] = val ;
203+ int count = 1 ;
204+ while (!q .isEmpty ()) {
205+ Coord nex = q .poll ();
206+
207+ boolean [] valid = m .generateValidMoves (nex .x , nex .y );
208+
209+ for (int i = 0 ; i < 4 ; i ++) {
210+ if (!valid [i ]) continue ;
211+
212+ int altX = nex .x + Directions .dx [i ];
213+ int altY = nex .y + Directions .dy [i ];
214+
215+ if (!m .pointIsValid (altX , altY )
216+ || dp [altX ][altY ] <= val ) continue ;
217+
218+ dp [altX ][altY ] = val ;
219+ q .add (new Coord (altX , altY ));
220+
221+ count ++;
48222 }
49223 }
50224
51- MapGenerator x = new DensityBasedMapGenerator (tile );
52- Car [] cars = new Car [5 ];
53- Map y = x .generateMap ();
54- System .out .println (y );
55225
226+ return count ;
227+ }
228+
229+ private class Coord {
230+ final int x , y ;
231+
232+ public Coord (int x , int y ) {
233+ this .x = x ;
234+ this .y = y ;
235+ }
236+
237+ @ Override
238+ public int hashCode () {
239+ return x << 15 + y ;
240+ }
241+
242+ @ Override
243+ public boolean equals (Object o ) {
244+ if (o == null || o .getClass () != getClass ()) {
245+ return false ;
246+ }
247+
248+ Coord other = (Coord ) o ;
249+
250+ return this .x == other .x && this .y == other .y ;
251+ }
252+
253+ @ Override
254+ public String toString () {
255+ return "(" + x + " " + y + ")" ;
256+ }
257+ }
258+
259+ public static void main (String [] args ) {
260+ DensityBasedMapGenerator mapGen = new DensityBasedMapGenerator (50 , 1 );
261+ mapGen .spot (1 , 1 );
262+ mapGen .spot (20 , 20 );
263+
264+ mapGen .spot (40 , 40 );
265+
266+ Map map = mapGen .generateMap ();
267+
268+ System .out .println (map );
269+ System .out .println (map .getCars ());
270+ }
271+
272+
273+ public static String arrayToString (double [][] arr ) {
274+ StringBuilder total = new StringBuilder ();
275+
276+ for (int i = 0 ; i < arr .length ; i ++) {
277+ for (int j = 0 ; j < arr [i ].length ; j ++) {
278+ total .append (arr [j ][i ]).append (" " );
279+ }
280+
281+ total .append ('\n' );
282+ }
283+
284+ return total .toString ();
56285 }
57286}
0 commit comments