module BishBosh.Search.TranspositionValue (
IsOptimal,
FindFitness,
Value(
getIsOptimal,
getNPlies,
getMoves
),
inferSearchDepth,
mkValue,
isBetter
) where
import qualified BishBosh.Component.Move as Component.Move
import qualified BishBosh.Data.Exception as Data.Exception
import qualified Control.Exception
import qualified Data.Ord
type IsOptimal = Bool
data Value move = MkValue {
Value move -> IsOptimal
getIsOptimal :: IsOptimal,
Value move -> NPlies
getNPlies :: Component.Move.NPlies,
Value move -> [move]
getMoves :: [move]
}
mkValue
:: IsOptimal
-> Component.Move.NPlies
-> [move]
-> Value move
mkValue :: IsOptimal -> NPlies -> [move] -> Value move
mkValue IsOptimal
_ NPlies
_ [] = Exception -> Value move
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> Value move) -> Exception -> Value move
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkNullDatum String
"BishBosh.Search.TranspositionValue.mkValue:\tnull list of moves."
mkValue IsOptimal
isOptimal NPlies
nPlies [move]
moves
| NPlies
nPlies NPlies -> NPlies -> IsOptimal
forall a. Ord a => a -> a -> IsOptimal
< NPlies
0 = Exception -> Value move
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> Value move) -> Exception -> Value move
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkOutOfBounds String
"BishBosh.Search.TranspositionValue.mkValue:\tnPlies can't be negative."
| IsOptimal
otherwise = MkValue :: forall move. IsOptimal -> NPlies -> [move] -> Value move
MkValue {
getIsOptimal :: IsOptimal
getIsOptimal = IsOptimal
isOptimal,
getNPlies :: NPlies
getNPlies = NPlies
nPlies,
getMoves :: [move]
getMoves = [move]
moves
}
inferSearchDepth :: Value move -> Component.Move.NPlies
inferSearchDepth :: Value move -> NPlies
inferSearchDepth = [move] -> NPlies
forall (t :: * -> *) a. Foldable t => t a -> NPlies
length ([move] -> NPlies)
-> (Value move -> [move]) -> Value move -> NPlies
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value move -> [move]
forall move. Value move -> [move]
getMoves
type FindFitness move weightedMean = Value move -> weightedMean
isBetter
:: Ord weightedMean
=> FindFitness move weightedMean
-> Value move
-> Value move
-> Bool
isBetter :: FindFitness move weightedMean
-> Value move -> Value move -> IsOptimal
isBetter FindFitness move weightedMean
findFitness Value move
proposedValue Value move
incumbentValue = case (Value move -> NPlies) -> Value move -> Value move -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
Data.Ord.comparing Value move -> NPlies
forall move. Value move -> NPlies
inferSearchDepth Value move
proposedValue Value move
incumbentValue of
Ordering
GT -> IsOptimal
True
Ordering
EQ -> Value move -> IsOptimal
forall move. Value move -> IsOptimal
getIsOptimal Value move
proposedValue IsOptimal -> IsOptimal -> IsOptimal
|| FindFitness move weightedMean
-> Value move -> Value move -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
Data.Ord.comparing FindFitness move weightedMean
findFitness Value move
proposedValue Value move
incumbentValue Ordering -> Ordering -> IsOptimal
forall a. Eq a => a -> a -> IsOptimal
== Ordering
GT
Ordering
_ -> IsOptimal
False