-
Notifications
You must be signed in to change notification settings - Fork 0
/
tictactoe.py
170 lines (153 loc) · 5.79 KB
/
tictactoe.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
# an unbeatable Tic Tac Toe program where you (X) play against the computer (O)
options = ['1','2','3','4','5','6','7','8','9']
corners = [1, 3, 7, 9]
import random
# set-up of grid, board is a list
def Board(board):
print(' | |')
print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
print('-----------')
print(' | |')
print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
print(' | |')
print('-----------')
print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
print(' | |')
# this function will help set 'X' or 'O' to the specific space on the board
def Move(board, letter, move):
board[move] = letter
def Winner(b, l):
# returns True if that player has won
# b instead of board and l instead of letter
# I calculated that there are 8 winning cases total
return ((b[7] == l and b[8] == l and b[9] == l) or
(b[4] == l and b[5] == l and b[6] == l) or
(b[1] == l and b[2] == l and b[3] == l) or
(b[7] == l and b[4] == l and b[1] == l) or
(b[8] == l and b[5] == l and b[2] == l) or
(b[9] == l and b[6] == l and b[3] == l) or
(b[7] == l and b[5] == l and b[3] == l) or
(b[9] == l and b[5] == l and b[1] == l))
def Copy(board):
# duplicate of the board list that will later help computer figure out which move to make
Board_2 = []
for i in board:
Board_2.append(i)
return Board_2
def isSpaceFree(board, move):
# returns True if the space is free on board
# if not marked by X or O, board[move] equals an empty string
return board[move] == ' '
def PlayerMove(board):
move = ' '
# if the player types in an invalid number or they type in a number they already have before, ask for their input again
while move not in options or not isSpaceFree(board, int(move)):
print('What is your next move? (1-9)')
move = input()
# important to use int function since initial input is a string and will cause an error otherwise
return int(move)
def RandomMoveFromList(board,specific_list):
# returns a valid, random move from the list of possible moves on the board
# returns None if there is no valid move
possibleMoves = []
for i in specific_list:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
def getComputerMove(board, computerLetter):
playerLetter = 'X'
# algorithm for AI (more code than PlayerMove function)
# first, check if we can win in the next move
# loop goes through the 9 options
for i in range(1, 10):
copy = Copy(board)
if isSpaceFree(copy, i):
Move(copy, computerLetter, i)
if Winner(copy, computerLetter):
return i
# check if the player could win on their next move, and block them by putting computer symbol there instead (beat them to it)
for i in range(1, 10):
copy = Copy(board)
if isSpaceFree(copy, i):
Move(copy, playerLetter, i)
if Winner(copy, playerLetter):
return i
# if player didn't occupy a corner spot during their first move, computer can move to a corner
if board[1] != 'X' and board[3] != 'X' and board[7] != 'X'and board[9] != 'X':
move = RandomMoveFromList(board, corners)
if move != None:
return move
else:
if isSpaceFree(board, 5):
return 5
# move on one of the sides.
return RandomMoveFromList(board, [2, 4, 6, 8])
def isBoardFull(board):
# returns True if every space on the board has been taken. Otherwise returns False.
for i in range(1, 10):
if isSpaceFree(board, i):
return False
return True
# start console-based game
# first, print instructions once
print('Unbeatable Tic Tac Toe game against the computer! \nYou, the player (X), will go first.\nThe computer (O) goes next.')
print('The board positions are as follows:')
print(' | |')
print(' ' + '7' + ' | ' + '8' + ' | ' + '9')
print('-----------')
print(' | |')
print(' ' + '4' + ' | ' + '5' + ' | ' + '6')
print(' | |')
print('-----------')
print(' ' + '1' + ' | ' + '2' + ' | ' + '3')
print(' | |\n\n')
Repeat = True
while Repeat:
try:
# reset the board
theBoard = [' '] * 10
playerLetter = 'X'
computerLetter = 'O'
turn = 'player'
gameIsPlaying = True
while gameIsPlaying:
if turn == 'player':
# player's turn
Board(theBoard)
move = PlayerMove(theBoard)
Move(theBoard, playerLetter, move)
if Winner(theBoard, playerLetter):
Board(theBoard)
print('You won')
Repeat = False
gameIsPlaying = False
else:
if isBoardFull(theBoard):
Board(theBoard)
print('Tie')
Repeat = False
gameIsPlaying = False
else:
turn = 'computer'
else:
# computer's turn
move = getComputerMove(theBoard, computerLetter)
Move(theBoard, computerLetter, move)
if Winner(theBoard, computerLetter):
Board(theBoard)
print('You lose')
Repeat = False
gameIsPlaying = False
else:
if isBoardFull(theBoard):
Board(theBoard)
print('Tie')
Repeat = False
gameIsPlaying = False
else:
turn = 'player'
except IndexError:
continue