-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchapter11.hs
69 lines (49 loc) · 1.38 KB
/
chapter11.hs
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
import Data.Char
import Data.List
import System.IO
size :: Int
size = 3
type Grid = [[Player]]
data Player = O | B | X deriving (Eq, Ord, Show)
next :: Player -> Player
next O = X
next X = O
next B = B
empty :: Grid
empty = replicate size (replicate size B)
full :: Grid -> Bool
full = all (/= B) . concat
turn :: Grid -> Player
turn g = if os <= xs then O else X
where
os = length (filter (== O) ps)
xs = length (filter (== X) ps)
ps = concat g
wins :: Player -> Grid -> Bool
wins p g = any line (rows ++ cols ++ dias)
where
line = all (== p)
rows = g
cols = transpose g
dias = [diag g, diag (map reverse g)]
diag :: Grid -> [Player]
diag g = [g !! n !! n | n <- [0..size-1]]
won :: Grid -> Bool
won g = wins O g || wins X g
putGrid :: Grid -> IO ()
putGrid = putStrLn . unlines . concat . interleave bar . map showRow
where bar = [replicate ((size * 4) -1) '-']
showRow :: [Player] -> [String]
showRow = beside . interleave bar . map showPlayer
where
beside = foldr1 (zipWith (++))
bar = replicate 3 "|"
showPlayer :: Player -> [String]
showPlayer O = [" ", " O ", " "]
showPlayer B = [" ", " ", " "]
showPlayer X = [" ", " X ", " "]
interleave :: a -> [a] -> [a]
interleave x [] = []
interleave x [y] = [y]
interleave x (y:ys) = y : x : interleave x ys
howPlayer O = [" ", " O ", " "]