Skip to content

Commit

Permalink
Add function to calculate map configurations hash version value
Browse files Browse the repository at this point in the history
  • Loading branch information
Nico-Sanchez committed Sep 10, 2024
1 parent 7ec0009 commit 38ae9a4
Showing 1 changed file with 43 additions and 5 deletions.
48 changes: 43 additions & 5 deletions apps/game_backend/lib/game_backend/configuration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ defmodule GameBackend.Configuration do
Configuration context for GameBackend
"""
import Ecto.Query
require Decimal
alias Ecto.Multi
alias GameBackend.CurseOfMirra.GameConfiguration
alias GameBackend.CurseOfMirra.MapConfiguration.Position
alias GameBackend.Items.ConsumableItem
alias GameBackend.Units.Characters.Character
alias GameBackend.CurseOfMirra.MapConfiguration
Expand Down Expand Up @@ -542,13 +544,49 @@ defmodule GameBackend.Configuration do
Repo.one(from(g in GameConfiguration, order_by: [desc: g.inserted_at], limit: 1))
end

@doc """
Returns a 16 base encoded string representing the hashed value of the map configurations.
## Examples
iex> get_configuration_hash_version()
"A6F0CC6917D195AB8A03129ACBE1FA48364845B8"
"""
def get_configuration_hash_version do
get_current_version()
|> Map.get(:map_configurations)
|> Enum.flat_map(fn map_config -> Map.get(map_config, :obstacles) end)
|> Enum.flat_map(fn obstacle -> obstacle.vertices end)
|> Enum.map(fn position -> Decimal.to_string(position.x) <> Decimal.to_string(position.y) end)
|> Enum.reduce(fn position_sum_last, position_sum_current -> position_sum_current <> position_sum_last end)
|> (fn position_sum_string -> :crypto.hash(:sha, position_sum_string) |> Base.encode16() end).()
|> Enum.flat_map(fn map_config ->
Map.take(map_config, [:obstacles, :initial_positions, :bushes, :radius]) |> Map.values()
end)
|> List.flatten()
|> Enum.map(fn config -> sum_shape_coordinates(config) end)
|> Enum.reduce(fn coordinates_last, coordinates_current -> Decimal.add(coordinates_last, coordinates_current) end)
|> Decimal.to_string()
|> (fn coordinates -> :crypto.hash(:sha, coordinates) |> Base.encode16() end).()
end

# The following function retrieves a number representing a shape's figure.
# If it's a circle, gets its radius.
# For everything else, gets its vertices' positions.
# And for everyone, gets their positions in map.
# Calculate the sum of every retrieved value.
defp sum_shape_coordinates(%Position{x: x, y: y}) do
Decimal.add(x, y)
end

defp sum_shape_coordinates(%{shape: "circle"} = obstacle) do
Decimal.add(obstacle.radius, sum_shape_coordinates(obstacle.position))
end

defp sum_shape_coordinates(map_radius) when Decimal.is_decimal(map_radius) do
map_radius
end

defp sum_shape_coordinates([]), do: Decimal.new(0)

defp sum_shape_coordinates([vertex | vertices]) do
Decimal.add(sum_shape_coordinates(vertex), sum_shape_coordinates(vertices))
end

defp sum_shape_coordinates(%{position: position, vertices: vertices}) do
Decimal.add(sum_shape_coordinates(position), sum_shape_coordinates(vertices))
end
end

0 comments on commit 38ae9a4

Please sign in to comment.