icfp14/AI.hs

48 行
1.4 KiB
Haskell

module AI (aimove) where
import Eval
import Lambda
import GoalTransform
import qualified Data.Array.IO as A
cannon 1 = "dec"
cannon 2 = "S dec dec"
cannon n = "S(" ++ cannon (n-1) ++ ") dec"
keepalive func 0 = "S(" ++ func ++ ")(get)0"
keepalive func 1 = "S(K(S(" ++ func ++ ")(get)))(succ)0"
keepalive func slot = "S(" ++ func ++ ")(S (K get) (K " ++ show slot ++ "))0"
findAliveSlot :: (Game -> Player) -> Turn Int
findAliveSlot player = do
game <- getGame
slots <- liftIO $ A.getAssocs (fields $ player game)
let (slot, _):_ = filter (\(_, (_, vit)) -> vit > 0) slots
return slot
findHighAliveSlot :: (Game -> Player) -> Turn Int
findHighAliveSlot player = do
game <- getGame
slots <- liftIO $ A.getAssocs (fields $ player game)
let (slot, _):_ = filter (\(_, (_, vit)) -> vit > 0) $ reverse slots
return slot
aimove :: Turn Goal
aimove = do
target <- findAliveSlot opponent
let l = if (target == 255) then "S(dec)(S(get)(I))" else "S(S(K(dec))(K(" ++ show (255-target) ++ ")))(S(get)(I))"
-- let l = if (target == 255) then "S(dec)(S(get)(I))" else "S(K(S(dec)(S(get)(I))))(K(" ++ show (255-target) ++ "))"
let pos = 1 -- if (target == 255) then 1 else 255-target
haveLoop <- satGoal (0, read l)
if haveLoop then do
haveLoop <- satGoal (pos, read l)
if haveLoop then do
return (Just pos, read (l ++ "0"))
else
return (Just pos, read "get 0")
else do
return (Just 0, read l)