-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApocStrategyHuman.hs
More file actions
77 lines (70 loc) · 3.62 KB
/
ApocStrategyHuman.hs
File metadata and controls
77 lines (70 loc) · 3.62 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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module ApocStrategyHuman where
import Data.Maybe (fromJust, isNothing)
--import Data.List ((\\))
import Data.Foldable(find)
import Text.Read(readMaybe)
import ApocTools
--import ApocUtil
human :: Chooser
human board Normal player =
do move <- readNPairs 2
("Enter the move coordinates for player "
++ (show player)
++ " in the form 'srcX srcY destX destY'\n"
++ "[0 >= n >= 4, or just enter return for a 'pass'] "
++ (if player==White then "W" else "B")
++ "2:\n")
(\x -> x>=0 && x<=4)
return move
human board PawnPlacement player =
do move <- readNPairs 1
("Enter the coordinates to place the pawn for player "
++ (show player)
++ " in the form 'destX destY':\n"
++ "[0 >= n >= 4] "
++ (if player==White then "W" else "B")
++ "1:\n")
(\x -> x>=0 && x<=4)
return move
list2pairs :: [a] -> [(a,a)]
list2pairs [] = []
list2pairs (x0:x1:xs) = (x0,x1):list2pairs xs
{- | Reads a pair of pairs from standard input in the form "int1 int2 int3 int4". If user
just types a return, Nothing is returned, otherwise if the user types other than
4 well-formed integers, then a subsequent attempt is done until we get correct
input.
-}
readNPairs :: Int -> String -> (Int->Bool)-> IO (Maybe [(Int,Int)])
readNPairs n prompt f =
do putStrLn prompt
line <- getLine
putStrLn line
let lst = words line
in if length lst == 0
then return Nothing
else
if length lst < (2*n)
then do putStrLn $ "Bad input! (" ++ line ++ ") \nPlease enter "
++ show (n*2) ++ " integers in the form '"
++ (foldl (++) " " [show i++" "|i<-[1..n*2]]) ++ "'" -- count up to n
readNPairs n prompt f
else case readInts (n*2) lst f of
Nothing -> do putStrLn $ "Bad input: one or more integers is manformed! ("
++ line ++ ") \nPlease enter "
++ show (n*2) ++ " integers in the form '"
++ (foldl (++) " " [show i++" "|i<-[1..n*2]]) ++ "'" -- count up to n
readNPairs n prompt f
Just x -> return $ Just $ list2pairs x
{- | Converts a list of Strings into a list of Ints that obey constraint f.
If one or more of the strings does not parse into an Int, or if it fails constraint
f, then return Nothing.
-}
readInts :: Int -> [String] -> (Int->Bool) -> Maybe [Int]
readInts n xs f = let ints = take n $ map (readMaybe :: String -> Maybe Int) xs -- convert each from String to Int
-- setting each to Nothing if failure
in if find (isNothing) ints == Nothing -- check all reads were successful
then let ints2 = (map (fromJust) ints) -- strip the "Just" from each element
in if find (==False) (map f ints2) == Nothing -- check constraint
then Just ints2 -- success
else Nothing -- failure (constraint f)
else Nothing -- failure (int conversion)