hs-pgms-0.1: src/SimpleStrat.hs
-- |
-- Module : SimpleStrat
-- Copyright : (c) 2008 Bertram Felgenhauer
-- License : BSD3
--
-- Maintainer : Bertram Felgenhauer <int-e@gmx.de>
-- Stability : experimental
-- Portability : portable
--
-- This module is part of Haskell PGMS.
--
-- Another simple minesweeper strategy.
--
module SimpleStrat (simpleStrat) where
import Mine
import Data.Array.IArray
import System.Random
import Control.Monad
simpleStrat :: Strategy
simpleStrat = defaultStrategy {
sName = "SimpleStrat",
sAuthor = "Bertram Felgenhauer <int-e@gmx.de>",
sDescription =
"This strategy makes inferences from exposed cells and their immediate \
\neighbourhood, and picks a random cell if no inference can be made.\n\
\It should be equivalent to the PGMS Single Point Strategy.",
sRun = \s -> getConfig >>= flip worker s
}
worker :: Config -> StdGen -> StrategyM String
worker cfg gen = do
view <- getView
let actions = scan cfg view
if null actions then randomMove cfg view gen >>= worker cfg
else sequence_ actions >> worker cfg gen
randomMove :: Config -> View -> StdGen -> StrategyM StdGen
randomMove cfg@Config { cSize = Pos sX sY } view gen = let
(x, gen') = randomR (1, sX) gen
(y, gen'') = randomR (1, sY) gen'
p = Pos x y
in
if view ! p == Hidden then move p >> return gen''
else randomMove cfg view gen''
scan :: Config -> View -> [StrategyM ()]
scan cfg view = concat
[ moves
| (p, Exposed num) <- assocs view,
let ns = neighbours cfg p
ms = [n | n <- ns, view ! n == Marked]
us = [n | n <- ns, view ! n == Hidden]
moves | num == length ms = [move_ n | n <- us]
| num == length ms + length us = [mark n | n <- us]
| otherwise = []]