Skip to content

Commit df34250

Browse files
committed
Create mapgen step func
1 parent f2cbe7f commit df34250

File tree

3 files changed

+80
-21
lines changed

3 files changed

+80
-21
lines changed

src/game.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ end
6868

6969
type state = {
7070
random: Random.State.t;
71+
random_seed: int;
7172
game: game;
7273
screen: Screen.t;
7374
resources: resources;
@@ -77,6 +78,8 @@ type state = {
7778

7879
let run ?(view=Screen.MapGen None) ?(area=Gmap.WestUS) () : unit =
7980
let random = Random.get_state () in
81+
(* Used by different elements *)
82+
let random_seed = Random.int 0x7FFF random in
8083

8184
Printf.printf "Loading resources...";
8285

@@ -96,7 +99,7 @@ let run ?(view=Screen.MapGen None) ?(area=Gmap.WestUS) () : unit =
9699
let game = {map; area; cities} in
97100

98101
let textures = Textures.of_resources win resources area in
99-
let state = {game; screen; resources; random; textures} in
102+
let state = {game; screen; resources; random; textures; random_seed} in
100103

101104
Printf.printf " done.\n";
102105

@@ -106,10 +109,11 @@ let run ?(view=Screen.MapGen None) ?(area=Gmap.WestUS) () : unit =
106109
| Screen.MapGen None ->
107110
(* Prepare mapgen with init *)
108111
let cities = List.assoc ~eq:(Gmap.equal_area) area s.resources.res_cities in
109-
let data = Mapgen.init s.random s.game.area cities in
112+
let data = Mapgen.init s.random s.game.area cities ~random_seed in
110113
Lens.Infix.((state_screen |-- Screen.view) ^= Screen.MapGen(Some data)) state
111114

112115
| Screen.MapGen Some data -> s
116+
113117
| _ -> s
114118
in
115119
state, false
@@ -126,6 +130,7 @@ let run ?(view=Screen.MapGen None) ?(area=Gmap.WestUS) () : unit =
126130
Result.return ()
127131
in
128132
s
133+
129134
| Screen.MapGen None -> s
130135
in
131136
state, Graphics.{update; render}

src/gmap.ml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ type pixel =
6969
| EnemyRR_pixel
7070
| City_pixel
7171
| Mountain_pixel (* 15 *)
72-
[@@deriving enum]
72+
[@@deriving enum, eq]
7373

7474
let pixel_of_tile = function
7575
| Slums -> Slum_pixel
@@ -122,13 +122,10 @@ let tile_of_pixel_default = function
122122
let map_height = 192
123123
let map_width = 256
124124

125-
let calc_offset x y = y * map_width + x
126-
let read_map map x y = map.(calc_offset x y)
127-
128125
(* random_seed: 15 bits from time *)
129126
let tile_of_pixel ~x ~y ~pixel ~random_seed =
130127
let xy_random = x * 9 + y * 13 + random_seed in
131-
let pixel = Option.get @@ pixel_of_enum pixel in
128+
(* let pixel = Option.get @@ pixel_of_enum pixel in *)
132129
let simple_mapping = function
133130
| Slum_pixel -> Slums
134131
| Ocean_pixel -> Ocean
@@ -226,3 +223,15 @@ let to_img map =
226223
let ndarray = to_ndarray map in
227224
Pic.img_of_ndarray ndarray
228225

226+
let calc_offset x y = y * map_width + x
227+
228+
let get_tile map x y = map.(calc_offset x y)
229+
230+
let get_pixel ~map ~x ~y = get_tile map x y |> pixel_of_tile
231+
232+
let set_pixel ~map ~x ~y ~pixel ~random_seed =
233+
let tile = tile_of_pixel ~x ~y ~pixel ~random_seed in
234+
map.(calc_offset x y) <- tile
235+
236+
237+

src/mapgen.ml

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ open Gmap
33

44
let debug = false
55

6-
let add_mountain_pixel = function
6+
let pixel_apply_mountain = function
77
| Foothills_pixel -> Hills_pixel
88
| Hills_pixel -> Mountain_pixel
99
| Ocean_pixel
@@ -147,7 +147,7 @@ let add_mountains_list r area =
147147
This particular function needs to access the map, and since resources can only
148148
be in certain tiles, it may fail and need to try again and again.
149149
*)
150-
let add_resource area ~map ~land_type ~resource_pixel ~wanted_tile ~random_seed ~r =
150+
let add_resource area ~map ~land_pixel ~resource_pixel ~wanted_tile ~random_seed ~r =
151151
let rec loop () =
152152
let x = Random.int 256 r in
153153
let y = Random.int 192 r in
@@ -159,21 +159,21 @@ let add_resource area ~map ~land_type ~resource_pixel ~wanted_tile ~random_seed
159159
| Europe -> x
160160
in
161161
let rec attempt i x y =
162-
if i >= 2 then false else
163-
let offset = calc_offset x y in
164-
let tile = map.(offset) in
162+
if i >= 2 then None else
163+
let pixel = Gmap.get_pixel ~map ~x ~y in
165164
let possible_tile = tile_of_pixel ~x ~y ~random_seed ~pixel:resource_pixel in
166-
if Gmap.equal_tile tile land_type && Gmap.equal_tile possible_tile wanted_tile then (
167-
map.(offset) <- possible_tile;
168-
true
165+
if Gmap.equal_pixel pixel land_pixel && Gmap.equal_tile possible_tile wanted_tile then (
166+
Gmap.set_pixel ~map ~x ~y ~pixel:resource_pixel ~random_seed;
167+
Some (x, y)
169168
) else
170169
let x = if y mod 2 = 1 then x + 1 else x - 1 in
171170
attempt (i + 1) x (y + 1)
172171
in
173-
if attempt 0 x y then ()
174-
else loop () (* Keep trying *)
172+
match attempt 0 x y with
173+
| None -> loop ()
174+
| x -> x
175175
in
176-
loop ()
176+
loop () |> Option.get_exn_or "Impossible failure reached"
177177

178178
(* A general list of resources to add *)
179179
let add_resources_list area =
@@ -192,7 +192,7 @@ let add_resources_list area =
192192
(Clear_pixel, OilWell_pixel, OilWell, count);
193193
]
194194

195-
let upgrade_city_pixel = function
195+
let pixel_apply_city = function
196196
| Clear_pixel
197197
| Woods_pixel
198198
| Farm_pixel -> Village_pixel
@@ -260,17 +260,62 @@ let load_city_list ?(debug=false) area =
260260
cities
261261

262262
type t = {
263+
area: area;
263264
mountains : (int * int) list;
264265
resources: (pixel * pixel * tile * int) list;
265266
cities: (int * int) list;
266267
current: [`Mountains | `Resources | `Cities];
268+
new_pixels: (int * int * pixel) list;
269+
random_seed: int;
267270
}
268271

269-
let init r area cities =
272+
let init r area cities ~random_seed =
270273
let mountains = add_mountains_list r area in
271274
let resources = add_resources_list area in
272275
let cities = add_city_list r area cities in
273276
let current = `Mountains in
274-
{mountains; resources; cities; current}
277+
let new_pixels = [] in
278+
{area; mountains; resources; cities; current; new_pixels; random_seed}
279+
280+
(* Perform a step of updating the map *)
281+
let update_map_step r v map =
282+
let random_seed = v.random_seed in
283+
let is_done = false in
284+
match v.current with
285+
| `Mountains ->
286+
begin match v.mountains with
287+
| (x, y)::rest ->
288+
let pixel = Gmap.get_pixel ~map ~x ~y in
289+
let pixel = pixel_apply_mountain pixel in
290+
Gmap.set_pixel ~map ~x ~y ~pixel ~random_seed;
291+
let new_pixels = (x, y, pixel)::v.new_pixels in
292+
{v with mountains=rest; new_pixels}, is_done
293+
| _ ->
294+
{v with current=`Resources}, is_done
295+
end
296+
| `Cities ->
297+
begin match v.cities with
298+
| (x, y)::rest ->
299+
let pixel = Gmap.get_pixel ~map ~x ~y in
300+
let pixel = pixel_apply_city pixel in
301+
Gmap.set_pixel ~map ~x ~y ~pixel ~random_seed;
302+
let new_pixels = (x, y, pixel)::v.new_pixels in
303+
{v with cities=rest; new_pixels}, is_done
304+
| _ -> v, true
305+
end
306+
| `Resources ->
307+
begin match v.resources with
308+
| (_, _, _, 0)::rest ->
309+
{v with resources=rest}, is_done
310+
| (land_pixel, resource_pixel, wanted_tile, num)::rest ->
311+
let x, y =
312+
add_resource v.area ~map ~land_pixel ~resource_pixel ~wanted_tile ~random_seed ~r
313+
in
314+
let new_pixels = (x, y, resource_pixel)::v.new_pixels in
315+
let resources = (land_pixel, resource_pixel, wanted_tile, num-1)::rest in
316+
{v with resources; new_pixels}, is_done
317+
| _ -> {v with current=`Cities}, is_done
318+
end
319+
275320

276321

0 commit comments

Comments
 (0)