From e7fb6a70a0b66b17918b0facc29e5aad2a40ceaa Mon Sep 17 00:00:00 2001 From: Swrup Date: Sun, 9 Jul 2023 22:11:21 +0200 Subject: [PATCH] wip: animals --- .ocamlformat | 2 +- src/animal.ml | 62 +++++++++++++++++++++++++ src/content/assets/img/sheep.png | Bin 0 -> 21508 bytes src/dune | 2 +- src/island.ml | 1 + src/island_client.ml | 28 ++++++++---- src/map.ml | 14 +++++- src/state.ml | 76 ++++++++++++++++++++----------- 8 files changed, 147 insertions(+), 38 deletions(-) create mode 100644 src/animal.ml create mode 100644 src/content/assets/img/sheep.png diff --git a/.ocamlformat b/.ocamlformat index c54116a..078d270 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,4 +1,4 @@ -version=0.24.1 +version=0.25.1 assignment-operator=end-line break-cases=fit break-fun-decl=wrap diff --git a/src/animal.ml b/src/animal.ml new file mode 100644 index 0000000..473f96b --- /dev/null +++ b/src/animal.ml @@ -0,0 +1,62 @@ +type fairy = + { mana : int + ; pos : Map.position + } + +type t = + | Sheep of { pos : Map.position } + | Fairy of fairy + +let pp fmt = function + | Sheep o -> Format.fprintf fmt "Sheep: %a" Map.pp_position o.pos + | Fairy o -> + Format.fprintf fmt "Fairy : mana = %d, %a" o.mana Map.pp_position o.pos + +let make_sheep ~x ~y = + Sheep + { pos = + Map. + { x; y; offset_x = 0.; offset_y = 0.; dir = Obj.magic (x * y mod 4) } + } + +let make_fairy ~x ~y = + { mana = 1; pos = Map.{ x; y; offset_x = 0.; offset_y = 0.; dir = Down } } + +let pos = function Sheep o -> o.pos | Fairy o -> o.pos + +let set_pos pos = function + | Sheep _o -> Sheep { pos } + | Fairy o -> Fairy { o with pos } + +module Herd = struct + (* ... or just use a mutable state and a hashtbl? *) + module IntMap = Stdlib.Map.Make (struct + type t = int + + let compare = Int.compare + end) + + type nonrec t = t IntMap.t + + let find_opt = IntMap.find_opt + + let update = IntMap.update + + let iter = IntMap.iter + + let init map = + List.init 50 (fun _i -> + let x = Random.int map.width in + let y = Random.int map.height in + (x, y) ) + |> List.filter (fun (x, y) -> Map.get_tile_kind ~x ~y map = Grass) + |> List.mapi (fun i (x, y) -> (i, make_sheep ~x ~y)) + |> List.to_seq |> IntMap.of_seq + + let pp fmt o = + Format.fprintf fmt "[%a]" + (Format.pp_print_list + ~pp_sep:(fun _fmt () -> Format.pp_print_string fmt "; ") + pp ) + (IntMap.to_seq o |> List.of_seq |> List.map snd) +end diff --git a/src/content/assets/img/sheep.png b/src/content/assets/img/sheep.png new file mode 100644 index 0000000000000000000000000000000000000000..7ba231a8d5a0bc3ccea17d5291a53508c872a432 GIT binary patch literal 21508 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 b6ea6rCMTb^ocN4^fq}u()z4*}Q$iB})+hPo literal 0 HcmV?d00001 diff --git a/src/dune b/src/dune index db008b0..9e5e468 100644 --- a/src/dune +++ b/src/dune @@ -45,7 +45,7 @@ (library (name shared) - (modules log map network state time) + (modules animal log map network state time) (libraries)) (rule diff --git a/src/island.ml b/src/island.ml index ad37b85..9e6bb4d 100644 --- a/src/island.ml +++ b/src/island.ml @@ -43,6 +43,7 @@ let get request = ; "papy_up" ; "water" ; "wheat" + ; "sheep" ] in diff --git a/src/island_client.ml b/src/island_client.ml index 1f25a64..e5d3593 100644 --- a/src/island_client.ml +++ b/src/island_client.ml @@ -53,6 +53,8 @@ let water = C2d.image_src_of_el (get_el "water") let wheat = C2d.image_src_of_el (get_el "wheat") +let sheep = C2d.image_src_of_el (get_el "sheep") + let draw_canvas = let offset_conv = let m = float_of_int @@ (tile_size / 2) in @@ -66,14 +68,16 @@ let draw_canvas = let open State in (* TODO: it could be possible to optimize starting/ending index by looking at the offset *) for x = -2 to tiles_per_w + 1 do - let map_x = x + state.player_pos.x - half_tiles_per_w in + let map_x = x + state.player.pos.x - half_tiles_per_w in let tile_x = - float_of_int ((x * tile_size) + orig_x) +. offset_conv state.offset_x + float_of_int ((x * tile_size) + orig_x) + +. offset_conv state.player.pos.offset_x in for y = -2 to tiles_per_h + 1 do - let map_y = y + state.player_pos.y - half_tiles_per_h in + let map_y = y + state.player.pos.y - half_tiles_per_h in let tile_y = - float_of_int ((y * tile_size) + orig_y) +. offset_conv state.offset_y + float_of_int ((y * tile_size) + orig_y) + +. offset_conv state.player.pos.offset_y in let tile_img = match Map.get_tile_kind ~x:map_x ~y:map_y state.map with @@ -82,11 +86,18 @@ let draw_canvas = | Black -> water | Wheat -> wheat in - C2d.draw_image context tile_img ~x:tile_x ~y:tile_y + C2d.draw_image context tile_img ~x:tile_x ~y:tile_y; + (* TODO *) + Herd.iter + (fun _v k -> + let pos = Animal.pos k in + if pos.x = map_x && pos.y = map_y then + C2d.draw_image context sheep ~x:tile_x ~y:tile_y ) + state.animals done done; let papy = - match state.player_pos.dir with + match state.player.pos.dir with | Left -> papy_left | Right -> papy_right | Down -> papy_down @@ -98,7 +109,7 @@ let draw_topbar state = (* draw mana level *) let mana_lvl = Jv.get Jv.global "mana_lvl" in Jv.set mana_lvl "innerHTML" - (Jv.of_string @@ string_of_int state.Shared.State.mana); + (Jv.of_string @@ string_of_int state.Shared.State.player.mana); (* draw wheat level *) let wheat_lvl = Jv.get Jv.global "wheat_lvl" in Jv.set wheat_lvl "innerHTML" (Jv.of_string @@ string_of_int state.wheat) @@ -121,7 +132,8 @@ let send_action state = function end *) (* actions we want to send to the server *) - | (State.Move_offset _ | Move _ | Meditate | Plant_wheat) as action -> ( + | (State.Move_offset _ | Move _ | Animal_move _ | Meditate | Plant_wheat) as + action -> ( match State.check_action state action with | Error e -> (* TODO: display this in the window *) diff --git a/src/map.ml b/src/map.ml index ea9c498..492cc97 100644 --- a/src/map.ml +++ b/src/map.ml @@ -30,14 +30,24 @@ let pp_background fmt b = in Format.pp_print_string fmt s -type position = +type simple_position = { x : int ; y : int ; dir : dir } +type position = + { x : int + ; y : int + ; offset_x : float + ; offset_y : float + ; dir : dir + } + let pp_position fmt p = - Format.fprintf fmt "(x = %d; y = %d; dir = %a)" p.x p.y pp_dir p.dir + Format.fprintf fmt + "(x = %d; y = %d; offset_x = %03f; offset_y = %03f; dir = %a)" p.x p.y + p.offset_x p.offset_y pp_dir p.dir type t = { tiles : background array array diff --git a/src/state.ml b/src/state.ml index cc8af84..ea3913b 100644 --- a/src/state.ml +++ b/src/state.ml @@ -37,22 +37,21 @@ end = struct else (x, y', None) end +module Herd = Animal.Herd + type t = { map : Map.t - ; mana : int ; wheat : int - ; player_pos : Map.position - ; offset_x : float - ; offset_y : float + ; player : Animal.fairy + ; animals : Herd.t } let init () = - { map = Map.init () - ; mana = 0 + let map = Map.init () in + { map ; wheat = 0 - ; player_pos = { x = 0; y = 0; dir = Down } - ; offset_x = 0. - ; offset_y = 0. + ; player = Animal.make_fairy ~x:0 ~y:0 + ; animals = Herd.init map } type action = @@ -60,6 +59,7 @@ type action = (* TODO some action do not needs to be checked by server *) | Move_offset of Map.dir | Move of Map.dir + | Animal_move of int * Map.dir | Plant_wheat (* TODO: we don't need dir so we should change the type of Map.position *) @@ -67,6 +67,7 @@ type action = type action' = | Add_mana of int | Set_player_position of Map.position + | Set_animal_position of (int * Map.position) | Set_offset of float * float | Plant_wheat of int * int @@ -74,12 +75,16 @@ let pp_action fmt = function | Meditate -> Format.pp_print_string fmt "Meditate" | Move_offset dir -> Format.fprintf fmt "Move_offset %a" Map.pp_dir dir | Move dir -> Format.fprintf fmt "Move %a" Map.pp_dir dir + | Animal_move (id, dir) -> + Format.fprintf fmt "Animal_move %d %a" id Map.pp_dir dir | Plant_wheat -> Format.fprintf fmt "Plant_wheat" let pp_action' fmt = function | Add_mana n -> Format.fprintf fmt "Add_mana %d" n | Set_player_position pos -> Format.fprintf fmt "Set_player_position (%a)" Map.pp_position pos + | Set_animal_position (id, pos) -> + Format.fprintf fmt "Set_animal_position (%d,%a)" id Map.pp_position pos | Set_offset (x, y) -> Format.fprintf fmt "Set_offset (%f, %f)" x y | Plant_wheat (x, y) -> Format.fprintf fmt "Plant_wheat (%d, %d)" x y @@ -87,20 +92,28 @@ let plant_wheat_cost = 10 let rec check_action state = function | Meditate -> - if state.mana < 99 then Ok [ Add_mana 1 ] else Error "maximum mana" + if state.player.mana < 99 then Ok [ Add_mana 1 ] else Error "maximum mana" | Move dir -> ( - match Map.check_move state.map state.player_pos dir with + match Map.check_move state.map state.player.pos dir with | Error _e as error -> error | Ok pos -> Ok [ Set_player_position pos ] ) + | Animal_move (id, dir) -> ( + match Herd.find_opt id state.animals with + | None -> Error (Format.sprintf "unknown animal id: %d" id) + | Some animal -> ( + match Map.check_move state.map (Animal.pos animal) dir with + | Error _e as error -> error + | Ok pos -> Ok [ Set_animal_position (id, pos) ] ) ) | Move_offset dir -> - if dir <> state.player_pos.dir then - Ok [ Set_player_position { state.player_pos with dir } ] + if dir <> state.player.pos.dir then + Ok [ Set_player_position { state.player.pos with dir } ] else let offset_x, offset_y, dir' = - Offset.check_move ~x:state.offset_x ~y:state.offset_y dir + Offset.check_move ~x:state.player.pos.offset_x + ~y:state.player.pos.offset_y dir in let offset_action = - [ Set_player_position { state.player_pos with dir } + [ Set_player_position { state.player.pos with dir } ; Set_offset (offset_x, offset_y) ] in @@ -114,7 +127,7 @@ let rec check_action state = function end end | Plant_wheat -> ( - let { Map.x; y; dir } = state.player_pos in + let { Map.x; y; dir; _ } = state.player.pos in let x, y = match dir with | Down -> (x, y + 1) @@ -127,16 +140,27 @@ let rec check_action state = function | Water -> Error "can't plant wheat in water !" | Wheat -> Error "there's already some wheat there !" | Grass -> - if state.mana >= plant_wheat_cost then Ok [ Plant_wheat (x, y) ] + if state.player.mana >= plant_wheat_cost then Ok [ Plant_wheat (x, y) ] else Error "not enough mana..." ) let perform_action state = function - | Add_mana n -> { state with mana = state.mana + n } - | Set_player_position player_pos -> { state with player_pos } - | Set_offset (offset_x, offset_y) -> { state with offset_x; offset_y } + | Add_mana n -> + { state with player = { state.player with mana = state.player.mana + n } } + | Set_player_position pos -> { state with player = { state.player with pos } } + | Set_animal_position (id, pos) -> + { state with + animals = Herd.update id (Option.map (Animal.set_pos pos)) state.animals + } + | Set_offset (offset_x, offset_y) -> + { state with + player = + { state.player with pos = { state.player.pos with offset_x; offset_y } } + } | Plant_wheat (x, y) -> state.map.tiles.(x).(y) <- Map.Wheat; - { state with mana = state.mana - plant_wheat_cost } + { state with + player = { state.player with mana = state.player.mana - plant_wheat_cost } + } let auto_update state = let state = @@ -145,12 +169,12 @@ let auto_update state = | Ok actions -> List.fold_left perform_action state actions in let count_wheat = Map.count_wheat state.map.tiles in + (* TODO simulate animals *) { state with wheat = state.wheat + count_wheat } let auto_update_rate = Time.mk_s 1 -let pp fmt { mana; wheat; player_pos; map; offset_x; offset_y } = - let bg = Map.get_tile_kind ~x:player_pos.x ~y:player_pos.y map in - Format.fprintf fmt - "mana = %d; wheat = %d; player_pos = %a; %a; offset_x = %f; offset_y = %f" - mana wheat Map.pp_position player_pos Map.pp_background bg offset_x offset_y +let pp fmt { wheat; player; map; animals } = + let bg = Map.get_tile_kind ~x:player.pos.x ~y:player.pos.y map in + Format.fprintf fmt "wheat = %d; player = %a; %a; animals = %a" wheat Animal.pp + (Fairy player) Map.pp_background bg Herd.pp animals