39 lines
1.2 KiB
Elixir
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
|