Skip to content

Commit 6ec9f47

Browse files
committed
Learn: store statistics.
refs #6.
1 parent ad55907 commit 6ec9f47

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

src/AI/AlphaBeta/Persistent.hs

+15-7
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ readDataSized file = do
191191
bstr <- readBytes file (fromIntegral size)
192192
when (B.null bstr) $ do
193193
offset <- tell file
194-
fail $ "readDataSized: unexpected EOF, offset " ++ show offset
194+
fail $ "readDataSized: zero data size, offset " ++ show offset
195195
liftIO $ Data.Store.decodeIO bstr
196196

197197
writeDataSized :: forall a. Data.Store.Store a => FileType -> a -> Storage ()
@@ -338,6 +338,7 @@ putRecordFileB bstr newData = do
338338
let dataBlockNumber = irDataBlock record
339339
if dataBlockNumber == unexistingBlock
340340
then do
341+
Metrics.increment "storage.data.block.created"
341342
newDataBlock <- createDataBlock
342343
let record' = record {irDataBlock = newDataBlock}
343344
seek IndexFile idxOffset
@@ -346,6 +347,7 @@ putRecordFileB bstr newData = do
346347
writeDataSized DataFile newData
347348
return ()
348349
else do
350+
Metrics.increment "storage.data.block.reused"
349351
let dataOffset = calcDataBlockOffset dataBlockNumber
350352
seek DataFile dataOffset
351353
oldData <- readDataSized DataFile
@@ -361,12 +363,15 @@ putRecordFileB bstr newData = do
361363
let nextBlockNumber = irIndexBlock record
362364
if nextBlockNumber == unexistingBlock
363365
then do
366+
Metrics.increment "storage.index.block.created"
364367
newIndexBlock <- createIndexBlock
365368
let record' = record {irIndexBlock = newIndexBlock}
366369
seek IndexFile idxOffset
367370
writeData IndexFile record'
368371
tryBlock newIndexBlock (B.tail bstr)
369-
else tryBlock nextBlockNumber (B.tail bstr)
372+
else do
373+
Metrics.increment "storage.index.block.reused"
374+
tryBlock nextBlockNumber (B.tail bstr)
370375

371376
createIndexBlock = do
372377
seek IndexFile 0
@@ -461,7 +466,7 @@ readDataSizedIO file = do
461466
bstr <- B.hGet file (fromIntegral size)
462467
when (B.null bstr) $ do
463468
offset <- hTell file
464-
fail $ printf "readDataSized: unexpected EOF, offset %s, size %s" (show offset) (show size)
469+
fail $ printf "readDataSizedIO: zero data size, offset %s, size %s" (show offset) (show size)
465470
Data.Store.decodeIO bstr
466471

467472
dumpIndexBlock :: Handle -> BoardSize -> IndexBlockNumber -> IO ()
@@ -476,8 +481,11 @@ checkDataFile :: FilePath -> IO ()
476481
checkDataFile path = withFile path ReadMode $ \file -> do
477482
nBlocks <- readDataIO file :: IO DataBlockNumber
478483
forM_ [0 .. nBlocks - 1] $ \i -> do
479-
let start = fromIntegral $ calcDataBlockOffset i
480-
hSeek file AbsoluteSeek start
481-
size <- readDataIO file :: IO Word16
482-
printf "Block #%d: data size %d\n" i size
484+
let start = fromIntegral $ calcDataBlockOffset i
485+
hSeek file AbsoluteSeek start
486+
size <- readDataIO file :: IO Word16
487+
when (size > 0) $ do
488+
bstr <- B.hGet file (fromIntegral size)
489+
record <- Data.Store.decodeIO bstr :: IO PerBoardData
490+
printf "Block #%d: data: %s\n" i (show record)
483491

src/Learn.hs

+28-15
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,60 @@ import Core.Board
1616
import AI.AlphaBeta
1717
import AI.AlphaBeta.Types
1818
import AI.AlphaBeta.Cache
19+
import AI.AlphaBeta.Persistent
1920
import Formats.Types
2021
import Formats.Pdn
2122

2223
doLearn :: (GameRules rules, Evaluator eval) => rules -> eval -> AICacheHandle rules eval -> AlphaBetaParams -> GameRecord -> Checkers ()
2324
doLearn rules eval var params gameRec = do
24-
let board = initBoardFromTags (SomeRules rules) (grTags gameRec)
25-
$info "Initial board: {}; tags: {}" (show board, show $ grTags gameRec)
25+
let startBoard = initBoardFromTags (SomeRules rules) (grTags gameRec)
26+
$info "Initial board: {}; tags: {}" (show startBoard, show $ grTags gameRec)
2627
forM_ (instructionsToMoves $ grMoves gameRec) $ \moves -> do
27-
-- liftIO $ print moves
28-
go board [] moves
28+
(endScore, allBoards) <- go (0, []) startBoard [] moves
29+
$info "End score: {}" (Single endScore)
30+
runStorage var $ forM_ allBoards $ \board -> do
31+
let stats = Stats 1 endScore endScore endScore
32+
putStatsFile board stats
33+
2934
where
30-
go _ _ [] = return ()
31-
go board0 predicted (moveRec : rest) = do
32-
(board1, predict2) <- do
35+
go (score, boards) lastBoard _ [] = return (score, lastBoard : boards)
36+
go (score0, boards) board0 predicted (moveRec : rest) = do
37+
(board1, predict2, score2) <- do
3338
case mrFirst moveRec of
34-
Nothing -> return (board0, [])
39+
Nothing -> return (board0, [], score0)
3540
Just rec -> do
3641
let move1 = parseMoveRec rules First board0 rec
3742
if move1 `elem` predicted
3843
then Metrics.increment "learn.hit"
3944
else Metrics.increment "learn.miss"
4045
let (board1, _,_) = applyMove rules First move1 board0
41-
predict2 <- processMove rules eval var params Second move1 board1
42-
return (board1, predict2)
46+
(predict2, score2) <- processMove rules eval var params Second move1 board1
47+
return (board1, predict2, score2)
4348
case mrSecond moveRec of
44-
Nothing -> return ()
49+
Nothing -> return (score2, board0 : board1 : boards)
4550
Just rec -> do
4651
let move2 = parseMoveRec rules Second board1 rec
4752
if move2 `elem` predict2
4853
then Metrics.increment "learn.hit"
4954
else Metrics.increment "learn.miss"
5055
let (board2, _, _) = applyMove rules Second move2 board1
51-
predict1 <- processMove rules eval var params First move2 board2
52-
go board2 predict1 rest
56+
(predict1, score1) <- processMove rules eval var params First move2 board2
57+
go (score1, board0 : board1 : boards) board2 predict1 rest
5358

54-
processMove :: (GameRules rules, Evaluator eval) => rules -> eval -> AICacheHandle rules eval -> AlphaBetaParams -> Side -> Move -> Board -> Checkers [Move]
59+
processMove :: (GameRules rules, Evaluator eval)
60+
=> rules
61+
-> eval
62+
-> AICacheHandle rules eval
63+
-> AlphaBetaParams
64+
-> Side
65+
-> Move
66+
-> Board
67+
-> Checkers ([Move], Score)
5568
processMove rules eval var params side move board = do
5669
let ai = AlphaBeta params rules eval
5770
(moves, score) <- runAI ai var side board
5871
$info "Processed: side {}, move: {}, depth: {} => score {}; we think next best moves are: {}" (show side, show move, abDepth params, show score, show moves)
59-
return moves
72+
return (moves, score)
6073

6174
learnPdn :: (GameRules rules, Evaluator eval) => AlphaBeta rules eval -> FilePath -> Checkers ()
6275
learnPdn ai@(AlphaBeta params rules eval) path = do

src/Main.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ main = do
3636
let rules = russian
3737
eval = ai
3838
params = def {
39-
abDepth = 6
39+
abDepth = 4
4040
, abCombinationDepth = 9
4141
}
4242
ai = AlphaBeta params rules (dfltEvaluator rules)

0 commit comments

Comments
 (0)