defmodule Odinsea.AntiCheat.CheaterData do @moduledoc """ Data structure for tracking cheaters. Ported from: handling.world.CheaterData.java Stores information about a cheating offense for reporting/broadcasting: - points: The point value of the offense - info: Description of the offense """ defstruct [:points, :info] @type t :: %__MODULE__{ points: integer(), info: String.t() } @doc """ Creates a new CheaterData entry. """ @spec new(integer(), String.t()) :: t() def new(points, info) do %__MODULE__{ points: points, info: info } end @doc """ Compares two CheaterData entries by points (descending order). """ @spec compare(t(), t()) :: :gt | :eq | :lt def compare(%__MODULE__{points: p1}, %__MODULE__{points: p2}) do cond do p1 > p2 -> :gt p1 == p2 -> :eq true -> :lt end end @doc """ Sorts a list of CheaterData by points (highest first). """ @spec sort_by_points(list(t())) :: list(t()) def sort_by_points(cheater_data_list) do Enum.sort(cheater_data_list, fn a, b -> compare(a, b) == :gt end) end @doc """ Gets the top N cheaters by points. """ @spec top_cheaters(list(t()), integer()) :: list(t()) def top_cheaters(cheater_data_list, n) do cheater_data_list |> sort_by_points() |> Enum.take(n) end @doc """ Calculates total points from a list of CheaterData. """ @spec total_points(list(t())) :: integer() def total_points(cheater_data_list) do Enum.reduce(cheater_data_list, 0, fn data, acc -> acc + data.points end) end @doc """ Formats CheaterData for display/logging. """ @spec format(t()) :: String.t() def format(%__MODULE__{points: points, info: info}) do "[#{points} pts] #{info}" end end