-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMTDf.hs
66 lines (55 loc) · 1.87 KB
/
MTDf.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-
- We didn't focused on optimising the MTD(f) algorithm. The code in this file
- is left just for an interested reader.
-}
#ifdef ENGINE
module Main (main) where
import AEI
#else
module MTDf (newSearch) where
#endif
import AlphaBeta
import Bits.BitRepresentation (Board(..), DMove)
import Eval.BitEval (iNFINITY)
import Control.Applicative ((<$>))
import Control.Concurrent (MVar, swapMVar)
import System.IO (hFlush, stdout)
newSearch :: Int -- ^ table size
-> IO (Board -> MVar (DMove, String) -> IO ())
newSearch tableSize = iterative <$> newHTables tableSize
mtdf :: Board -- ^ start position
-> ABTables
-> (DMove, Int) -- ^ best value with PV from last time
-> Int -- ^ depth
-> Int -- ^ lower bound
-> Int -- ^ upper bound
-> IO (DMove, Int) -- ^ IO (steps to go, best value)
mtdf !b tt (_, bestValue) depth !lb !ub = do
best'@(_, bestV') <- alphaBeta b tt (beta - 1, beta) depth (pl,0)
let (lb', ub') | bestV' < beta = (lb, bestV')
| otherwise = (bestV', ub)
if lb' >= ub' then return best'
else mtdf b tt best' depth lb' ub'
where
pl = mySide b
beta | bestValue == lb = bestValue + 1
| otherwise = bestValue
-- | iterative deepening
iterative :: ABTables -> Board -> MVar (DMove, String) -> IO ()
iterative tt board mvar = search' 1 ([], 0)
where
search' :: Int -> (DMove, Int) -> IO ()
search' depth gues = do
#ifdef VERBOSE
putStrLn $ "info actual " ++ show gues
#endif
hFlush stdout
m@(pv,sc) <- mtdf board tt gues depth (-iNFINITY) iNFINITY
_ <- swapMVar mvar (pv, show sc)
search' (depth+1) m
#ifdef ENGINE
main :: IO ()
main = runAEIInterface newSearch
#endif