This repository was archived by the owner on May 25, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
/
Copy pathtic-tac-toe-AI.py
346 lines (256 loc) · 11.4 KB
/
tic-tac-toe-AI.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#### TIC TAC TOE ####
#START;
#FUNCTIONS;
def default():
#To be printed as Default;
print("\nWelcome! Let's play TIC TAC TOE!\n")
def rules():
print("The board will look like this!")
print("The positions of this 3 x 3 board is same as the right side of your key board.\n")
print(" 7 | 8 | 9 ")
print("-----------")
print(" 4 | 5 | 6 ")
print("-----------")
print(" 1 | 2 | 3 ")
print("\nYou just have to input the position(1-9).")
def play():
#Asking if the player is ready;
return input("\nAre you ready to play the game? Enter [Y]es or [N]o.\t").upper().startswith('Y')
def names():
#Player names input;
p1_name=input("\nEnter NAME of PLAYER 1:\t").capitalize()
p2_name=input("Enter NAME of PLAYER 2:\t").capitalize()
return (p1_name, p2_name)
def choice():
#Player choice input;
p1_choice = ' '
p2_choice = ' '
while p1_choice != 'X' or p1_choice != 'O': #while loop; if the entered value isn't X or O;
#WHILE LOOP STARTS
p1_choice = input(f"\n{p1_name}, Do you want to be X or O?\t")[0].upper()
#The input above has [0].upper() in the end;
#So the user can enter x, X, xxxx or XXX; the input will always be taken as X;
#Thereby, increasing the user input window;
if p1_choice == 'X' or p1_choice == 'O':
#if entered value is X or O; get out of the loop;
break
print("INVALID INPUT! Please Try Again!")
#if the entered value isn't X or O, re-run the while loop;
#WHILE LOOP ENDS
#Assigning the value to p2 and then diplaying the values;
if p1_choice == 'X':
p2_choice = 'O'
elif p1_choice == 'O':
p2_choice = 'X'
return (p1_choice, p2_choice)
def first_player():
#This function will randomly decide who will go first;
import random
return random.choice((0, 1))
def display_board(board, avail):
print(" " + " {} | {} | {} ".format(board[7],board[8],board[9]) + " " + " {} | {} | {} ".format(avail[7],avail[8],avail[9]))
print(" " + "-----------" + " " + "-----------")
print(" " + " {} | {} | {} ".format(board[4],board[5],board[6]) + " " + " {} | {} | {} ".format(avail[4],avail[5],avail[6]))
print(" " + "-----------" + " " + "-----------")
print(" " + " {} | {} | {} ".format(board[1],board[2],board[3]) + " " + " {} | {} | {} ".format(avail[1],avail[2],avail[3]))
def player_choice(board, name, choice):
position = 0
#Initialising position as 0^; so it passes through the while loop;
while position not in [1,2,3,4,5,6,7,8,9] or not space_check(board, position):
position = int(input(f'\n{name} ({choice}), Choose your next position: (1-9) \t'))
if position not in [1,2,3,4,5,6,7,8,9] or not space_check(board, position) or position == "":
#To check whether the given position is in the set [1-9] or whether it is empty or occupied;
print(f"INVALID INPUT. Please Try Again!\n")
print("\n")
return position
# THIS IS THEFUNCTION WHERE AI IS ADDED:
def CompAI(board, name, choice):
position = 0
possibilities = [x for x, letter in enumerate(board) if letter == ' ' and x != 0]
# including both X and O, since if computer will win, he will place a choice there, but if the component will win --> we have to block that move
for let in ['O', 'X']:
for i in possibilities:
# Creating a copy of the board everytime, placing the move and checking if it wins;
# Creating a copy like this and not this boardCopy = board, since changes to boardCopy changes the original board;
boardCopy = board[:]
boardCopy[i] = let
if(win_check(boardCopy, let)):
position = i
return position
openCorners = [x for x in possibilities if x in [1, 3, 7, 9]]
if len(openCorners) > 0:
position = selectRandom(openCorners)
return position
if 5 in possibilities:
position = 5
return position
openEdges = [x for x in possibilities if x in [2, 4, 6, 8]]
if len(openEdges) > 0:
position = selectRandom(openEdges)
return position
def selectRandom(board):
import random
ln = len(board)
r = random.randrange(0,ln)
return board[r]
def place_marker(board, avail, choice, position):
#To mark/replace the position on the board list;
board[position] = choice
avail[position] = ' '
def space_check(board, position):
#To check whether the given position is empty or occupied;
return board[position] == ' '
def full_board_check(board):
#To check if the board is full, then the game is a draw;
for i in range(1,10):
if space_check(board, i):
return False
return True
def win_check(board, choice):
#To check if one of the following patterns are true; then the respective player has won!;
#HORIZONTAL CHECK;
return (
( board[1] == choice and board[2] == choice and board[3] == choice )
or ( board[4] == choice and board[5] == choice and board[6] == choice )
or ( board[7] == choice and board[8] == choice and board[9] == choice )
#VERTICAL CHECK;
or ( board[1] == choice and board[4] == choice and board[7] == choice )
or ( board[2] == choice and board[5] == choice and board[8] == choice )
or ( board[3] == choice and board[6] == choice and board[9] == choice )
#DIAGONAL CHECK;
or ( board[1] == choice and board[5] == choice and board[9] == choice )
or ( board[3] == choice and board[5] == choice and board[7] == choice ) )
def delay(mode):
if mode == 2:
import time
time.sleep(2)
def replay():
#If the users want to play the game again?
return input('\nDo you want to play again? Enter [Y]es or [N]o: ').lower().startswith('y')
#MAIN PROGRAM STARTS;
print("\n\t\t NAMASTE! \n")
input("Press ENTER to start!")
default()
rules()
while True:
####################################################################################
#Creating the board as a list; to be kept replacing it with user input;
theBoard = [' ']*10
#Creating the available options on the board:
available = [str(num) for num in range(0,10)] # a List Comprehension
#available = '0123456789'
print("\n[0]. Player vs. Computer")
print("[1]. Player vs. Player")
print("[2]. Computer vs. Computer")
mode = int(input("\nSelect an option [0]-[2]: "))
if mode == 1:
#Asking Names;
p1_name, p2_name = names()
# Asking Choices; Printing choices; X or O;
p1_choice, p2_choice = choice()
print(f"\n{p1_name}:", p1_choice)
print(f"{p2_name}:", p2_choice)
elif mode == 0:
p1_name = input("\nEnter NAME of PLAYER who will go against the Computer:\t").capitalize()
p2_name = "Computer"
# Asking Choices; Printing choices; X or O;
p1_choice, p2_choice = choice()
print(f"\n{p1_name}:", p1_choice)
print(f"{p2_name}:", p2_choice)
else:
p1_name = "Computer1"
p2_name = "Computer2"
p1_choice, p2_choice = "X", "O"
print(f"\n{p1_name}:", p1_choice)
print(f"\n{p2_name}:", p2_choice)
#Printing randomly who will go first;
if first_player():
turn = p2_name
else:
turn = p1_name
print(f"\n{turn} will go first!")
#Asking the user, if ready to play the game; Output will be True or False;
if(mode == 2):
ent = input("\nThis is going to be fast! Press Enter for the battle to begin!\n")
play_game = 1
else:
play_game = play()
while play_game:
############################
#PLAYER1
if turn == p1_name:
#Displaying the board;
display_board(theBoard, available)
#Position of the input;
if mode != 2:
position = player_choice(theBoard, p1_name, p1_choice)
else:
position = CompAI(theBoard, p1_name, p1_choice)
print(f'\n{p1_name} ({p1_choice}) has placed on {position}\n')
#Replacing the ' ' at *position* to *p1_choice* in *theBoard* list;
place_marker(theBoard, available, p1_choice, position)
#To check if Player 1 has won after the current input;
if win_check(theBoard, p1_choice):
display_board(theBoard, available)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
if(mode):
print(f'\n\nCONGRATULATIONS {p1_name}! YOU HAVE WON THE GAME!\n\n')
else:
print('\n\nTHE Computer HAS WON THE GAME!\n\n')
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
play_game = False
else:
#To check if the board is full; if yes, the game is a draw;
if full_board_check(theBoard):
display_board(theBoard, available)
print("~~~~~~~~~~~~~~~~~~")
print('\nThe game is a DRAW!\n')
print("~~~~~~~~~~~~~~~~~~")
break
#If none of the above is possible, next turn of Player 2;
else:
turn = p2_name
############################
#PLAYER2
elif turn == p2_name:
#Displaying the board;
display_board(theBoard, available)
#Position of the input;
if(mode == 1):
position = player_choice(theBoard, p2_name, p2_choice)
else:
position = CompAI(theBoard, p2_name, p2_choice)
print(f'\n{p2_name} ({p2_choice}) has placed on {position}\n')
#Replacing the ' ' at *position* to *p2_choice* in *theBoard* list;
place_marker(theBoard, available, p2_choice, position)
#To check if Player 2 has won after the current input;
if win_check(theBoard, p2_choice):
display_board(theBoard, available)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
if(mode):
print(f'\n\nCONGRATULATIONS {p2_name}! YOU HAVE WON THE GAME!\n\n')
else:
print('\n\nTHE Computer HAS WON THE GAME!\n\n')
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
play_game = False
else:
#To check if the board is full; if yes, the game is a draw;
if full_board_check(theBoard):
display_board(theBoard, available)
print("~~~~~~~~~~~~~~~~~~")
print('\nThe game is a DRAW!\n')
print("~~~~~~~~~~~~~~~~~~")
break
#If none of the above is possible, next turn of Player 2;
else:
turn = p1_name
#If the users want to play the game again?
if replay():
#if Yes;
continue
else:
#if No;
break
####################################################################################
print("\n\n\t\t\tTHE END!")
#END