-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMasterAI.hs
More file actions
54 lines (45 loc) · 1.57 KB
/
MasterAI.hs
File metadata and controls
54 lines (45 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module MasterAI (AIState, AIStateM, aiTurn, initAIState, masterAI, updateAI) where
import GameRules
import Control.Monad (replicateM) --for permutations
import Control.Monad.State (StateT, get, put, gets, modify)
import Control.Monad.Identity
import System.Random (StdGen, random, randomR, newStdGen)
type AIGuess = (PegCode, CompRes)
data AIState = AIState {
aiTurn :: Int,
aiGuesses :: [AIGuess],
codeLen :: Int,
aiPossible :: [PegCode],
aiRndGen :: StdGen
}
type AIStateM = StateT AIState Identity
colors = [Red, Green, Blue, Yellow, Purple, Orange]
initAIState :: Int -> IO AIState
initAIState n = do
gen <- newStdGen
return $ AIState 0 [] n p gen
where
p = replicateM n colors
masterAI :: AIStateM PegCode
masterAI = do
cl <- gets codeLen
turn <- gets aiTurn
guess <- case turn of
0 -> return $ take cl $ cycle [Red,Green]
1 -> return $ take cl $ cycle [Blue,Yellow]
-- 2 -> return $ take cl $ cycle [Purple,Orange]
n -> chooseBestGuess
return guess
updateAI :: PegCode -> CompRes -> AIStateM ()
updateAI guess res = modify $
\st@(AIState turn guesses _ _ _) -> st{
aiTurn = turn + 1,
aiGuesses = (guess, res): guesses }
chooseBestGuess :: AIStateM PegCode
chooseBestGuess = do
st@(AIState _ guess _ poss gen) <- get
let p = [c | c <- poss, all (\(g,r) -> compPegs c g == r) guess]
l = length p
(c, gen') = randomR (0, l-1) gen
put st {aiRndGen = gen'}
return (p !! c)