diamondtail/lib/diamondtail/genometracker.ex
2025-11-09 10:31:56 +01:00

39 lines
1.2 KiB
Elixir

defmodule Diamondtail.Genometracker do
@moduledoc """
This agent keeps track of which genome is associated with each running game,
it handles taking out a genome from the Population to assign it to a game and reintroducing new genomes after the end of the game.
"""
alias Diamondtail.Population.Genome
alias Diamondtail.Population
use Agent
def start_link(_) do
Agent.start_link(fn -> %{} end, name: __MODULE__)
end
@spec game_start({String.t(), String.t()}) :: :ok
def game_start(id) do
genome = Population.take_random()
Agent.update(__MODULE__, &Map.put(&1, id, genome))
end
@spec get_genome({String.t(), String.t()}) :: Genome.t() | nil
def get_genome(id) do
Agent.get(__MODULE__, &Map.get(&1, id))
end
@spec game_end({String.t(), String.t()}, boolean()) :: nil
def game_end(id, victory?) do
genome = Agent.get_and_update(__MODULE__, &Map.pop(&1, id))
# If this genome lost, we will not reintroduce it into the population, effectively "killing" it
if victory? do
# The genome will create three "offspring", amount could be tweaked
for _ <- 0..3 do
Population.add(Genome.mutate(genome))
end
end
end
end