53 lines
1.2 KiB
Haskell
53 lines
1.2 KiB
Haskell
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
|
module Hanafuda.Game where
|
|
|
|
import Data.Map (Map, empty, fromList)
|
|
import Hanafuda.Card (Card, Pack, contains, packOfCards, remove)
|
|
import Hanafuda.Yaku (Score, Points)
|
|
|
|
data Player =
|
|
Player1
|
|
| Player2
|
|
deriving (Eq, Ord)
|
|
|
|
next :: Player -> Player
|
|
next Player1 = Player2
|
|
next _ = Player1
|
|
|
|
data PlayerState = PlayerState {
|
|
hand :: Pack
|
|
, meld :: Pack
|
|
, yakus :: Score
|
|
}
|
|
type Players = Map Player PlayerState
|
|
|
|
players :: [Player]
|
|
players = [Player1, Player2]
|
|
|
|
deal :: [a] -> Map Player a
|
|
deal = fromList . zip players
|
|
|
|
initPlayers :: [[Card]] -> Players
|
|
initPlayers =
|
|
deal . map player
|
|
where
|
|
player cards = PlayerState {
|
|
hand = packOfCards cards
|
|
, meld = packOfCards []
|
|
, yakus = empty
|
|
}
|
|
|
|
plays :: PlayerState -> Card -> Either String PlayerState
|
|
plays player@(PlayerState {hand}) card =
|
|
if hand `contains` card
|
|
then Right $ player {hand = remove hand card}
|
|
else Left "You don't have this card"
|
|
|
|
data Move = Play Card | Capture (Card, Card) | Choose Card | KoiKoi Bool
|
|
|
|
type Scores = Map Player Points
|
|
|
|
class Game a b where
|
|
play :: a -> Move -> Either String b
|