-- -- | -- Module : RobberOneStepMoveFun -- Copyright : (c) 2005 -- License : GPL version 2 or later -- Created : 26 Jun 2005 -- -- Looks ahead one move. -- module CopSimpleMoveFun where import KnowledgeBase import CopHeuristic import Syntax import Logging import Pretty import CR import Graph import Utils import qualified Data.Map as M import System.IO import System.Random import Control.Concurrent.MVar import System.IO.Unsafe import Monad import Data.List ------------------------------------------------------------------------ {- -- the state is the times at which banks were robbed data CopState = CopState state :: MVar CopState state = unsafePerformIO (newMVar CopState) {-# NOINLINE state #-} getState :: CR CopState getState = liftIO $ readMVar state setState :: CopState -> CR () setState s = liftIO $ modifyMVar_ state $ (const $ return s) -} ------------------------------------------------------------------------ moveFun :: CR CopMove moveFun = do kb <- getKB nodes <- mapM moveFun' (kb_ownLoc kb) let moves = nodes offer = Straight accuses = [] return $ CopMove offer (MoveBlock moves) (AccuseBlock accuses) moveFun' :: (Name, GNode) -> CR Move moveFun' (name, loc) = do kb <- getKB let graphFoot = kb_footMap kb let nexts = gsucc graphFoot loc next <- do goodnessNodes <- mapM checkGoodness nexts let nextNodes = reverse $ sortBy orderLoc goodnessNodes maxVal = fst (head nextNodes) numMaxVals = length (filter (\(v, _) -> abs (v - maxVal) < 0.001) nextNodes) r <- liftIO $ randomRIO (0, numMaxVals - 1) return $ snd (nextNodes !! r) -- -- Move to best node -- liftIO $ setVisited next return $ Move (locOfNode next) CopFoot name where -- tune our coefficients: checkGoodness nextLoc = do kb <- getKB vs <- liftIO $ getVisited g <- goodness nextLoc 5000 -- near nodes where robber could be 0 -- near next robbed bank 0 -- just near a bank in general 50 -- near the bank the robber starts at 500 -- penalty for nodes visited recently 10 -- random bonus vs -- nodes visited recently kb return (g, nextLoc) orderLoc (a, _) (b, _) | a < b = LT | a == b = EQ | otherwise = GT ------------------------------------------------------------------------ numberOfVisitedNodes = 5 visitedNodes :: MVar [GNode] visitedNodes = unsafePerformIO $ newMVar [] {-# NOINLINE visitedNodes #-} {- isVisited :: GNode -> IO Bool isVisited g = withMVar visitedNodes $ \m -> return $ case M.lookup g m of Nothing -> False Just _ -> True -} setVisited :: GNode -> IO () setVisited g = modifyMVar_ visitedNodes $ \l -> return $ g : take (numberOfVisitedNodes - 1) l getVisited :: IO [GNode] getVisited = readMVar visitedNodes ------------------------------------------------------------------------