module Wordify.Rules.Game.Internal (updateGame, Game(Game),
GameStatus(InProgress, Finished),
moveNumber,
playerNumber,
currentPlayer,
passes,
nextPlayer,
player1,
player2,
optionalPlayers,
gameStatus,
board,
bag,
pass,
dictionary,
updateHistory,
Move(PlaceTiles, Exchange, Pass),
History(History),
history) where
import Wordify.Rules.Player
import Wordify.Rules.Board
import Wordify.Rules.LetterBag
import Wordify.Rules.Dictionary
import Control.Applicative
import Data.Map
import Wordify.Rules.Pos
import Wordify.Rules.Tile
import Data.Sequence
data Move = PlaceTiles (Map Pos Tile) | Exchange [Tile] | Pass deriving (Eq, Show)
data History = History LetterBag (Seq Move) deriving (Eq, Show)
data GameStatus = InProgress | Finished deriving (Eq, Show)
data Game = Game { player1 :: Player
, player2 :: Player
, optionalPlayers :: Maybe (Player, Maybe Player)
, board :: Board
, bag :: LetterBag
, dictionary :: Dictionary
, currentPlayer :: Player
, playerNumber :: Int
, moveNumber :: Int
, passes :: Int
, gameStatus :: GameStatus
, history :: History }
updateGame :: Game -> Player -> Board -> LetterBag -> Game
updateGame game player newBoard newBag =
updatedPlayerGame {board = newBoard, bag = newBag, currentPlayer = newPlayer, playerNumber = newPlayerNum, moveNumber = succ moveNo, passes = 0}
where
updatedPlayerGame = updateCurrentPlayer game player
(newPlayerNum, newPlayer) = nextPlayer game
moveNo = moveNumber game
updateCurrentPlayer :: Game -> Player -> Game
updateCurrentPlayer game player =
case playing of
1 -> game {player1 = player}
2 -> game {player2 = player}
3 -> game {optionalPlayers = (\(_, player4) -> (player, player4)) <$> maybePlayers }
_ -> game {optionalPlayers = (\(player3, _) -> (player3, (Just player))) <$> maybePlayers }
where
playing = playerNumber game
maybePlayers = optionalPlayers game
nextPlayer :: Game -> (Int, Player)
nextPlayer game
| (playing == 1) = (2, playr2)
| (playing == 2 || playing == 3) =
maybe ( (1, playr1) ) (\(player3, player4) ->
if (playing == 2) then (3, player3 )
else
case player4 of
Just playr4 -> (4, playr4)
Nothing -> (1, playr1)
) $ maybePlayers
| otherwise = (1, playr1)
where
playing = playerNumber game
playr2 = player2 game
playr1 = player1 game
maybePlayers = optionalPlayers game
pass :: Game -> Game
pass game = game {moveNumber = succ moveNo, playerNumber = playerNo, currentPlayer = player, passes = succ numPasses}
where
(playerNo, player) = nextPlayer game
numPasses = passes game
moveNo = moveNumber game
updateHistory :: Game -> Move -> Game
updateHistory game move = game {history = History originalBag (moveList |> move) }
where
History originalBag moveList = history game