module BishBosh.ContextualNotation.QualifiedMoveForest(
Name,
OnymousResult,
QualifiedMoveForest(
deconstruct
),
showsNames,
findMinimumPieces,
count,
fromPGNDatabase,
toGameTree,
mergePGNDatabase,
) where
import Control.Applicative((<|>))
import Control.Arrow((&&&), (***))
import qualified BishBosh.Attribute.MoveType as Attribute.MoveType
import qualified BishBosh.Component.Piece as Component.Piece
import qualified BishBosh.Component.QualifiedMove as Component.QualifiedMove
import qualified BishBosh.Component.Turn as Component.Turn
import qualified BishBosh.ContextualNotation.PGN as ContextualNotation.PGN
import qualified BishBosh.ContextualNotation.PGNDatabase as ContextualNotation.PGNDatabase
import qualified BishBosh.Data.RoseTree as Data.RoseTree
import qualified BishBosh.Model.Game as Model.Game
import qualified BishBosh.Model.GameTree as Model.GameTree
import qualified BishBosh.Notation.MoveNotation as Notation.MoveNotation
import qualified BishBosh.Property.Empty as Property.Empty
import qualified BishBosh.Property.Null as Property.Null
import qualified BishBosh.Rule.GameTerminationReason as Rule.GameTerminationReason
import qualified BishBosh.Rule.Result as Rule.Result
import qualified BishBosh.Text.ShowList as Text.ShowList
import qualified BishBosh.Type.Count as Type.Count
import qualified Control.Arrow
import qualified Data.Default
import qualified Data.List
import qualified Data.Maybe
import qualified Data.Tree
type Name = String
type OnymousResult = (Name, Rule.Result.Result)
type QualifiedMoveTree = Data.Tree.Tree (Component.QualifiedMove.QualifiedMove, Maybe OnymousResult)
newtype QualifiedMoveForest = MkQualifiedMoveForest {
QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct :: [QualifiedMoveTree]
} deriving (
QualifiedMoveForest -> QualifiedMoveForest -> Bool
(QualifiedMoveForest -> QualifiedMoveForest -> Bool)
-> (QualifiedMoveForest -> QualifiedMoveForest -> Bool)
-> Eq QualifiedMoveForest
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QualifiedMoveForest -> QualifiedMoveForest -> Bool
$c/= :: QualifiedMoveForest -> QualifiedMoveForest -> Bool
== :: QualifiedMoveForest -> QualifiedMoveForest -> Bool
$c== :: QualifiedMoveForest -> QualifiedMoveForest -> Bool
Eq,
Int -> QualifiedMoveForest -> ShowS
[QualifiedMoveForest] -> ShowS
QualifiedMoveForest -> String
(Int -> QualifiedMoveForest -> ShowS)
-> (QualifiedMoveForest -> String)
-> ([QualifiedMoveForest] -> ShowS)
-> Show QualifiedMoveForest
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QualifiedMoveForest] -> ShowS
$cshowList :: [QualifiedMoveForest] -> ShowS
show :: QualifiedMoveForest -> String
$cshow :: QualifiedMoveForest -> String
showsPrec :: Int -> QualifiedMoveForest -> ShowS
$cshowsPrec :: Int -> QualifiedMoveForest -> ShowS
Show
)
instance Property.Empty.Empty QualifiedMoveForest where
empty :: QualifiedMoveForest
empty = [QualifiedMoveTree] -> QualifiedMoveForest
MkQualifiedMoveForest [QualifiedMoveTree]
forall a. Empty a => a
Property.Empty.empty
instance Property.Null.Null QualifiedMoveForest where
isNull :: QualifiedMoveForest -> Bool
isNull MkQualifiedMoveForest { deconstruct :: QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct = [] } = Bool
True
isNull QualifiedMoveForest
_ = Bool
False
instance Notation.MoveNotation.ShowNotation QualifiedMoveForest where
showsNotation :: MoveNotation -> QualifiedMoveForest -> ShowS
showsNotation MoveNotation
moveNotation MkQualifiedMoveForest { deconstruct :: QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct = [QualifiedMoveTree]
forest } = String -> ShowS
showString (String -> ShowS) -> String -> ShowS
forall a b. (a -> b) -> a -> b
$ ((QualifiedMove, Maybe OnymousResult) -> String)
-> [QualifiedMoveTree] -> String
forall a. (a -> String) -> Forest a -> String
Data.RoseTree.drawForest (
\(QualifiedMove
qualifiedMove, Maybe OnymousResult
maybeOnymousResult) -> MoveNotation -> QualifiedMove -> ShowS
forall a. ShowNotation a => MoveNotation -> a -> ShowS
Notation.MoveNotation.showsNotation MoveNotation
moveNotation QualifiedMove
qualifiedMove ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS -> (OnymousResult -> ShowS) -> Maybe OnymousResult -> ShowS
forall b a. b -> (a -> b) -> Maybe a -> b
Data.Maybe.maybe ShowS
forall a. a -> a
id (
\OnymousResult
onymousResult -> Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnymousResult -> ShowS
forall a. Show a => a -> ShowS
shows OnymousResult
onymousResult
) Maybe OnymousResult
maybeOnymousResult String
""
) [QualifiedMoveTree]
forest
showsNames
:: Maybe Type.Count.NGames
-> [Name]
-> ShowS
showsNames :: Maybe Int -> [String] -> ShowS
showsNames Maybe Int
maybeMaximumPGNNames [String]
names = [ShowS] -> ShowS
Text.ShowList.showsUnterminatedList ([ShowS] -> ShowS) -> ([String] -> [ShowS]) -> [String] -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ShowS) -> [String] -> [ShowS]
forall a b. (a -> b) -> [a] -> [b]
map (
\String
name -> String -> ShowS
showString String
"\n\t" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
name
) ([String] -> ShowS) -> [String] -> ShowS
forall a b. (a -> b) -> a -> b
$ ([String] -> [String])
-> (Int -> [String] -> [String])
-> Maybe Int
-> [String]
-> [String]
forall b a. b -> (a -> b) -> Maybe a -> b
Data.Maybe.maybe [String] -> [String]
forall a. a -> a
id (
\Int
maximumPGNNames -> (
if Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
maximumPGNNames Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
names'
then ([String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"..."])
else [String] -> [String]
forall a. a -> a
id
) ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
take (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
maximumPGNNames)
) Maybe Int
maybeMaximumPGNNames [String]
names' where
names' :: [String]
names' = [String] -> [String]
forall a. Eq a => [a] -> [a]
Data.List.nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. Ord a => [a] -> [a]
Data.List.sort [String]
names
mergePGNDatabase
:: ContextualNotation.PGNDatabase.PGNDatabase
-> QualifiedMoveForest
-> QualifiedMoveForest
mergePGNDatabase :: PGNDatabase -> QualifiedMoveForest -> QualifiedMoveForest
mergePGNDatabase PGNDatabase
pgnDatabase MkQualifiedMoveForest { deconstruct :: QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct = [QualifiedMoveTree]
initialForest } = [QualifiedMoveTree] -> QualifiedMoveForest
MkQualifiedMoveForest ([QualifiedMoveTree] -> QualifiedMoveForest)
-> [QualifiedMoveTree] -> QualifiedMoveForest
forall a b. (a -> b) -> a -> b
$ (PGN -> [QualifiedMoveTree] -> [QualifiedMoveTree])
-> [QualifiedMoveTree] -> PGNDatabase -> [QualifiedMoveTree]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (
\PGN
pgn -> OnymousResult
-> [QualifiedMove] -> [QualifiedMoveTree] -> [QualifiedMoveTree]
merge (
PGN -> String
mkCompositeIdentifier (PGN -> String) -> (PGN -> Result) -> PGN -> OnymousResult
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Result
-> (GameTerminationReason -> Result)
-> Maybe GameTerminationReason
-> Result
forall b a. b -> (a -> b) -> Maybe a -> b
Data.Maybe.maybe (
Maybe LogicalColour -> Result
Rule.Result.mkResult Maybe LogicalColour
forall a. Maybe a
Nothing
) GameTerminationReason -> Result
Rule.GameTerminationReason.toResult (Maybe GameTerminationReason -> Result)
-> (PGN -> Maybe GameTerminationReason) -> PGN -> Result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Game -> Maybe GameTerminationReason
Model.Game.getMaybeTerminationReason (Game -> Maybe GameTerminationReason)
-> (PGN -> Game) -> PGN -> Maybe GameTerminationReason
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PGN -> Game
ContextualNotation.PGN.getGame (PGN -> OnymousResult) -> PGN -> OnymousResult
forall a b. (a -> b) -> a -> b
$ PGN
pgn
) (
(Turn -> QualifiedMove) -> [Turn] -> [QualifiedMove]
forall a b. (a -> b) -> [a] -> [b]
map Turn -> QualifiedMove
Component.Turn.getQualifiedMove ([Turn] -> [QualifiedMove])
-> (Game -> [Turn]) -> Game -> [QualifiedMove]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Game -> [Turn]
Model.Game.listTurnsChronologically (Game -> [QualifiedMove]) -> Game -> [QualifiedMove]
forall a b. (a -> b) -> a -> b
$ PGN -> Game
ContextualNotation.PGN.getGame PGN
pgn
)
) [QualifiedMoveTree]
initialForest PGNDatabase
pgnDatabase where
mkCompositeIdentifier :: ContextualNotation.PGN.PGN -> Name
mkCompositeIdentifier :: PGN -> String
mkCompositeIdentifier = [String] -> String
unwords ([String] -> String) -> (PGN -> [String]) -> PGN -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> b
snd ([(String, String)] -> [String])
-> (PGN -> [(String, String)]) -> PGN -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PGN -> [(String, String)]
ContextualNotation.PGN.getIdentificationTagPairs
merge
:: OnymousResult
-> [Component.QualifiedMove.QualifiedMove]
-> [QualifiedMoveTree]
-> [QualifiedMoveTree]
merge :: OnymousResult
-> [QualifiedMove] -> [QualifiedMoveTree] -> [QualifiedMoveTree]
merge OnymousResult
onymousResult qualifiedMoves :: [QualifiedMove]
qualifiedMoves@(QualifiedMove
qualifiedMove : [QualifiedMove]
remainingQualifiedMoves) [QualifiedMoveTree]
forest = case (QualifiedMoveTree -> Bool)
-> [QualifiedMoveTree]
-> ([QualifiedMoveTree], [QualifiedMoveTree])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (
\Data.Tree.Node { rootLabel :: forall a. Tree a -> a
Data.Tree.rootLabel = (QualifiedMove
qualifiedMove', Maybe OnymousResult
_) } -> QualifiedMove -> Move
Component.QualifiedMove.getMove QualifiedMove
qualifiedMove Move -> Move -> Bool
forall a. Eq a => a -> a -> Bool
/= QualifiedMove -> Move
Component.QualifiedMove.getMove QualifiedMove
qualifiedMove'
) [QualifiedMoveTree]
forest of
([QualifiedMoveTree]
unmatchedForest, QualifiedMoveTree
matchingTree : [QualifiedMoveTree]
remainingForest) -> [QualifiedMoveTree]
unmatchedForest [QualifiedMoveTree] -> [QualifiedMoveTree] -> [QualifiedMoveTree]
forall a. [a] -> [a] -> [a]
++ (
if [QualifiedMove] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [QualifiedMove]
remainingQualifiedMoves
then QualifiedMoveTree
matchingTree {
rootLabel :: (QualifiedMove, Maybe OnymousResult)
Data.Tree.rootLabel = (Maybe OnymousResult -> Maybe OnymousResult)
-> (QualifiedMove, Maybe OnymousResult)
-> (QualifiedMove, Maybe OnymousResult)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Control.Arrow.second (
Maybe OnymousResult -> Maybe OnymousResult -> Maybe OnymousResult
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> OnymousResult -> Maybe OnymousResult
forall a. a -> Maybe a
Just OnymousResult
onymousResult
) ((QualifiedMove, Maybe OnymousResult)
-> (QualifiedMove, Maybe OnymousResult))
-> (QualifiedMove, Maybe OnymousResult)
-> (QualifiedMove, Maybe OnymousResult)
forall a b. (a -> b) -> a -> b
$ QualifiedMoveTree -> (QualifiedMove, Maybe OnymousResult)
forall a. Tree a -> a
Data.Tree.rootLabel QualifiedMoveTree
matchingTree
}
else QualifiedMoveTree
matchingTree {
subForest :: [QualifiedMoveTree]
Data.Tree.subForest = OnymousResult
-> [QualifiedMove] -> [QualifiedMoveTree] -> [QualifiedMoveTree]
merge OnymousResult
onymousResult [QualifiedMove]
remainingQualifiedMoves ([QualifiedMoveTree] -> [QualifiedMoveTree])
-> [QualifiedMoveTree] -> [QualifiedMoveTree]
forall a b. (a -> b) -> a -> b
$ QualifiedMoveTree -> [QualifiedMoveTree]
forall a. Tree a -> Forest a
Data.Tree.subForest QualifiedMoveTree
matchingTree
}
) QualifiedMoveTree -> [QualifiedMoveTree] -> [QualifiedMoveTree]
forall a. a -> [a] -> [a]
: [QualifiedMoveTree]
remainingForest
([QualifiedMoveTree], [QualifiedMoveTree])
_ -> OnymousResult -> [QualifiedMove] -> QualifiedMoveTree
mkLinkedList OnymousResult
onymousResult [QualifiedMove]
qualifiedMoves QualifiedMoveTree -> [QualifiedMoveTree] -> [QualifiedMoveTree]
forall a. a -> [a] -> [a]
: [QualifiedMoveTree]
forest
merge OnymousResult
_ [] [QualifiedMoveTree]
forest = [QualifiedMoveTree]
forest
mkLinkedList :: OnymousResult -> [Component.QualifiedMove.QualifiedMove] -> QualifiedMoveTree
mkLinkedList :: OnymousResult -> [QualifiedMove] -> QualifiedMoveTree
mkLinkedList OnymousResult
onymousResult ~(QualifiedMove
qualifiedMove : [QualifiedMove]
remainingQualifiedMoves)
| [QualifiedMove] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [QualifiedMove]
remainingQualifiedMoves = Node :: forall a. a -> Forest a -> Tree a
Data.Tree.Node {
rootLabel :: (QualifiedMove, Maybe OnymousResult)
Data.Tree.rootLabel = (QualifiedMove
qualifiedMove, OnymousResult -> Maybe OnymousResult
forall a. a -> Maybe a
Just OnymousResult
onymousResult),
subForest :: [QualifiedMoveTree]
Data.Tree.subForest = []
}
| Bool
otherwise = Node :: forall a. a -> Forest a -> Tree a
Data.Tree.Node {
rootLabel :: (QualifiedMove, Maybe OnymousResult)
Data.Tree.rootLabel = (QualifiedMove
qualifiedMove, Maybe OnymousResult
forall a. Maybe a
Nothing),
subForest :: [QualifiedMoveTree]
Data.Tree.subForest = [OnymousResult -> [QualifiedMove] -> QualifiedMoveTree
mkLinkedList OnymousResult
onymousResult [QualifiedMove]
remainingQualifiedMoves ]
}
fromPGNDatabase :: ContextualNotation.PGNDatabase.PGNDatabase -> QualifiedMoveForest
fromPGNDatabase :: PGNDatabase -> QualifiedMoveForest
fromPGNDatabase = (PGNDatabase -> QualifiedMoveForest -> QualifiedMoveForest
`mergePGNDatabase` QualifiedMoveForest
forall a. Empty a => a
Property.Empty.empty )
findMinimumPieces :: QualifiedMoveForest -> Type.Count.NPieces
findMinimumPieces :: QualifiedMoveForest -> Int
findMinimumPieces = Int -> [QualifiedMoveTree] -> Int
forall t b. (Ord t, Enum t) => t -> Forest (QualifiedMove, b) -> t
slave (
Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
Component.Piece.nPiecesPerSide
) ([QualifiedMoveTree] -> Int)
-> (QualifiedMoveForest -> [QualifiedMoveTree])
-> QualifiedMoveForest
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct where
slave :: t -> Forest (QualifiedMove, b) -> t
slave t
nPieces [] = t
nPieces
slave t
nPieces Forest (QualifiedMove, b)
forest = [t] -> t
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum ([t] -> t) -> [t] -> t
forall a b. (a -> b) -> a -> b
$ (Tree (QualifiedMove, b) -> t) -> Forest (QualifiedMove, b) -> [t]
forall a b. (a -> b) -> [a] -> [b]
map (
\Data.Tree.Node {
rootLabel :: forall a. Tree a -> a
Data.Tree.rootLabel = (QualifiedMove
qualifiedMove, b
_),
subForest :: forall a. Tree a -> Forest a
Data.Tree.subForest = Forest (QualifiedMove, b)
subForest
} -> let
nPieces' :: t
nPieces' = MoveType -> t -> t
forall nPieces. Enum nPieces => MoveType -> nPieces -> nPieces
Attribute.MoveType.nPiecesMutator (QualifiedMove -> MoveType
Component.QualifiedMove.getMoveType QualifiedMove
qualifiedMove) t
nPieces
in t
nPieces' t -> t -> t
`seq` t -> Forest (QualifiedMove, b) -> t
slave t
nPieces' Forest (QualifiedMove, b)
subForest
) Forest (QualifiedMove, b)
forest
count :: QualifiedMoveForest -> (Type.Count.NGames, Type.Count.NPositions)
count :: QualifiedMoveForest -> (Int, Int)
count = [QualifiedMoveTree] -> (Int, Int)
forall a a. [Tree (a, Maybe a)] -> (Int, Int)
slave ([QualifiedMoveTree] -> (Int, Int))
-> (QualifiedMoveForest -> [QualifiedMoveTree])
-> QualifiedMoveForest
-> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct where
slave :: [Tree (a, Maybe a)] -> (Int, Int)
slave = ((Int, Int) -> Tree (a, Maybe a) -> (Int, Int))
-> (Int, Int) -> [Tree (a, Maybe a)] -> (Int, Int)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (
\(Int
nGames, Int
nPositions) Data.Tree.Node {
rootLabel :: forall a. Tree a -> a
Data.Tree.rootLabel = (a
_, Maybe a
maybeOnymousResult),
subForest :: forall a. Tree a -> Forest a
Data.Tree.subForest = [Tree (a, Maybe a)]
forest
} -> let
acc :: (Int, Int)
acc@(Int
nGames', Int
nPositions') = (
(Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
nGames) (Int -> Int) -> (Int -> Int) -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
if Maybe a -> Bool
forall a. Maybe a -> Bool
Data.Maybe.isJust Maybe a
maybeOnymousResult
then Int -> Int
forall a. Enum a => a -> a
succ
else Int -> Int
forall a. a -> a
id
) (Int -> Int) -> (Int -> Int) -> (Int, Int) -> (Int, Int)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
nPositions) (Int -> Int) -> (Int -> Int) -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Enum a => a -> a
succ
) ((Int, Int) -> (Int, Int)) -> (Int, Int) -> (Int, Int)
forall a b. (a -> b) -> a -> b
$ [Tree (a, Maybe a)] -> (Int, Int)
slave [Tree (a, Maybe a)]
forest
in Int
nGames' Int -> (Int, Int) -> (Int, Int)
`seq` Int
nPositions' Int -> (Int, Int) -> (Int, Int)
`seq` (Int, Int)
acc
) (Int
0, Int
0)
toGameTree :: QualifiedMoveForest -> Model.GameTree.GameTree
toGameTree :: QualifiedMoveForest -> GameTree
toGameTree MkQualifiedMoveForest { deconstruct :: QualifiedMoveForest -> [QualifiedMoveTree]
deconstruct = [QualifiedMoveTree]
qualifiedMoveForest } = BareGameTree -> GameTree
Model.GameTree.fromBareGameTree Node :: forall a. a -> Forest a -> Tree a
Data.Tree.Node {
rootLabel :: Game
Data.Tree.rootLabel = Game
initialGame,
subForest :: Forest Game
Data.Tree.subForest = (QualifiedMoveTree -> BareGameTree)
-> [QualifiedMoveTree] -> Forest Game
forall a b. (a -> b) -> [a] -> [b]
map (Game -> QualifiedMoveTree -> BareGameTree
forall b. Game -> Tree (QualifiedMove, b) -> BareGameTree
slave Game
initialGame) [QualifiedMoveTree]
qualifiedMoveForest
} where
initialGame :: Game
initialGame = Game
forall a. Default a => a
Data.Default.def
slave :: Game -> Tree (QualifiedMove, b) -> BareGameTree
slave Game
game Data.Tree.Node {
rootLabel :: forall a. Tree a -> a
Data.Tree.rootLabel = (QualifiedMove
qualifiedMove, b
_),
subForest :: forall a. Tree a -> Forest a
Data.Tree.subForest = Forest (QualifiedMove, b)
qualifiedMoveForest'
} = Node :: forall a. a -> Forest a -> Tree a
Data.Tree.Node {
rootLabel :: Game
Data.Tree.rootLabel = Game
game',
subForest :: Forest Game
Data.Tree.subForest = (Tree (QualifiedMove, b) -> BareGameTree)
-> Forest (QualifiedMove, b) -> Forest Game
forall a b. (a -> b) -> [a] -> [b]
map (Game -> Tree (QualifiedMove, b) -> BareGameTree
slave Game
game') Forest (QualifiedMove, b)
qualifiedMoveForest'
} where
game' :: Game
game' = QualifiedMove -> Transformation
Model.Game.applyQualifiedMove QualifiedMove
qualifiedMove Game
game