-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathp4.sc
139 lines (119 loc) · 4.66 KB
/
p4.sc
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
129
130
131
132
133
134
135
136
137
138
139
;Generate a list of rows
(define (generate-rows n row)
(if (= n 0)
row
(generate-rows (- n 1) (cons 0 row))))
;Generates a list of rows with size n and row size m
(define (generate-board n m list-rows)
(if (= n 0)
list-rows
(generate-board (- n 1) m (cons (generate-rows m (list)) list-rows))))
;Generates initial n x n empty board
(define (initial-board n)
(generate-board n n (list)))
;Gets length of row
(define (len-row len row)
(if (null? row)
len
(len-row (+ len 1) (rest row))))
;Get's legal moves of each row
(define (get-row-moves x y row list-moves len-row)
(if (= x len-row)
list-moves
(if (= (first row) 0)
(get-row-moves (+ x 1) y (rest row) (append list-moves (list (list (+ x 1) (+ y 1)))) len-row)
(get-row-moves (+ x 1) y (rest row) list-moves len-row))))
;Returns list of all legal moves for a board
(define (get-moves b len y list-moves)
(if (null? b)
list-moves
(get-moves (rest b) len (+ y 1) (get-row-moves 0 y (first b) list-moves len))))
;Returns the list of legal moves for a player in board b
(define (moves b)
(get-moves b (len-row 0 (first b)) 0 (list)))
;Checks if move is legal or not and returns 1 if it is legal otherwise returns a 0
(define (check-legal-move move list-moves)
(if (null? list-moves)
0
(if (equal? move (first list-moves))
1
(check-legal-move move (rest list-moves)))))
;Change a row to reflect move of player
(define (change-row x row curr-col player new-row row-len)
(if (= curr-col row-len)
new-row
(if (= x curr-col)
(change-row x (rest row) (+ curr-col 1) player (append new-row (list player)) row-len)
(change-row x (rest row) (+ curr-col 1) player (append new-row (list (first row))) row-len))))
;Go to row specified by move and change its correct column to make move
(define (go-to-row x y b curr-row player b-len b-prime)
(if (= b-len curr-row)
b-prime
(if (= y curr-row)
(go-to-row x y (rest b) (+ curr-row 1) player b-len (append b-prime (list (change-row x (first b) 0 player (list) b-len))))
(go-to-row x y (rest b) (+ curr-row 1) player b-len (append b-prime (list (first b)))))))
;Makes a move m on board b and returns the new board after checking if move is legal oherwise just returns original board
(define (make-move m b)
(if (= (check-legal-move (first (rest m)) (moves b)) 0)
b
(go-to-row (- (first (first (rest m))) 1) (- (last (first (rest m))) 1) b 0 (first m) (len-row 0 (first b)) (list))))
;Checks a row to see if a player won or not
(define (check-row row player row-len curr-col iter)
(if (not (= player curr-col))
0
(if (= iter row-len)
1
(check-row (rest row) player row-len (first row) (+ iter 1)))))
;Checks if a player won by getting the rows
(define (win-row player b iter side-len)
(if (= iter side-len)
0
(if (= 1 (check-row (first b) player side-len (first (first b)) 0))
1
(win-row player (rest b) (+ iter 1) side-len))))
;Returns which player won through rows only
(define (win-player-row player-list b side-len)
(if (null? player-list)
0
(if (= (win-row (first player-list) b 0 side-len) 1)
(first player-list)
(win-player-row (rest player-list) b side-len))))
;Returns which player won through columns only
(define (win-player-col player-list b side-len)
(win-player-row player-list (transpose b) side-len))
;Transposes board
(define (transpose b)
(apply map list b))
;Gets the number in the diagonal in the current row
(define (get-diagonal-num row-num col-iter row)
(if (= col-iter row-num)
(first row)
(get-diagonal-num row-num (+ col-iter 1) (rest row))))
;Gets the list of numbers in the diagonal
(define (get-diagonal-list b list-diag row-num)
(if (null? b)
list-diag
(get-diagonal-list (rest b) (append list-diag (list (get-diagonal-num row-num 0 (first b)))) (+ row-num 1))))
;Checks if current player wins any diagonal
(define (win-diag player b iter side-len)
(if (= iter 2)
0
(if (= 1 (check-row (get-diagonal-list b (list) 0) player side-len (first (get-diagonal-list b (list) 0)) 0))
1
(win-diag player (reverse b) (+ iter 1) side-len))))
;Returns which player wins a diagonal
(define (win-player-diag player-list b side-len)
(if (null? player-list)
0
(if (= (win-diag (first player-list) b 0 side-len) 1)
(first player-list)
(win-player-diag (rest player-list) b side-len))))
;Returns if a player won
(define (win b)
(if (not (= (win-player-row (list 1 -1) b (len-row 0 (first b))) 0))
(win-player-row (list 1 -1) b (len-row 0 (first b)))
(if (not (= (win-player-col (list 1 -1) b (len-row 0 (first b))) 0))
(win-player-col (list 1 -1) b (len-row 0 (first b)))
(if (not (= (win-player-diag (list 1 -1) b (len-row 0 (first b))) 0))
(win-player-diag (list 1 -1) b (len-row 0 (first b)))
0))))