-- -- Copyright (c) 2005 Don Stewart - http://www.cse.unsw.edu.au/~dons -- Sean Seefried -- Stefan Wehr -- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html) -- module CopABMoveFun where import List ( maximumBy, elemIndex ) import Maybe ( fromJust ) import qualified CopSimpleMoveFun as SMF import qualified CopHeuristic as CH import CR import Logging import AlphaBeta hiding ( ABMove(..) ) import Syntax import KnowledgeBase import Graph import CopState {- getCutoff :: [GNode] -- number of possible robber positions -> Int getCutoff l | length l <= 1 = 14 | length l <= 5 = 13 | otherwise = 11 maxGoodness = 4 minGoodness = 0 goodnessAB :: KnowledgeBase -> Int goodnessAB kb = case kb_robber kb of Nothing -> minGoodness Just robber -> let own = kb_ownLoc kb in if robber `elem` own then maxGoodness else let g = kb_footSPs kb p = fastShortestPath own robber g dist = length p - 1 in max minGoodness (maxGoodness - dist) {- goodness kb = floor (CH.goodnessAB 1000 -- near next robbed bank 5 -- just near a bank in general 50 -- near the bank the robber starts at kb) -} timeout = 3500 aroundThreshold = 4 moveFun :: CR CopMove moveFun = watchdogCR timeout moveFun' SMF.moveFun moveFun' :: CR CopMove moveFun' = time Info "CopMoveFun" $ do kb <- getKB state <- getState let pos = possibleRobberPositions kb state if null pos then do info ("have no clue where the robber is, using simple " ++ "move fun") SMF.moveFun else do let cutoff = getCutoff pos info ("the robber is at one of the following positions (" ++ show pos ++ "). I am at " ++ show own ++ ". I'll use AB search with cutoff " ++ show cutoff) let bestMoves = copABSearch kb pos cutoff goodnessAB myMove = bestMoves !! (myIndex kb) info ("move returned by AB-search: " ++ show myMove) return $ CopMove Straight (MoveBlock [Move (locOfNode myMove) CopFoot (kb_ownName kb)]) (AccuseBlock []) where myIndex :: KnowledgeBase -> Int myIndex kb = copIndex (kb_ownName kb) (kb_cops kb) -- returns the empty list of the search space would become too big... possibleRobberPositions :: KnowledgeBase -> CopState -> [GNode] possibleRobberPositions kb state = let prefs = [case kb_robber kb of Just n -> [n] Nothing -> [] , case byRobbedBank kb of l@(_:_) -> l _ -> [] , case kb_smell kb of Just (Smell n) -> case somewhereAround kb ownLoc n of l@(_:_) -> l _ -> [] Nothing -> [] , bestEvidence kb , byOtherLocs kb state ] select [] = [] select (l:ls) = if not (null l) then l else select ls in select prefs somewhereAround :: KnowledgeBase -> GNode -> Int{- radius -} -> [GNode] somewhereAround kb node n | n > aroundThreshold = [] | otherwise = nodesWithin (kb_footMap kb) node n bestEvidence :: KnowledgeBase -> [GNode] bestEvidence kb = let evs = kb_evidences kb worldNo = kb_worldCount kb in if null evs then [] else let youngest = maximumBy (\e1 e2 -> ev_world e1 `compare` ev_world e2) evs node = ev_node youngest age = worldNo - (ev_world youngest) in somewhereAround kb node age byRobbedBank kb = let bs = kb_robbedbanks kb in if null bs then [] else let b = maximumBy (\ b1 b2 -> (fromJust . bank_lastTimeRobbed) b1 `compare` (fromJust . bank_lastTimeRobbed) b2) bs node = bank_node b n = kb_worldCount kb - (fromJust $ bank_lastTimeRobbed b) in somewhereAround kb node n byOtherLocs kb state | not (null (otherLoc state)) = let (loc, worldNo) = maximumBy (\ t1 t2 -> snd t1 `compare` snd t2) (otherLoc state) diff = kb_worldCount kb - worldNo in somewhereAround kb (lookupNode loc kb) diff byOtherLocs _ _ = [] -}