Skip to content

Commit

Permalink
feat: add test for dynamic_card and canon.
Browse files Browse the repository at this point in the history
  • Loading branch information
dennyabrain committed Sep 4, 2024
1 parent 4227c27 commit 696e218
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 26 deletions.
21 changes: 20 additions & 1 deletion lib/viral_spiral/affinity.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
defmodule ViralSpiral.Affinity do
alias ViralSpiral.Affinity
import ViralSpiral.Game.EngineConfig.Guards

defstruct target: nil

@type target :: :cat | :sock | :highfive | :houseboat | :skub
@labels %{
cat: "Cat",
sock: "Sock",
high_five: "High Five",
houseboat: "Houseboat",
skub: "Skub"
}

@type target :: :cat | :sock | :high_five | :houseboat | :skub
@type t :: %__MODULE__{
target: target()
}

def label(target) when is_affinity(target) do
@labels[target]
end

def label(%Affinity{} = affinity) do
@labels[affinity.target]
end
end
16 changes: 16 additions & 0 deletions lib/viral_spiral/bias.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
defmodule ViralSpiral.Bias do
alias ViralSpiral.Bias
import ViralSpiral.Game.EngineConfig.Guards
defstruct target: nil

@type target :: :red | :yellow | :blue
@type t :: %__MODULE__{
target: target()
}

@labels %{
red: "Red",
yellow: "Yellow",
blue: "Blue"
}

def label(target) when is_community(target) do
@labels[target]
end

def label(%Bias{} = affinity) do
@labels[affinity.target]
end
end
43 changes: 31 additions & 12 deletions lib/viral_spiral/canon/deck.ex
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ defmodule ViralSpiral.Canon.Deck do
Enum.reduce(
cards,
%{},
&Map.put(&2, &1.id, &1)
&Map.put(&2, {&1.id, &1.veracity}, &1)
)
end

Expand Down Expand Up @@ -315,7 +315,7 @@ defmodule ViralSpiral.Canon.Deck do
target: :sock,
veracity: false,
polarity: :positive,
headline: Enum.at(row, @columns.pro_sock),
headline: Enum.at(row, @columns.pro_sock_fake),
image: Enum.at(row, @columns.pro_sock_image)
},
%Affinity{
Expand All @@ -333,7 +333,7 @@ defmodule ViralSpiral.Canon.Deck do
target: :sock,
veracity: false,
polarity: :negative,
headline: Enum.at(row, @columns.anti_sock),
headline: Enum.at(row, @columns.anti_sock_fake),
image: Enum.at(row, @columns.anti_sock_image)
},
%Affinity{
Expand All @@ -351,7 +351,7 @@ defmodule ViralSpiral.Canon.Deck do
target: :skub,
veracity: false,
polarity: :positive,
headline: Enum.at(row, @columns.pro_skub),
headline: Enum.at(row, @columns.pro_skub_fake),
image: Enum.at(row, @columns.pro_skub_image)
},
%Affinity{
Expand All @@ -369,7 +369,7 @@ defmodule ViralSpiral.Canon.Deck do
target: :skub,
veracity: false,
polarity: :negative,
headline: Enum.at(row, @columns.anti_skub),
headline: Enum.at(row, @columns.anti_skub_fake),
image: Enum.at(row, @columns.anti_skub_image)
},
%Affinity{
Expand All @@ -387,7 +387,7 @@ defmodule ViralSpiral.Canon.Deck do
target: :highfive,
veracity: false,
polarity: :positive,
headline: Enum.at(row, @columns.pro_high_five),
headline: Enum.at(row, @columns.pro_high_five_fake),
image: Enum.at(row, @columns.pro_high_five_image)
},
%Affinity{
Expand All @@ -405,7 +405,7 @@ defmodule ViralSpiral.Canon.Deck do
target: :highfive,
veracity: false,
polarity: :negative,
headline: Enum.at(row, @columns.anti_highfive),
headline: Enum.at(row, @columns.anti_highfive_fake),
image: Enum.at(row, @columns.anti_highfive_image)
},
%Affinity{
Expand Down Expand Up @@ -456,7 +456,12 @@ defmodule ViralSpiral.Canon.Deck do
]
end

defp card_id(headline) do
@doc """
Generate a hash of the card headline.
Throughout the csv files, viral spiral writers use the card headline as a link between various sheets and rows.
"""
def card_id(headline) do
"card_" <> Integer.to_string(:erlang.phash2(headline))
end

Expand Down Expand Up @@ -523,7 +528,9 @@ defmodule ViralSpiral.Canon.Deck do
end

defp choose_one(list) do
list |> Enum.shuffle() |> Enum.take(1) |> hd |> Map.get(:id)
ix = :rand.uniform(list |> Enum.to_list() |> length)

list |> Enum.at(ix) |> Map.get(:id)
end

def key(card) do
Expand Down Expand Up @@ -613,14 +620,26 @@ defmodule ViralSpiral.Canon.Deck do
|> Enum.map(fn card ->
try do
if card.type == :conflated do
IO.inspect(card)
# IO.inspect(card)
end

article_id = articles[{card.id, card.veracity}]
%{card | article_id: article_id}
article = articles[{card.id, card.veracity}]
%{card | article_id: article.id}
rescue
KeyError -> card
end
end)
end

def get_fake_card(store, card_id) when is_bitstring(card_id) do
store[{card_id, false}]
end

def get_fake_card(store, card) do
store[{card.id, false}]
end

def substitute_text(state, card) do

Check warning on line 642 in lib/viral_spiral/canon/deck.ex

View workflow job for this annotation

GitHub Actions / build-and-deploy

variable "state" is unused (if the variable is not meant to be used, prefix it with an underscore)
card
end
end
68 changes: 68 additions & 0 deletions lib/viral_spiral/canon/dynamic_card.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
defmodule ViralSpiral.Canon.DynamicCard do
@moduledoc """
Changes card text dynamically.
Viral Spiral card texts have placeholders that get replaced at runtime by the game engine. We call these cards to be having dynamic text. Some examples of dynamic texts in cards are :
- City revokes docking privileges for (other community) HoBos - "If they like the water so much they can stay there!
- (oppressed community) ghetto vandalized, burned down during hilarious (popular affinity) day parade hooliganism
Supported placeholders are : (other community), (dominant community), (oppressed community), (unpopular affinity), (popular affinity).
## Example Usage
headline = "People who like (unpopular affinity) are usually (dominant community)"
matches = DynamicCard.find_placeholders(headline)
replacements = %{
unpopular_affinity: :skub,
dominant_community: :red
}
new_headline = DynamicCard.replace_text(headline, matches, replacements)
In practice you'd require visibility into the game state to create the replacements map show above. This falls under the responsibility of `ViralSpiral.Room.State.Analytics`
"""
alias ViralSpiral.Bias
alias ViralSpiral.Affinity

@mappings [
{"(other community)", :other_community},
{"(dominant community)", :dominant_community},
{"(oppressed community)", :oppressed_community},
{"(unpopular affinity)", :unpopular_affinity},
{"(popular affinity)", :popular_affinity}
]
@string_to_atom_map Enum.reduce(@mappings, %{}, fn x, acc ->
Map.put(acc, elem(x, 0), elem(x, 1))
end)
@atom_to_string_map Enum.reduce(@mappings, %{}, fn x, acc ->
Map.put(acc, elem(x, 1), elem(x, 0))
end)

def find_placeholders(headline) do
results =
Regex.scan(
~r/(\(oppressed community\)|\(popular affinity\)|\(unpopular affinity\)|\(other community\)|\(dominant community\))/,
headline
)

results
|> Enum.map(&Enum.at(&1, 0))
|> Enum.map(&@string_to_atom_map[&1])
end

def replace_text(headline, matches, replacements) do
Enum.reduce(
matches,
headline,
fn el, acc ->
String.replace(acc, @atom_to_string_map[el], label(replacements[el]))
end
)
end

defp label(atom) do
case atom do
x when x in [:cat, :skub, :high_five, :houseboat, :sock] -> Affinity.label(atom)
y when y in [:red, :yellow, :blue] -> Bias.label(atom)
end
end
end
6 changes: 5 additions & 1 deletion lib/viral_spiral/canon/encyclopedia.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ defmodule ViralSpiral.Canon.Encyclopedia do
"""
def create_store(articles) do
articles
|> Enum.reduce(%{}, fn el, acc -> Map.put(acc, {el.card_id, el.veracity}, el.id) end)
|> Enum.reduce(%{}, fn el, acc -> Map.put(acc, {el.card_id, el.veracity}, el) end)
end

def get_article_by_card(article_store, card) do
article_store[{card.id, card.veracity}]
end
end
4 changes: 2 additions & 2 deletions lib/viral_spiral/card_share.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ end

defimpl ViralSpiral.CardShare, for: ViralSpiral.Canon.Card.Topical do
def pass(card, state, from, to) do

Check warning on line 17 in lib/viral_spiral/card_share.ex

View workflow job for this annotation

GitHub Actions / build-and-deploy

variable "card" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/viral_spiral/card_share.ex

View workflow job for this annotation

GitHub Actions / build-and-deploy

variable "from" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/viral_spiral/card_share.ex

View workflow job for this annotation

GitHub Actions / build-and-deploy

variable "state" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 17 in lib/viral_spiral/card_share.ex

View workflow job for this annotation

GitHub Actions / build-and-deploy

variable "to" is unused (if the variable is not meant to be used, prefix it with an underscore)
IO.inspect("returning changes for Bias card")
# IO.inspect("returning changes for Bias card")
end

def keep(card, state, from) do
Expand Down Expand Up @@ -73,7 +73,7 @@ end

defimpl ViralSpiral.CardShare, for: ViralSpiral.Canon.Card.Conflated do
def pass(card, state, from, to) do
IO.inspect("returning changes for Bias card")
# IO.inspect("returning changes for Bias card")
end

def keep(card, state, from) do
Expand Down
7 changes: 7 additions & 0 deletions lib/viral_spiral/room/state/analytics.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule ViralSpiral.Room.State.Analytics do
@moduledoc """
Find insights into the room durin gameplay.
As part of the gameplay we often need to know information like who is winning the game or which community is performing well etc. This module provides helpers for that
"""
end
6 changes: 4 additions & 2 deletions lib/viral_spiral/room/state/player.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ defmodule ViralSpiral.Room.State.Player do
clout: 0
}
"""
alias ViralSpiral.Bias
alias ViralSpiral.Affinity
alias ViralSpiral.Room.State.Player
alias ViralSpiral.Game.EngineConfig
alias ViralSpiral.Game.Player, as: PlayerData
Expand All @@ -25,8 +27,8 @@ defmodule ViralSpiral.Room.State.Player do
}

@spec new(t(), %ViralSpiral.Game.EngineConfig{
:affinities => list(),
:communities => list()
:affinities => list(Affinity.t()),
:communities => list(Bias.t())
}) :: t()
def new(%PlayerData{} = player, %EngineConfig{} = room_config) do
bias_list = Enum.filter(room_config.communities, &(&1 != player.identity))
Expand Down
52 changes: 52 additions & 0 deletions test/viral_spiral/canon/dynamic_card_text.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule ViralSpiral.Canon.DynamicCardTest do
use ExUnit.Case
alias ViralSpiral.Canon.DynamicCard

test "find placeholder text for (other community)" do
headline = "(other community) club shover crime spree continues - another rave in disarray"
matches = DynamicCard.find_placeholders(headline)
assert Enum.at(matches, 0) == :other_community
end

test "find placeholder text for (dominant community)" do
headline = "(dominant community) club shover crime spree continues - another rave in disarray"
matches = DynamicCard.find_placeholders(headline)
assert Enum.at(matches, 0) == :dominant_community
end

test "find placeholder text for (oppressed community)" do
headline =
"City announces discriminatory rating system to filter 'productive' members of (oppressed community) community from others"

matches = DynamicCard.find_placeholders(headline)
assert Enum.at(matches, 0) == :oppressed_community
end

test "find placeholder text for (popuar affinity)" do
headline = "People who like (popular affinity) are good"

matches = DynamicCard.find_placeholders(headline)
assert Enum.at(matches, 0) == :popular_affinity
end

test "find placeholder text for (unpopuar affinity)" do
headline = "People who like (unpopular affinity) are good"

matches = DynamicCard.find_placeholders(headline)
assert Enum.at(matches, 0) == :unpopular_affinity
end

test "replace multiple placeholder text" do
headline = "People who like (unpopular affinity) are usually (dominant community)"

matches = DynamicCard.find_placeholders(headline)

replacements = %{
unpopular_affinity: :skub,
dominant_community: :red
}

new_headline = DynamicCard.replace_text(headline, matches, replacements)
assert new_headline == "People who like Skub are usually Red"
end
end
Loading

0 comments on commit 696e218

Please sign in to comment.