-
Notifications
You must be signed in to change notification settings - Fork 2
/
tic-tac-toe.red
146 lines (130 loc) · 3.24 KB
/
tic-tac-toe.red
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
140
141
142
143
144
145
146
Red [
Title: {tic-tac-toe}
File: %tic-tac-toe.red
Author: "Wayne Tsui"
Name: 'tia-tac-toe
Description: {
A Tic Tac Toe Game to play with a clever computer.
COMPUTER-STRATEGE employs the strategy from http://en.wikipedia.org/wiki/Tic-tac-toe
}
]
tic-tac-toe: context [
keypoints: [[ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] [ 1 4 7 ] [ 2 5 8 ][ 3 6 9 ] [ 1 5 9 ][ 3 5 7 ]]
center: 5
corners: [ 1 3 7 9 ]
sides: [ 2 4 6 8 ]
validate-input: function [ position [block!] return: [logic!]][
x: position/1
y: position/2
unless all [ x y integer? x integer? y x >= 1 x <= 3 y >= 1 y <= 3 ][ return false ]
board/((x - 1) * 3 + y) = '_
]
test-over: function [ board[block!] return: [logic!]][
fun: function['arg][
either letter = arg ["You"] ["I"]
]
foreach point keypoints [
oss: copy []
xs: copy []
foreach i point [append oss (board/:i = quote 'X)]
foreach i point [append xs (board/:i = quote 'O)]
case [
all oss [print [fun 'X "win!"] return true]
all xs [print [fun 'O "win!"] return true]
]
]
unless find board '_ [ print "Tie!" return true ]
]
test-win: function[ board [ block! ] return: [logic!]][
board: copy board
foreach point keypoints [
cs: copy []
ps: copy []
foreach i point [append cs (board/(i) = symbols/computer)]
foreach i point [append ps (board/(i) = symbols/player)]
case [
all cs [ return true]
all ps [ return true]
]
]
]
computer-stratege: function[ board [block!] return: [ unset! ]][
temp: copy []
cb: copy board
if not find cb '_ [ exit ]
until [
append temp index? find cb '_
cb: next cb
not find cb '_
]
;First, check if we can win in the next move
foreach i temp [
cb: copy board
cb/(i): symbols/computer
if test-win cb [ return i ]
]
;;Second, check if the player could win on his next move, and block them.
foreach i temp [
cb: copy board
cb/(i): symbols/player
if test-win cb [ return i ]
]
;;Third, try to take one of the corners, if they are free.
foreach i corners [
if find temp i [ return i ]
]
;;Others
case [
find temp center [ center ]
true [ first temp ]
]
]
print-board: function[ board [block!]][
board: copy board
insert at board 7 lf
insert at board 4 lf
print board
]
;MAIN PROGRAM
start: does [
print "Welcome to the tic tac toe game."
print "Let's begin!"
board: copy [ '_ '_ '_ '_ '_ '_ '_ '_ '_ ]
;;Who will make the first move
;player: true
player: false
until [
letter: ask "Do you want to be [X] or [O] or just [Q]uit?"
switch/default first letter [
#"x" #"X" [ symbols: [ player 'X computer 'O ] true ]
#"o" #"O" [ symbols: [ player 'O computer 'X ] true ]
#"q" #"Q" [ quit ]
][
print "Invalid input."
false
]
]
until [
either player [
print "It's your turn!"
;player's move
until [
position: load ask "Please enter [x y]:"
validate-input position
]
board/((position/1 - 1) * 3 + position/2): symbols/player
player: false
][
print "It's my turn!"
;computor's move
move: computer-stratege board
board/(move): symbols/computer
player: true
]
print-board board
test-over board
]
if(first ask "Try again? [Y/N]: ") = #"Y" [start]
]
]
tic-tac-toe/start