{-# LANGUAGE DeriveGeneric #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Use bimap" #-}
{-# HLINT ignore "Use first" #-}
module Game.Calc(PlayerInput(..), LineResult, LineType(..), PlayerCalculations(..), comparePlayers, calcGame) where
import CardParts.Cards (Card(..))
import Game.Combination
( Combination,
CombinationName(..),
Combination(RankCombination),
Combination(..) )
import CardParts.Values (Value(..))
import CardParts.Suits (Suit(..))
import GHC.Generics (Generic)
import Data.Aeson (FromJSON, ToJSON)
import Data.List (find)
data PlayerInput = PlayerInput {
PlayerInput -> String
username :: String,
PlayerInput -> [Combination]
board :: [Combination],
PlayerInput -> Bool
scoop :: Bool,
PlayerInput -> Bool
withFantasy :: Bool
} deriving (Int -> PlayerInput -> ShowS
[PlayerInput] -> ShowS
PlayerInput -> String
(Int -> PlayerInput -> ShowS)
-> (PlayerInput -> String)
-> ([PlayerInput] -> ShowS)
-> Show PlayerInput
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PlayerInput] -> ShowS
$cshowList :: [PlayerInput] -> ShowS
show :: PlayerInput -> String
$cshow :: PlayerInput -> String
showsPrec :: Int -> PlayerInput -> ShowS
$cshowsPrec :: Int -> PlayerInput -> ShowS
Show, (forall x. PlayerInput -> Rep PlayerInput x)
-> (forall x. Rep PlayerInput x -> PlayerInput)
-> Generic PlayerInput
forall x. Rep PlayerInput x -> PlayerInput
forall x. PlayerInput -> Rep PlayerInput x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PlayerInput x -> PlayerInput
$cfrom :: forall x. PlayerInput -> Rep PlayerInput x
Generic)
instance FromJSON PlayerInput
instance ToJSON PlayerInput
data LineType = Top | Middle | Bottom deriving (Int -> LineType -> ShowS
[LineType] -> ShowS
LineType -> String
(Int -> LineType -> ShowS)
-> (LineType -> String) -> ([LineType] -> ShowS) -> Show LineType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LineType] -> ShowS
$cshowList :: [LineType] -> ShowS
show :: LineType -> String
$cshow :: LineType -> String
showsPrec :: Int -> LineType -> ShowS
$cshowsPrec :: Int -> LineType -> ShowS
Show, (forall x. LineType -> Rep LineType x)
-> (forall x. Rep LineType x -> LineType) -> Generic LineType
forall x. Rep LineType x -> LineType
forall x. LineType -> Rep LineType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LineType x -> LineType
$cfrom :: forall x. LineType -> Rep LineType x
Generic)
instance FromJSON LineType
instance ToJSON LineType
type IntPair = (Int, Int)
type LineCompareResult = ([String], Int, Int, [IntPair])
data LineResult = LineResult {
LineResult -> LineType
lineType :: LineType,
LineResult -> Maybe Combination
combination :: Maybe Combination,
LineResult -> Int
points :: Int,
LineResult -> Int
totalCombination :: Int,
LineResult -> Int
totalBonus :: Int
} deriving (Int -> LineResult -> ShowS
[LineResult] -> ShowS
LineResult -> String
(Int -> LineResult -> ShowS)
-> (LineResult -> String)
-> ([LineResult] -> ShowS)
-> Show LineResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LineResult] -> ShowS
$cshowList :: [LineResult] -> ShowS
show :: LineResult -> String
$cshow :: LineResult -> String
showsPrec :: Int -> LineResult -> ShowS
$cshowsPrec :: Int -> LineResult -> ShowS
Show, (forall x. LineResult -> Rep LineResult x)
-> (forall x. Rep LineResult x -> LineResult) -> Generic LineResult
forall x. Rep LineResult x -> LineResult
forall x. LineResult -> Rep LineResult x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LineResult x -> LineResult
$cfrom :: forall x. LineResult -> Rep LineResult x
Generic)
instance FromJSON LineResult
instance ToJSON LineResult
data PlayerCalculations = PlayerCalculations {
PlayerCalculations -> PlayerInput
player :: PlayerInput,
PlayerCalculations -> LineResult
top :: LineResult,
PlayerCalculations -> LineResult
middle :: LineResult,
PlayerCalculations -> LineResult
bottom :: LineResult,
PlayerCalculations -> Bool
isScoop :: Bool,
PlayerCalculations -> Bool
isNextFantasy :: Bool,
PlayerCalculations -> (String, [LineCompareResult])
totalDetailed :: (String, [LineCompareResult]),
PlayerCalculations -> Int
total :: Int
} deriving ((forall x. PlayerCalculations -> Rep PlayerCalculations x)
-> (forall x. Rep PlayerCalculations x -> PlayerCalculations)
-> Generic PlayerCalculations
forall x. Rep PlayerCalculations x -> PlayerCalculations
forall x. PlayerCalculations -> Rep PlayerCalculations x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PlayerCalculations x -> PlayerCalculations
$cfrom :: forall x. PlayerCalculations -> Rep PlayerCalculations x
Generic)
instance FromJSON PlayerCalculations
instance ToJSON PlayerCalculations
calcGame :: [PlayerInput] -> [PlayerCalculations]
calcGame :: [PlayerInput] -> [PlayerCalculations]
calcGame [PlayerInput]
playerInputs
| [PlayerInput] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PlayerInput]
playerInputs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
3 = String -> [PlayerCalculations]
forall a. HasCallStack => String -> a
error String
"Invalid number of players"
| [(String, [LineCompareResult])] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(String, [LineCompareResult])]
linesResults Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
3 = String -> [PlayerCalculations]
forall a. HasCallStack => String -> a
error String
"Invalid number of linesResults"
| Bool
otherwise = (Int -> PlayerCalculations) -> [Int] -> [PlayerCalculations]
forall a b. (a -> b) -> [a] -> [b]
map Int -> PlayerCalculations
mapLinesResults [Int
0..Int
2]
where
linesResults :: [(String, [LineCompareResult])]
linesResults :: [(String, [LineCompareResult])]
linesResults = [LineCompareResult]
-> [PlayerInput]
-> [PlayerInput]
-> [(String, [LineCompareResult])]
collectLinesResults [] [PlayerInput]
playerInputs [PlayerInput]
playerInputs
mapLinesResults :: Int -> PlayerCalculations
mapLinesResults :: Int -> PlayerCalculations
mapLinesResults Int
index = PlayerCalculations :: PlayerInput
-> LineResult
-> LineResult
-> LineResult
-> Bool
-> Bool
-> (String, [LineCompareResult])
-> Int
-> PlayerCalculations
PlayerCalculations {
player :: PlayerInput
player = [PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index,
isScoop :: Bool
isScoop = PlayerInput -> Bool
scoop (PlayerInput -> Bool) -> PlayerInput -> Bool
forall a b. (a -> b) -> a -> b
$ [PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index,
isNextFantasy :: Bool
isNextFantasy =
Bool -> Bool
not (PlayerInput -> Bool
scoop ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index)) Bool -> Bool -> Bool
&&
Bool -> [Combination] -> Bool
nextIsFantasy
(PlayerInput -> Bool
withFantasy (PlayerInput -> Bool) -> PlayerInput -> Bool
forall a b. (a -> b) -> a -> b
$ [PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index)
(PlayerInput -> [Combination]
board (PlayerInput -> [Combination]) -> PlayerInput -> [Combination]
forall a b. (a -> b) -> a -> b
$ [PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index),
top :: LineResult
top = LineResult :: LineType -> Maybe Combination -> Int -> Int -> Int -> LineResult
LineResult {
combination :: Maybe Combination
combination = PlayerInput -> Int -> Maybe Combination
combinationByIndex ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index) Int
0,
lineType :: LineType
lineType = LineType
Top,
points :: Int
points = LineType -> Maybe Combination -> Int
pointsCalc LineType
Top (PlayerInput -> Int -> Maybe Combination
combinationByIndex ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index) Int
0),
totalCombination :: Int
totalCombination = (Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int, Int)
getLinePoints Int
index Int
0,
totalBonus :: Int
totalBonus = (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int, Int)
getLinePoints Int
index Int
0
},
middle :: LineResult
middle = LineResult :: LineType -> Maybe Combination -> Int -> Int -> Int -> LineResult
LineResult {
combination :: Maybe Combination
combination = PlayerInput -> Int -> Maybe Combination
combinationByIndex ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index) Int
1,
lineType :: LineType
lineType = LineType
Middle,
points :: Int
points = LineType -> Maybe Combination -> Int
pointsCalc LineType
Middle (PlayerInput -> Int -> Maybe Combination
combinationByIndex ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index) Int
1),
totalCombination :: Int
totalCombination = (Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int, Int)
getLinePoints Int
index Int
1,
totalBonus :: Int
totalBonus = (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int, Int)
getLinePoints Int
index Int
1
},
bottom :: LineResult
bottom = LineResult :: LineType -> Maybe Combination -> Int -> Int -> Int -> LineResult
LineResult {
combination :: Maybe Combination
combination = PlayerInput -> Int -> Maybe Combination
combinationByIndex ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index) Int
2,
lineType :: LineType
lineType = LineType
Bottom,
points :: Int
points = LineType -> Maybe Combination -> Int
pointsCalc LineType
Bottom (PlayerInput -> Int -> Maybe Combination
combinationByIndex ([PlayerInput]
playerInputs [PlayerInput] -> Int -> PlayerInput
forall a. [a] -> Int -> a
!! Int
index) Int
2),
totalCombination :: Int
totalCombination = (Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int, Int)
getLinePoints Int
index Int
2,
totalBonus :: Int
totalBonus = (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int, Int)
getLinePoints Int
index Int
2
},
totalDetailed :: (String, [LineCompareResult])
totalDetailed = [(String, [LineCompareResult])]
linesResults [(String, [LineCompareResult])]
-> Int -> (String, [LineCompareResult])
forall a. [a] -> Int -> a
!! Int
index,
total :: Int
total = (String, [LineCompareResult]) -> Int
totalPoints ([(String, [LineCompareResult])]
linesResults [(String, [LineCompareResult])]
-> Int -> (String, [LineCompareResult])
forall a. [a] -> Int -> a
!! Int
index)
}
combinationByIndex :: PlayerInput -> Int -> Maybe Combination
combinationByIndex :: PlayerInput -> Int -> Maybe Combination
combinationByIndex PlayerInput
playerInput Int
index
| PlayerInput -> Bool
scoop PlayerInput
playerInput = Maybe Combination
forall a. Maybe a
Nothing
| Bool
otherwise = Combination -> Maybe Combination
forall a. a -> Maybe a
Just (Combination -> Maybe Combination)
-> Combination -> Maybe Combination
forall a b. (a -> b) -> a -> b
$ PlayerInput -> [Combination]
board PlayerInput
playerInput [Combination] -> Int -> Combination
forall a. [a] -> Int -> a
!! Int
index
getTotal :: LineCompareResult -> Int
getTotal :: LineCompareResult -> Int
getTotal ([String]
_, Int
combo, Int
bonus, [(Int, Int)]
_) = Int
combo Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
bonus
totalPoints :: (String, [LineCompareResult]) -> Int
totalPoints :: (String, [LineCompareResult]) -> Int
totalPoints (String
_, [LineCompareResult]
compareResults) = (Int -> LineCompareResult -> Int)
-> Int -> [LineCompareResult] -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Int
acc LineCompareResult
r -> Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ LineCompareResult -> Int
getTotal LineCompareResult
r) Int
0 [LineCompareResult]
compareResults
nextIsFantasy :: Bool -> [Combination] -> Bool
nextIsFantasy :: Bool -> [Combination] -> Bool
nextIsFantasy Bool
withFantasy [] = Bool
False
nextIsFantasy Bool
withFantasy (Combination
top:Combination
middle:Combination
bottom:[Combination]
_)
| Bool
withFantasy =
Combination
top Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
>= CombinationName -> Card -> Combination
RankCombination CombinationName
Set (Value -> Suit -> Card
Card Value
Two Suit
Hearts)
Bool -> Bool -> Bool
|| Combination
middle Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
>= CombinationName -> Card -> Card -> Combination
PartCombination CombinationName
FullHouse (Value -> Suit -> Card
Card Value
Two Suit
Hearts) (Value -> Suit -> Card
Card Value
Three Suit
Hearts)
Bool -> Bool -> Bool
|| Combination
bottom Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
>= CombinationName -> Card -> Combination
RankCombination CombinationName
FourOfAKind (Value -> Suit -> Card
Card Value
Two Suit
Hearts)
| Bool
otherwise =
Combination
top Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
>= CombinationName -> Card -> Combination
RankCombination CombinationName
Pair (Value -> Suit -> Card
Card Value
Queen Suit
Hearts)
Bool -> Bool -> Bool
|| Combination
middle Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
>= CombinationName -> Card -> Card -> Combination
PartCombination CombinationName
FullHouse (Value -> Suit -> Card
Card Value
Two Suit
Hearts) (Value -> Suit -> Card
Card Value
Three Suit
Hearts)
Bool -> Bool -> Bool
|| Combination
bottom Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
>= CombinationName -> Card -> Combination
RankCombination CombinationName
StraightFlush (Value -> Suit -> Card
Card Value
Five Suit
Hearts)
nextIsFantasy Bool
_ [Combination]
_ = Bool
False
getLinePoints :: Int -> Int -> IntPair
getLinePoints :: Int -> Int -> (Int, Int)
getLinePoints Int
playerIndex Int
lineIndex
= ((Int, Int) -> LineCompareResult -> (Int, Int))
-> (Int, Int) -> [LineCompareResult] -> (Int, Int)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
(\(Int
comboAcc, Int
bonusAcc) ([String]
_, Int
_, Int
_, [(Int, Int)]
debug) -> (Int
comboAcc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int, Int) -> Int
forall a b. (a, b) -> a
fst ([(Int, Int)]
debug [(Int, Int)] -> Int -> (Int, Int)
forall a. [a] -> Int -> a
!! Int
lineIndex), Int
bonusAcc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int, Int) -> Int
forall a b. (a, b) -> b
snd ([(Int, Int)]
debug [(Int, Int)] -> Int -> (Int, Int)
forall a. [a] -> Int -> a
!! Int
lineIndex)))
(Int
0, Int
0)
((String, [LineCompareResult]) -> [LineCompareResult]
forall a b. (a, b) -> b
snd ([(String, [LineCompareResult])]
linesResults [(String, [LineCompareResult])]
-> Int -> (String, [LineCompareResult])
forall a. [a] -> Int -> a
!! Int
playerIndex))
collectLinesResults :: [LineCompareResult] -> [PlayerInput] -> [PlayerInput] -> [(String, [LineCompareResult])]
collectLinesResults :: [LineCompareResult]
-> [PlayerInput]
-> [PlayerInput]
-> [(String, [LineCompareResult])]
collectLinesResults [LineCompareResult]
acc [PlayerInput]
full (PlayerInput
currPlayer:[PlayerInput]
players) =
(PlayerInput -> String
username PlayerInput
currPlayer, (PlayerInput -> LineCompareResult)
-> [PlayerInput] -> [LineCompareResult]
forall a b. (a -> b) -> [a] -> [b]
map (PlayerInput -> PlayerInput -> LineCompareResult
getResult PlayerInput
currPlayer) [PlayerInput]
otherInputs) (String, [LineCompareResult])
-> [(String, [LineCompareResult])]
-> [(String, [LineCompareResult])]
forall a. a -> [a] -> [a]
: [LineCompareResult]
-> [PlayerInput]
-> [PlayerInput]
-> [(String, [LineCompareResult])]
collectLinesResults ([LineCompareResult]
acc [LineCompareResult] -> [LineCompareResult] -> [LineCompareResult]
forall a. [a] -> [a] -> [a]
++ (PlayerInput -> LineCompareResult)
-> [PlayerInput] -> [LineCompareResult]
forall a b. (a -> b) -> [a] -> [b]
map (PlayerInput -> PlayerInput -> LineCompareResult
getResult PlayerInput
currPlayer) [PlayerInput]
otherInputs) [PlayerInput]
full [PlayerInput]
players
where
otherInputs :: [PlayerInput]
otherInputs :: [PlayerInput]
otherInputs = (PlayerInput -> Bool) -> [PlayerInput] -> [PlayerInput]
forall a. (a -> Bool) -> [a] -> [a]
filter (\PlayerInput
player -> PlayerInput -> String
username PlayerInput
player String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= PlayerInput -> String
username PlayerInput
currPlayer) [PlayerInput]
full
negateTuple :: IntPair -> IntPair
negateTuple :: (Int, Int) -> (Int, Int)
negateTuple (Int
a, Int
b) = (Int -> Int
forall a. Num a => a -> a
negate Int
a, Int -> Int
forall a. Num a => a -> a
negate Int
b)
getResult :: PlayerInput -> PlayerInput -> ([String], Int, Int, [IntPair])
getResult :: PlayerInput -> PlayerInput -> LineCompareResult
getResult PlayerInput
player1 PlayerInput
player2 = case (LineCompareResult -> Bool)
-> [LineCompareResult] -> Maybe LineCompareResult
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\([String]
usernames, Int
_, Int
_, [(Int, Int)]
_) -> [String]
usernames [String] -> [String] -> Bool
forall a. Eq a => a -> a -> Bool
== [PlayerInput -> String
username PlayerInput
player2, PlayerInput -> String
username PlayerInput
player1] ) [LineCompareResult]
acc of
Just ([String]
usernames, Int
combo, Int
bonus, [(Int, Int)]
debug) -> ([String] -> [String]
forall a. [a] -> [a]
reverse [String]
usernames, Int -> Int
forall a. Num a => a -> a
negate Int
combo, Int -> Int
forall a. Num a => a -> a
negate Int
bonus, ((Int, Int) -> (Int, Int)) -> [(Int, Int)] -> [(Int, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Int) -> (Int, Int)
negateTuple [(Int, Int)]
debug)
Maybe LineCompareResult
_ -> PlayerInput -> PlayerInput -> LineCompareResult
comparePlayers PlayerInput
player1 PlayerInput
player2
collectLinesResults [LineCompareResult]
acc [PlayerInput]
_ [] = []
comparePlayers :: PlayerInput -> PlayerInput -> LineCompareResult
comparePlayers :: PlayerInput -> PlayerInput -> LineCompareResult
comparePlayers
p1 :: PlayerInput
p1@PlayerInput{ username :: PlayerInput -> String
username = String
p1name, board :: PlayerInput -> [Combination]
board = [Combination]
boardP1, scoop :: PlayerInput -> Bool
scoop = Bool
p1scoop }
p2 :: PlayerInput
p2@PlayerInput{ username :: PlayerInput -> String
username = String
p2name, board :: PlayerInput -> [Combination]
board = [Combination]
boardP2, scoop :: PlayerInput -> Bool
scoop = Bool
p2scoop } = (
[String
p1name, String
p2name],
[(Int, Int)] -> Int
foldPoints [(Int, Int)
topPoints, (Int, Int)
middlePoints, (Int, Int)
bottomPoints],
Int
bonusCalculated,
[
((Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (-) (Int, Int)
topPoints, Int
topBonus),
((Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (-) (Int, Int)
middlePoints, Int
middleBonus),
((Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (-) (Int, Int)
bottomPoints, Int
bottomBonus)
]
) where
topPoints :: IntPair
topPoints :: (Int, Int)
topPoints = (
if Bool
p1scoop then Int
0 else LineType -> Combination -> Int
getPoints LineType
Top ([Combination] -> Combination
forall a. [a] -> a
head [Combination]
boardP1),
if Bool
p2scoop then Int
0 else LineType -> Combination -> Int
getPoints LineType
Top ([Combination] -> Combination
forall a. [a] -> a
head [Combination]
boardP2)
)
middlePoints :: IntPair
middlePoints :: (Int, Int)
middlePoints = (
if Bool
p1scoop then Int
0 else LineType -> Combination -> Int
getPoints LineType
Middle ([Combination] -> Combination
forall a. [a] -> a
head ([Combination] -> Combination) -> [Combination] -> Combination
forall a b. (a -> b) -> a -> b
$ [Combination] -> [Combination]
forall a. [a] -> [a]
tail [Combination]
boardP1),
if Bool
p2scoop then Int
0 else LineType -> Combination -> Int
getPoints LineType
Middle ([Combination] -> Combination
forall a. [a] -> a
head ([Combination] -> Combination) -> [Combination] -> Combination
forall a b. (a -> b) -> a -> b
$ [Combination] -> [Combination]
forall a. [a] -> [a]
tail [Combination]
boardP2)
)
bottomPoints :: IntPair
bottomPoints :: (Int, Int)
bottomPoints = (
if Bool
p1scoop then Int
0 else LineType -> Combination -> Int
getPoints LineType
Bottom ([Combination] -> Combination
forall a. [a] -> a
last [Combination]
boardP1),
if Bool
p2scoop then Int
0 else LineType -> Combination -> Int
getPoints LineType
Bottom ([Combination] -> Combination
forall a. [a] -> a
last [Combination]
boardP2)
)
mirrorPoints :: Int -> IntPair
mirrorPoints :: Int -> (Int, Int)
mirrorPoints Int
p = (Int
p, Int -> Int
forall a. Num a => a -> a
negate Int
p)
anyScoop :: Bool
anyScoop :: Bool
anyScoop = Bool
p1scoop Bool -> Bool -> Bool
|| Bool
p2scoop
getDefaultBonus :: Combination -> Combination -> Int
getDefaultBonus :: Combination -> Combination -> Int
getDefaultBonus Combination
c1 Combination
c2
| Combination
c1 Combination -> Combination -> Bool
forall a. Ord a => a -> a -> Bool
> Combination
c2 = Int
1
| Combination
c1 Combination -> Combination -> Bool
forall a. Eq a => a -> a -> Bool
== Combination
c2 = Int
0
| Bool
otherwise = -Int
1
getScoopBonus :: Int
getScoopBonus :: Int
getScoopBonus = case (Bool
p1scoop, Bool
p2scoop) of
(Bool
True, Bool
True) -> Int
0
(Bool
True, Bool
False) -> -Int
1
(Bool
False, Bool
True) -> Int
1
(Bool
False, Bool
False) -> String -> Int
forall a. HasCallStack => String -> a
error String
"getDefaultBonus shouldb be used for this case"
topBonus :: Int
topBonus :: Int
topBonus
| Bool
anyScoop = Int
getScoopBonus
| Bool
otherwise = Combination -> Combination -> Int
getDefaultBonus ([Combination] -> Combination
forall a. [a] -> a
head [Combination]
boardP1) ([Combination] -> Combination
forall a. [a] -> a
head [Combination]
boardP2)
middleBonus :: Int
middleBonus :: Int
middleBonus
| Bool
anyScoop = Int
getScoopBonus
| Bool
otherwise = Combination -> Combination -> Int
getDefaultBonus ([Combination] -> Combination
forall a. [a] -> a
head ([Combination] -> Combination) -> [Combination] -> Combination
forall a b. (a -> b) -> a -> b
$ [Combination] -> [Combination]
forall a. [a] -> [a]
tail [Combination]
boardP1) ([Combination] -> Combination
forall a. [a] -> a
head ([Combination] -> Combination) -> [Combination] -> Combination
forall a b. (a -> b) -> a -> b
$ [Combination] -> [Combination]
forall a. [a] -> [a]
tail [Combination]
boardP2)
bottomBonus :: Int
bottomBonus :: Int
bottomBonus
| Bool
anyScoop = Int
getScoopBonus
| Bool
otherwise = Combination -> Combination -> Int
getDefaultBonus ([Combination] -> Combination
forall a. [a] -> a
last [Combination]
boardP1) ([Combination] -> Combination
forall a. [a] -> a
last [Combination]
boardP2)
summBonus :: Int
summBonus :: Int
summBonus = Int
topBonus Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
middleBonus Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
bottomBonus
bonusCalculated :: Int
bonusCalculated :: Int
bonusCalculated = case Int
topBonus Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
middleBonus Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
bottomBonus of
Int
3 -> Int
6
(-3) -> -Int
6
Int
b -> Int
b
foldPoints :: [IntPair] -> Int
foldPoints :: [(Int, Int)] -> Int
foldPoints [] = Int
0
foldPoints ((Int
r1, Int
r2):[(Int, Int)]
xs) = (Int
r1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r2) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [(Int, Int)] -> Int
foldPoints [(Int, Int)]
xs
middlePoints :: [Int]
middlePoints :: [Int]
middlePoints = [Int
0, Int
0, Int
0, Int
2, Int
4, Int
8, Int
12, Int
20, Int
30, Int
50]
bottomPoints :: [Int]
bottomPoints :: [Int]
bottomPoints = (Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
p -> if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
2 then Int
p Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2 else Int
0) [Int]
middlePoints
pointsCalc :: LineType -> Maybe Combination -> Int
pointsCalc :: LineType -> Maybe Combination -> Int
pointsCalc LineType
lineType Maybe Combination
combo = case Maybe Combination
combo of
Just Combination
c -> LineType -> Combination -> Int
getPoints LineType
lineType Combination
c
Maybe Combination
Nothing -> Int
0
getPoints :: LineType -> Combination -> Int
getPoints :: LineType -> Combination -> Int
getPoints LineType
Top (RankCombination CombinationName
Pair (Card Value
rank Suit
_)) =
if Value -> Int
forall a. Enum a => a -> Int
fromEnum Value
rank Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
4 then Int
0 else Value -> Int
forall a. Enum a => a -> Int
fromEnum Value
rank Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3
getPoints LineType
Top (RankCombination CombinationName
Set (Card Value
rank Suit
_)) = Value -> Int
forall a. Enum a => a -> Int
fromEnum Value
rank Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10
getPoints LineType
Top Combination
_ = Int
0
getPoints LineType
Middle Combination
c = [Int]
middlePoints [Int] -> Int -> Int
forall a. [a] -> Int -> a
!! CombinationName -> Int
forall a. Enum a => a -> Int
fromEnum (Combination -> CombinationName
name Combination
c)
getPoints LineType
Bottom Combination
c = [Int]
bottomPoints [Int] -> Int -> Int
forall a. [a] -> Int -> a
!! CombinationName -> Int
forall a. Enum a => a -> Int
fromEnum (Combination -> CombinationName
name Combination
c)