Skip to content

Commit 679ea24

Browse files
authored
TicTacToe game
1 parent 6311956 commit 679ea24

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

TicTacToe.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Tic Tac Toe
2+
3+
import random
4+
5+
def drawBoard(board):
6+
# This function prints out the board that it was passed.
7+
8+
# "board" is a list of 10 strings representing the board (ignore index 0)
9+
print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
10+
print('-----------')
11+
print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
12+
print('-----------')
13+
print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
14+
15+
def inputPlayerLetter():
16+
# Lets the player type which letter they want to be.
17+
# Returns a list with the player's letter as the first item, and the computer's letter as the second.
18+
letter = ''
19+
while not (letter == 'X' or letter == 'O'):
20+
print('Do you want to be X or O?')
21+
letter = input().upper()
22+
23+
# the first element in the tuple is the player's letter, the second is the computer's letter.
24+
if letter == 'X':
25+
return ['X', 'O']
26+
else:
27+
return ['O', 'X']
28+
29+
def whoGoesFirst():
30+
# Randomly choose the player who goes first.
31+
if random.randint(0, 1) == 0:
32+
return 'computer'
33+
else:
34+
return 'player'
35+
36+
def playAgain():
37+
# This function returns True if the player wants to play again, otherwise it returns False.
38+
print('Do you want to play again? (yes or no)')
39+
return input().lower().startswith('y')
40+
41+
def makeMove(board, letter, move):
42+
board[move] = letter
43+
44+
def isWinner(bo, le):
45+
# Given a board and a player's letter, this function returns True if that player has won.
46+
# We use bo instead of board and le instead of letter so we don't have to type as much.
47+
return ((bo[7] == le and bo[8] == le and bo[9] == le) or # across the top
48+
(bo[4] == le and bo[5] == le and bo[6] == le) or # across the middle
49+
(bo[1] == le and bo[2] == le and bo[3] == le) or # across the bottom
50+
(bo[7] == le and bo[4] == le and bo[1] == le) or # down the left side
51+
(bo[8] == le and bo[5] == le and bo[2] == le) or # down the middle
52+
(bo[9] == le and bo[6] == le and bo[3] == le) or # down the right side
53+
(bo[7] == le and bo[5] == le and bo[3] == le) or # diagonal
54+
(bo[9] == le and bo[5] == le and bo[1] == le)) # diagonal
55+
56+
def getBoardCopy(board):
57+
# Make a duplicate of the board list and return it the duplicate.
58+
dupeBoard = []
59+
60+
for i in board:
61+
dupeBoard.append(i)
62+
63+
return dupeBoard
64+
65+
def isSpaceFree(board, move):
66+
# Return true if the passed move is free on the passed board.
67+
return board[move] == ' '
68+
69+
def getPlayerMove(board):
70+
# Let the player type in his move.
71+
move = ' '
72+
while move not in '1 2 3 4 5 6 7 8 9'.split() or not isSpaceFree(board, int(move)):
73+
print('What is your next move? (1-9)')
74+
move = input()
75+
return int(move)
76+
77+
def chooseRandomMoveFromList(board, movesList):
78+
# Returns a valid move from the passed list on the passed board.
79+
# Returns None if there is no valid move.
80+
possibleMoves = []
81+
for i in movesList:
82+
if isSpaceFree(board, i):
83+
possibleMoves.append(i)
84+
85+
if len(possibleMoves) != 0:
86+
return random.choice(possibleMoves)
87+
else:
88+
return None
89+
90+
def getComputerMove(board, computerLetter):
91+
# Given a board and the computer's letter, determine where to move and return that move.
92+
if computerLetter == 'X':
93+
playerLetter = 'O'
94+
else:
95+
playerLetter = 'X'
96+
97+
# Here is our algorithm for our Tic Tac Toe AI:
98+
# First, check if we can win in the next move
99+
for i in range(1, 10):
100+
copy = getBoardCopy(board)
101+
if isSpaceFree(copy, i):
102+
makeMove(copy, computerLetter, i)
103+
if isWinner(copy, computerLetter):
104+
return i
105+
106+
# Check if the player could win on his next move, and block them.
107+
for i in range(1, 10):
108+
copy = getBoardCopy(board)
109+
if isSpaceFree(copy, i):
110+
makeMove(copy, playerLetter, i)
111+
if isWinner(copy, playerLetter):
112+
return i
113+
114+
# Try to take one of the corners, if they are free.
115+
move = chooseRandomMoveFromList(board, [1, 3, 7, 9])
116+
if move != None:
117+
return move
118+
119+
# Try to take the center, if it is free.
120+
if isSpaceFree(board, 5):
121+
return 5
122+
123+
# Move on one of the sides.
124+
return chooseRandomMoveFromList(board, [2, 4, 6, 8])
125+
126+
def isBoardFull(board):
127+
# Return True if every space on the board has been taken. Otherwise return False.
128+
for i in range(1, 10):
129+
if isSpaceFree(board, i):
130+
return False
131+
return True
132+
133+
134+
print('Welcome to Tic Tac Toe!')
135+
136+
while True:
137+
# Reset the board
138+
theBoard = [' '] * 10
139+
playerLetter, computerLetter = inputPlayerLetter()
140+
turn = whoGoesFirst()
141+
print('The ' + turn + ' will go first.')
142+
gameIsPlaying = True
143+
144+
while gameIsPlaying:
145+
if turn == 'player':
146+
# Player's turn.
147+
drawBoard(theBoard)
148+
move = getPlayerMove(theBoard)
149+
makeMove(theBoard, playerLetter, move)
150+
151+
if isWinner(theBoard, playerLetter):
152+
drawBoard(theBoard)
153+
print('Hooray! You have won the game!')
154+
gameIsPlaying = False
155+
else:
156+
if isBoardFull(theBoard):
157+
drawBoard(theBoard)
158+
print('The game is a tie!')
159+
break
160+
else:
161+
turn = 'computer'
162+
163+
else:
164+
# Computer's turn.
165+
move = getComputerMove(theBoard, computerLetter)
166+
makeMove(theBoard, computerLetter, move)
167+
168+
if isWinner(theBoard, computerLetter):
169+
drawBoard(theBoard)
170+
print('The computer has beaten you! You lose.')
171+
gameIsPlaying = False
172+
else:
173+
if isBoardFull(theBoard):
174+
drawBoard(theBoard)
175+
print('The game is a tie!')
176+
break
177+
else:
178+
turn = 'player'
179+
180+
if not playAgain():
181+
break
182+

0 commit comments

Comments
 (0)