TamerlaneHelpers

Helper library for building Tamerlane card game rules engines.

Installation

Add tamerlane_helpers to your list of dependencies in mix.exs:

def deps do
  [
    {:tamerlane_helpers, "~> 0.1.0"}
  ]
end

Quick Start

defmodule MyGame.Rules do
  @behaviour TamerlaneHelpers.RulesEngine

  alias TamerlaneHelpers.Helpers, as: H
  alias TamerlaneHelpers.Response

  @impl true
  def config do
    %{
      "game" => %{"name" => "My Game", "min_players" => 2, "max_players" => 4},
      "deck" => "52",
      "stacks" => [%{"id" => "discard", "label" => "Discard", "layout" => "pile"}]
    }
  end

  @impl true
  def init(player_ids) do
    %{
      "players" => Enum.map(player_ids, &%{"id" => &1, "meta" => %{}}),
      "state" => %{"phase" => "deal"}
    }
  end

  @impl true
  def next(state, players, action) do
    hand = H.hand_for(players, state["turn"])
    prompt = H.build_prompt(state["turn"], hand, name: "play", count: 1)
    decorations = H.build_decorations([{state["turn"], "turn", "Your Turn"}])

    response = Response.new([], state, prompt: prompt, decorations: decorations)
    {:ok, Response.to_map(response)}
  end
end

Modules

TamerlaneHelpers.Helpers

Core helper functions:

TamerlaneHelpers.Response

Response struct for next/3 return values. State must be a map with a "phase" key:

state = %{"phase" => "play", "turn" => "Alice"}
response = Response.new(events, state,
  prompt: prompt,
  decorations: decorations,
  infos: infos
)
{:ok, Response.to_map(response)}

TamerlaneHelpers.TrickTaking

Helpers for trick-taking games using Parlett's notation:

# Standard Whist: follow suit or play any card
playable = TrickTaking.playable_cards(state, hand, rules: [:f, :r])

# Tarock: must trump if void in led suit
playable = TrickTaking.playable_cards(state, hand,
  rules: [:f, :t, :r],
  trump_suit: "trumps"
)

# Determine trick winner
{winner, card} = TrickTaking.trick_winner(trick_cards, trump_suit: "spades")

TamerlaneHelpers.RulesEngine

Behaviour that rules engines must implement:

@callback config() :: map()
@callback init([String.t()]) :: map()
@callback next(map(), [map()], map() | nil) :: {:ok, map()}

License

MIT