At Domain Drive Design Europe I met the wonderful @Felienne. In the evening we played the card game bridge (a game the Felienne likes a lot). As a West-Vlaming I love the card game Manillen more, of course, and we joked about it. Felienne has the ambition to create an AI to compete at the world championship of Computer Bridge, and I have joked about some similar ambitions of mine at Socrates Belgium, but this blog post has a much more humble goal. I want to try to explain the rules of Manillen or Manille to you with Elm. If you are to eager and want to find out more about the game (and the rules), see wikipedia.
So lets start.
These are the valid cards:
type Suit = Spade | Club | Diamond | Heart
type Rank = Manille | Ace | King | Queen | Jack | Nine | Eight | Seven
type alias Card = (Suit, Rank)
The Manille
is the number 10 in a card deck.
The game is played with 32 cards (4 * 8), thus, this is the full deck:
type alias Deck = List Card
deck : Deck
deck =
[ (Spade, Manille), (Club, Manille), (Diamond, Manille), (Heart, Manille)
, (Spade, Ace), (Club, Ace), (Diamond, Ace), (Heart, Ace)
, (Spade, King), (Club, King), (Diamond, King), (Heart, King)
, (Spade, Queen), (Club, Queen), (Diamond, Queen), (Heart, Queen)
, (Spade, Jack), (Club, Jack), (Diamond, Jack), (Heart, Jack)
, (Spade, Nine), (Club, Nine), (Diamond, Nine), (Heart, Nine)
, (Spade, Eight), (Club, Eight), (Diamond, Eight), (Heart, Eight)
, (Spade, Seven), (Club, Seven), (Diamond, Seven), (Heart, Seven)
]
or shorter we could write it like this:
suits =
[ Spade, Club, Diamond, Heart ]
allCardsOfRank rank =
suits |> List.map (\suit -> ( suit, rank ))
ranks =
[ Manille, Ace, King, Queen, Jack, Nine, Eight, Seven ]
deck : List Card
deck =
ranks |> List.concatMap allCardsOfRank
but I find the longer version more readable.
So to start playing we need players:
type Player
= Front
| Left
| Back
| Right
wulder : ( Player, Player )
wulder =
( Front, Back )
zulder : ( Player, Player )
zulder =
( Left, Right )
We play in 2 teams, wulder vs zulder (West-Flemish for we and them)
Before we start playing, I’m going to explain how the scoring works and how you can win a game.
points : Rank -> Int
points rank =
case rank of
Manille ->
5
Ace ->
4
King ->
3
Queen ->
2
Jack ->
1
_ ->
0
score : List Card -> Int
score cards =
let
ranks =
List.map snd cards
allpoints =
List.map points ranks
in
List.sum allpoints
With elm-test we can see a constraint
[ test "A full deck scores always 60" ((score deck) `assertEqual` 60) ]
And with elm-check (a toolkit for writing property based tests) we see these properties: