3 -- Copyright : (c) 2008 Bertram Felgenhauer
6 -- Maintainer : Bertram Felgenhauer <int-e@gmx.de>
7 -- Stability : experimental
8 -- Portability : portable
10 -- This module is part of Haskell PGMS.
13 {-# LANGUAGE BangPatterns #-}
22 import qualified Graphics
.UI
.Gtk
as G
23 import System
.Glib
.Attributes
(AttrOp
(..))
25 import Control
.Concurrent
.MVar
26 import Control
.Concurrent
31 data Stat
= Stat
!Int !Int !Int !Int
33 runStats
:: Globals
-> IO ()
35 s
<- readIORef
(gState g
)
36 let strat
= sStrategy s
39 counter
<- newMVar
(Stat
0 0 0 0)
42 thread
<- forkIO
$ gatherStats counter chunks notify strat cfg
45 win `G
.set`
[G
.windowTitle
:= "Statistics for " ++ sName strat
]
47 vbox
<- G
.vBoxNew
False 2
48 win `G
.containerAdd` vbox
50 hbox
<- G
.hBoxNew
False 2
51 vbox `G
.containerAdd` hbox
53 configFrame
<- G
.frameNew
54 hbox `G
.containerAdd` configFrame
55 configFrame `G
.frameSetLabel`
"Board"
57 configTable
<- G
.tableNew
3 2 False
58 configFrame `G
.containerAdd` configTable
59 let Config
{ cSize
= Pos sX sY
, cMines
= m
} = sConfig s
60 forM_
(zip3 [0..] ["width", "height", "mines"] [sX
, sY
, m
])
61 $ \(c
, name
, val
) -> do
62 label
<- G
.labelNew
(Just name
)
63 G
.miscSetAlignment label
0 0.5
64 G
.tableAttach configTable label
0 1 c
(c
+1) [G
.Fill
] [] 5 2
65 label
<- G
.labelNew
(Just
(show val
))
66 G
.miscSetAlignment label
1 0.5
67 G
.tableAttach configTable label
1 2 c
(c
+1) [G
.Expand
, G
.Fill
] [] 5 2
69 statsFrame
<- G
.frameNew
70 hbox `G
.containerAdd` statsFrame
71 statsFrame `G
.frameSetLabel`
"Statistics"
73 statsTable
<- G
.tableNew
3 3 False
74 statsFrame `G
.containerAdd` statsTable
75 cs
<- forM
(zip [0..] ["won", "unfinished", "lost"]) $ \(c
, label
) -> do
76 label
<- G
.labelNew
(Just label
)
77 G
.miscSetAlignment label
0 0.5
78 G
.tableAttach statsTable label
0 1 c
(c
+1) [G
.Fill
] [] 5 2
79 label2
<- G
.labelNew
(Just
"0")
80 G
.miscSetAlignment label2
1 0.5
81 G
.tableAttach statsTable label2
1 2 c
(c
+1) [G
.Expand
, G
.Fill
] [] 5 2
82 label3
<- G
.labelNew
(Just
"0.00%")
83 G
.miscSetAlignment label3
1 0.5
84 G
.tableAttach statsTable label3
2 3 c
(c
+1) [G
.Expand
, G
.Fill
] [] 5 2
85 return (label2
, label3
)
87 button
<- G
.toggleButtonNewWithLabel
"Pause"
88 vbox `G
.containerAdd` button
89 button `G
.onToggled`
do
90 active
<- G
.toggleButtonGetActive button
91 if active
then takeMVar chunks
>> return () else putMVar chunks
1
94 x
<- tryTakeMVar notify
97 Stat w u l t
<- takeMVar counter
100 putMVar counter
(Stat w u l total
)
101 c
<- tryTakeMVar chunks
104 putMVar chunks
(maximum [1, d
' `
div`
2, d `
div`
2])
106 forM_
(zip [w
, u
, l
] cs
) $ \(c
, (labelN
, labelP
)) -> do
107 labelN `G
.labelSetText`
show c
108 when (total
> 0) $ do
109 let pct
= 100 * fromIntegral c
/ fromIntegral total
110 labelP `G
.labelSetText`
showGFloat (Just
2) pct
"%"
114 timer
<- G
.timeoutAddFull update G
.priorityDefaultIdle
100
118 G
.timeoutRemove timer
122 -- thread for collecting statistics
123 gatherStats
:: MVar Stat
-> MVar
Int -> MVar
() -> Strategy
-> Config
-> IO ()
124 gatherStats counter chunks notify strategy cfg
= do
126 let stats
:: Int -> Int -> Int -> Int -> IO Stat
127 stats
0 !w
!u
!l
= return (Stat w u l
0)
128 stats i
!w
!u
!l
= do
129 [gen1
, gen2
] <- replicateM
2 newStdGen
130 let (res
, _
) = playGame cfg gen1
(sRun strategy gen2
)
132 Won
-> stats
(i
-1) (w
+1) u l
133 Unfinished _
-> stats
(i
-1) w
(u
+1) l
134 Lost
-> stats
(i
-1) w u
(l
+1)
135 Stat w u l _
<- stats n
0 0 0
136 Stat w
' u
' l
' t
' <- takeMVar counter
137 putMVar counter
$! Stat
(w
+ w
') (u
+ u
') (l
+ l
') t
'
139 gatherStats counter chunks notify strategy cfg