-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUtils.idr
128 lines (103 loc) · 2.3 KB
/
Utils.idr
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
module Utils
import Data.Vect
import Data.Fin
%default total
public export
data Forever = More Forever
export partial
forever : Forever
forever = More forever
public export
data Player = X | O
export
Eq Player where
X == X = True
O == O = True
_ == _ = False
export
Show Player where
show X = "X"
show O = "O"
public export
data Cell = Blank | P Player
export
Eq Cell where
(==) Blank Blank = True
(==) (P p) (P p') = p == p'
(==) _ _ = False
export
Show Cell where
show Blank = " "
show (P p) = show p
-- This is the only suported size!
public export
Rows : Nat
Rows = 3
-- This is the only suported size!
public export
Cols : Nat
Cols = 3
public export
FieldSize : Nat
FieldSize = Rows * Cols
public export
Position : Type
Position = Fin FieldSize
public export
GameField : Type
GameField = Vect FieldSize Cell
export
rowIndex : Nat -> Nat -> Fin FieldSize
rowIndex r c =
case natToFin (c + r * Cols) FieldSize of
Nothing => FZ
(Just x) => x
export
colIndex : Nat -> Nat -> Fin FieldSize
colIndex = flip rowIndex
public export
data MoveResult : Type where
NextMove : MoveResult
ResultWon : MoveResult
ResultDraw : MoveResult
export
playerCell : Player -> Cell -> Bool
playerCell p (P pl) = pl == p
playerCell _ Blank = False
export
checkCols : Player -> GameField -> Bool
checkCols p xs = any id (map (all (playerCell p)) rows) where
rows : List (List Cell)
rows = [[index (rowIndex r c) xs | c <- [0..2]] | r <- [0..2]]
export
checkRows : Player -> GameField -> Bool
checkRows p xs = any id (map (all (playerCell p)) rows) where
rows : List (List Cell)
rows = [[index (colIndex c r) xs | r <- [0..2]] | c <- [0..2]]
export
checkDiags : Player -> GameField -> Bool
checkDiags p xs = any id (map (all (playerCell p)) diags) where
diags : List (List Cell)
diags =
let
xsInd = flip index xs
in map (map xsInd) (the (List (List (Fin 9))) [[0, 4, 8], [2, 4, 6]])
export
noMoreBlank : GameField -> Bool
noMoreBlank = all (/= Blank)
export
checkMoveResult : GameField -> Player -> MoveResult
checkMoveResult xs p =
if (checkCols p xs) ||
(checkRows p xs) ||
(checkDiags p xs)
then
ResultWon
else
if noMoreBlank xs
then ResultDraw
else NextMove
export
nextPlayer : Player -> Player
nextPlayer X = O
nextPlayer O = X