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"}
]
endQuick 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
endModules
TamerlaneHelpers.Helpers
Core helper functions:
- Player Management:
hand_for/2,seating_from/2,next_player/2,other_player/2,player_ids/1 - Card Operations:
card_value/1,card_suit/1,cards_of_suit/2 - Events:
draw/2,draw_to_stack/2,move_cards/2,reset_cards/0,start_new_hand/1 - Locations:
stack/1,hand/1 - Prompts:
build_prompt/3 - Decorations:
build_decorations/1 - State:
increment_in/2,build_infos/2 - Scoring:
game_over?/2,winners/1 - Turn Validation:
extract_action/1,turn?/2,validate_turn/2 - Utilities:
hand_empty_after_play?/3
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:
playable_cards/3- Filter hand to legally playable cardstrick_winner/2- Determine who won a tricklead_suit/1- Get the led suit from trick cardsfollows_suit?/2- Check if a card follows the led suitheads_trick?/3- Check if a card would win the current trick
# 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