I am a complete beginner with Python and coding in general. I am making a Tic Tac Toe game in Python as part of the online course I am studying.
I've struggled with getting my head around the nitty gritty of how functions work and can be utilised. I have had to follow the course notes quite closely to try and understand what is happening once the code starts fitting together. Can't find similar problems on here so it can't be an issue with the course notes!
When I run the programme, it skips my position_choice() function, displays the empty board and then asks to replay. I feel I'm missing some basic issue like indentation, but would really appreciate if anyone is able to spot a problem with the function itself or the code set up? It follows the course notes structure almost identically and I'm at a loss!
Here are the functions:
from IPython.display import clear_output
import random
def display_board(board):
clear_output()
print(' ' + board[7] + ' ' + '|' + ' ' + board[8] + ' ' + '|' + ' ' + board[9] + ' ')
print('- - - - - -')
print(' ' + board[4] + ' ' + '|' + ' ' + board[5] + ' ' + '|' + ' ' + board[6] + ' ')
print('- - - - - -')
print(' ' + board[1] + ' ' + '|' + ' ' + board[2] + ' ' + '|' + ' ' + board[3] + ' ')
def player_choice():
player1 = input('Choose your marker: '.upper())
while True:
if player1.upper() == 'X':
player2 = 'O'
print('\nPlayer 1 is ' + player1.upper() + '\nPlayer 2 is ' + player2 + '.')
return player1.upper(), player2
elif player1.upper() == 'O':
player2 = 'X'
print('\nPlayer 1 is ' + player1.upper() + '\nPlayer 2 is ' + player2 + '.')
return player1.upper(), player2
else:
print('Sorry, that is not a valid marker. Please choose either O or X.')
player1 = input('Choose your marker: '.upper())
def place_marker(board, marker, position):
board[position] = marker
def win_check(position, mark):
return ((position[7] == position[8] == position[9] == mark)
or (position[4] == position[5] == position[6] == mark)
or (position[1] == position[2] == position[3] == mark)
or (position[1] == position[5] == position[9] == mark)
or (position[7] == position[5] == position[3] == mark)
or (position[7] == position[4] == position[1] == mark)
or (position[8] == position[5] == position[2] == mark)
or (position[9] == position[6] == position[3] == mark))
def choose_first():
rand_int = random.randint(1,2)
if rand_int == 1:
print('Player 1 goes first')
return '1'
if rand_int == 2:
print('Player 2 goes first')
return '2'
def space_check(board, position):
return board[position] == ' '
def full_board_check(board):
for position in range(1,10):
if space_check(board, position):
return False
return True
def position_choice(board):
position = 0
while position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position):
position = int(input('Please choose your position: '))
return position
def replay():
return input('Do you want to play again?').lower().startswith('y')
def play_game():
play_game = input('Do you want to play?')
if play_game.lower()[0] == 'y':
return True
else:
return False
And here's the programme code. Why does it just display the empty board, skip asking for the position, and ask for the replay? Any help would keep up my stalling motivation!!
print('Welcome to Tic Tac Toe!')
while play_game():
theboard = [' '] * 10
player1_marker, player2_marker = player_choice()
turn = choose_first()
if turn == 1:
display_board(theboard)
position = position_choice(theboard)
place_marker(theboard, player1_marker, position)
if win_check(theboard, player1_marker):
display_board(theboard)
print('Player 1 is the winner!')
replay()
else:
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
replay()
else:
turn == 2
else:
display_board(theboard)
position = position_choice(theboard)
place_marker(theboard, player2_marker, position)
if win_check(theboard, player2_marker):
display_board(theboard)
print('Player 2 is the winner!')
replay()
else:
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
replay()
else:
turn == 1
if not replay():
break
There are several problems :
The choose_first returns a String instead of an integer.
The method called in the while, always ask if you want to play.
You recreate a new board on each loop, you have to declare it before the loop if you don't want to lose it.
At the end of each loop you ask each times if you want to replay
to change the turn variable you should do turn = 2 instead of using double equals witch is comparing equality.
And when you want to "replay", don't forget to reset the board.
To debug this, you should comment a part of your code. And run it step by step. By doing this, you will find were are the errors.
Here is the code, the game will works but you may still want to ad some improvements.
theboard = [' '] * 10
if play_game():
player1_marker, player2_marker = player_choice()
turn = choose_first()
while not full_board_check(theboard):
display_board(theboard)
position = position_choice(theboard)
if turn == 1:
place_marker(theboard, player1_marker, position)
if win_check(theboard, player1_marker):
display_board(theboard)
print('Player 1 is the winner!')
if replay():
theboard = [' '] * 10
else:
break
turn = 2
else:
place_marker(theboard, player2_marker, position)
if win_check(theboard, player2_marker):
display_board(theboard)
print('Player 2 is the winner!')
if replay():
theboard = [' '] * 10
else:
break
turn = 1
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
if replay():
theboard = [' '] * 10
else:
break
Why does it just display the empty board, skip asking for the position, and ask for the replay?
position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position) - this condition isn't working, the logic is wrong.
>>> theboard = [' '] * 10
>>> theboard
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
>>> position = 0
>>> position not in [1,2,3,4,5,6,7,8,9] and not space_check(theboard, position)
False
>>>
Here is one way to refactor position_choice
def position_choice(board):
#print(board)
#position = 0
valid = False
# keep asking till thay give a valid answer
while not valid:
position = int(input('Please choose your position (1-9): '))
valid = position in [1,2,3,4,5,6,7,8,9]
valid = valid and space_check(board, position)
return position
## OLD STUFF
## while position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position):
## position = int(input('Please choose your position: '))
##
## return position
Asking the user for input until they give a valid response
How to debug small programs
Related
I try to make a tic tac toe game and I get:
'str' object is not callable
as error. No idea what to do.
from IPython.display import clear_output
def display_board (board):
clear_output()
print (' ' + board [7] + '|' + board [8] + '|' + board[9])
print (' ' + board [4] + '|' + board [5] + '|' + board[6])
print (' ' + board [1] + '|' + board [2] + '|' + board[3])
def player_input():
marker = " "
while marker != "X" and marker != "O":
marker = input ('Igralec 1: izberi X ali O: ').upper()
if marker == 'X':
return ('X', 'O')
else:
return ('O', 'X')
def place_marker (board, marker, position):
board[position]= marker
def win_check (board, mark):
return ((board[1] == board[2] == board[3] == mark) or #vrsta 1
(board[4] == board[5] == board[6] == mark) or #vrsta 2
(board[5] == board[6] == board[7] == mark) or #vrsta 3
(board[8] == board[5] == board[2] == mark) or #stolpec 2
(board[9] == board[6] == board[3] == mark) or #stolpec 3
(board[7] == board[4] == board[1] == mark) or #stolpec 4
(board[3] == board[5] == board[7] == mark) or #diagonala
(board[1] == board[5] == board[9] == mark)) #diagonala
import random
def choose_first():
flip= random.randint (0,1)
if flip== 0:
return 'Igralec 1'
else:
return 'Player 2'
def space_check (board, position):
board[position] ==' '
def full_board_check (board):
for i in range (1,10):
if space_check (board, i):
return False
return True
def player_choice (board):
position= 0
while position not in [1,2,3,4,5,6,7,8,9] or not space_check (board, position):
position = int(input('Izberi pozicijo: (1-9) '))
return position
def replay():
choice = input ('Želiš še enkrat igrat (Y or N)? ')
return choice ('Y')
print (' Hello, pri tri v vrsto!')
while True:
the_board=[""] *10
player1_marker,player2_marker = player_input()
turn= choose_first()
print= (turn+ ' je prvi igralec!')
play_game= input (' Pripravljeni za igro? y or n ')
if play_game== 'y':
game_on= True
else:
game_on= False
##game time
while game_on:
#igralec 1
if turn== 'Player 1':
display_board(the_board)
position= player_choice(the_board)
place_marker(the_board,player1_marker,position)
#check if they won
if win_check(the_board,player1_marker):
display_board(the_board)
print ('Igralec 1 je zmagovalec!')
game_on = False
else:
if full_board_check(the_board):
display_board(the_board)
print ("Izanačeno!")
game_on= False
else:
turn = 'Igralec 2'
else:
#igralec 2
display_board(the_board)
position= player_choice(the_board)
place_marker(the_board,player2_marker,position)
#check if they won
if win_check(the_board,player2_marker):
display_board(the_board)
print ('Igralec 2 je zmagovalec!')
game_on = False
else:
if full_board_check(the_board):
display_board(the_board)
print ("Izanačeno!")
game_on= False
else:
turn = 'Igralec 1'
if not replay():
break
Errors are:
49 display_board(the_board)
\AppData\Local\Temp/ipykernel_10492/3794783463.py in display_board(board)
print (' ' + board [7] + '|' + board [8] + '|' + board[9])
TypeError: 'str' object is not callable
TypeError
1 print (' Hello pri tri v vrsto!')
2
3 while True:
TypeError: 'str' object is not callable
This line of code:
print= (turn+ ' je prvi igralec!')
Should be written like this:
print(turn+ ' je prvi igralec!')
You can find what goes wrong with the error description hints ;)
You have the typo = in print(), the fix would be:
print(turn + ' je prvi igralec!')
to prevent such cases install the linter, like flake8 or pylint, they could help you to improve your code. Also check the black formatting tool to improve readability.
I started an online course to learn Python, the first milestone of the course is to write a script for a tic-tac-toe. The problem occurs when I try to set up all the funcions together inside a while loop.
The tic-tac-toe game should run when the while loop is running and stop when it breaks
The while loop run when game_on is True, and should break when game_on is False, but it never breaks!
Thank you!
#Create a tic tac toe game for two players.
#ROADMAP: display board->player assignment->update board with player's choice->keep playing if win condition not met
#For testing
#board = ['#',' ',' ',' ',' ',' ',' ',' ',' ',' ']
#DISPLAY
from typing import Counter
def display_game(board): #can I write the print statement in one line? I coud add ,'\n', inbetween each line
print((board[7] + '|' + board[8] + '|' + board[9]))
print((board[4] + '|' + board[5] + '|' + board[6]))
print((board[1] + '|' + board[2] + '|' + board[3]))
#PLAYER 1 and PLAYER 2 ASSIGNMENT
def player_assign():
marker=''
while marker != 'X' and marker != 'O':
marker = input('Player 1, select a character X or O: ')
if marker not in ('X','O'):
print('Invalid choice you dumb head!!!')
player1 = marker
if player1=='X':
player2='O'
else:
player2='X'
#MARKER PALCE CHOICE
def player1_choice():
position1 = 'Wrong1'
while position1 not in ['1','2','3','4','5','6','7','8','9']: #can use it with list(range(0,9))
position1=input('Player 1, choose a position to place marker: ')
if position1 not in ['1','2','3','4','5','6','7','8','9']:
print("Invalid choice, dick sucker")
return int(position1)
def player2_choice():
position2 = 'Wrong2'
while position2 not in ['1','2','3','4','5','6','7','8','9']:
position2=input('Player 2, choose a position to place marker: ')
if position2 not in ['1','2','3','4','5','6','7','8','9']:
print("Invalid choice Luigi")
return int(position2)
#CHOICE REPLACEMENT
def marker_replacement1(board,position1):
board[position1]='X'
return board
def marker_replacement2(board,position2):
board[position2]='O'
return board
#WIN CONDITION
#player 1 wins
def winner_player1(board):
#Check horizonatl
if board[1:4]=='X' or board[4:7]=='X' or board[7:10]=='X':
print('Player 1 WINS!')
return False
#check vertical1
elif board[1]==board[4]==board[7]=='X' or board[2]==board[5]==board[8]=='X' or board[3]==board[6]==board[9]=='X':
print('Player 1 WINS!')
return False
#check diagonal1
elif board[1]==board[5]==board[9]=='X' or board[3]==board[5]==board[7]=='X':
print('Player 1 WINS!')
return False
else:
return True #this means there is no winner yet beacuse we will assign this variable to game_on
#player 2 wins
def winner_player2(board):
#Check horizontal2
if board[1:4]=='O' or board[4:7]=='O' or board[7:10]=='O':
print('Player 2 WINS!')
return False
#check vertical2
elif board[1]==board[4]==board[7]=='O' or board[2]==board[5]==board[8]=='O' or board[3]==board[6]==board[9]=='O':
print('Player 2 WINS!')
return False
#check diagonal12
elif board[1]==board[5]==board[9]=='O' or board[3]==board[5]==board[7]=='O':
print('Player 2 WINS!')
return False
else:
return True #this means there is no winner yet beacuse we will assign this variable to game_on
#put all together
game_on = True
board = ['#',' ',' ',' ',' ',' ',' ',' ',' ',' ']
counter=0
player_assign()
while game_on: #OBS: game_on = False, the while loop doesn't break, Why?
#Displays the game
display_game(board)
#Player1 Position choice
position1 = player1_choice()
#rewrite position 1 and update game list
marker_replacement1(board,position1)
#display the updated game
display_game(board)
#keep playing?
if ' ' not in board:
game_on = False
print("It's a TIE")
game_on=winner_player1(board)
print(game_on)
#Player 2 Position choice
position2 = player2_choice()
#rewrite position 2 and update game list
marker_replacement2(board,position2)
#display the updated game
display_game(board)
#keep playing?
if ' ' not in board:
game_on=False
print("It's a TIE")
game_on=winner_player2(board)
print(game_on)
When you write game_on = False in your code, the immediately following line says
game_on=winner_player2(board)
or
game_on=winner_player1(board)
which means that game_on = False is overwritten immediately. Notice that, at least for your second call to game_on = False you have:
if ' ' not in board:
game_on=False
print("It's a TIE")
game_on=winner_player2(board)
print(game_on)
and then the loop restarts, so you could just do
if ' ' not in board:
print("It's a TIE")
break
Be careful though: break exits the while loop immediately, so make sure you call it after all other relevant code has been called. It's also possible that you mean to write
if ' ' not in board:
game_on=False
print("It's a TIE")
else:
game_on=winner_player2(board)
so this code is making a tic tac toe game and lets the users keep playing until there is a winner. However, my code is creating the array, and automatically deciding that player two is the winner. I ran it through the debugger, and it will create the array for the board, and will automatically pick player 2 the winner. I know for a fact its after the array is made, but I cannot find out why. Any help is appreciated, thanks so much.
"""tictactoe game for 2 players"""
choices = []
for x in range(1, 9):
choices.append(x)
breakpoint()
playerOneTurn = True
winner = False
def printBoard():
print('\n -----')
print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|')
print(' -----')
print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|')
print(' -----')
print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|')
print(' -----\n')
while winner:
printBoard()
if playerOneTurn:
print("Player 1:")
else:
print("Player 2:")
try:
choice = int(input(">> "))
except:
print("please enter a valid field")
continue
if choices[choice - 1] == 'X' or choices[choice] == 'O':
print("illegal move, please try again")
continue
if playerOneTurn:
choices[choice - 1] = "X"
else:
choices[choice - 1] = "O"
playerOneTurn = not playerOneTurn
for x in range(0, 3):
y = x * 3
if choices[y] == choices[(y + 1)] and choices[y] == choices[(y + 2)]:
winner = True
printBoard()
if choices[x] == choices[(x + 3)] and choices[x] == choices[(x + 6)]:
winner = True
printBoard()
if((choices[0] == choices[4] and choices[0] == choices[8]) or
(choices[2] == choices[4] and choices[4] == choices[6])):
winner = True
printBoard()
print("Player " + str(int(playerOneTurn + 1)) + " wins!\n")
I am trying to make a tic tac toe program, I set the user to be X and the computer to be Y. Once a winner is
declared it is
supposed
to start the game to play again. It runs perfectly through the loop the first time, but on the following game it
changes the user to O and the computer to O, also only the user has a turn the computer never goes,
but the program
registers the computer as winning because the computer is O . If the program chooses the computer to go first,
it will make
the first move, but it wont get a turn again. I think there is something wrong with the loop but I cant figure out
where.
import random
winningCombinations=[]
userhistory=[]
secondchance=[]
def drawBoard(board):
# This function prints out the board that it was passed.
# "board" is a list of 10 strings representing the board (ignore index 0)
print('')
print('')
print(' | |')
print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
print(' | |')
print('')
print('')
def getComputerMove():
# Here is our algorithm for our Tic Tac Toe AI:
if userhistory in winningCombinations:
#try to beat it
blockingMove = secondchance[len(secondchance)-1]
return blockingMove
else:
#make a rando move
move = random.randint(1, 9)
while theBoard[move] != ' ': #if the move is invalid or occupied
move = random.randint(1, 9)
return move
print('Welcome to Tic Tac Toe!')
#First ask the user if it wants to be X or 0
userin = ''
#while not (userin == 'X' or userin == 'O'):
# userin = raw_input('Do you want to be X or O?').upper()
# the first element in the tuple is the player's letter, the second is the computer's letter.
#if userin == 'X':
# playerLetter, computerLetter = ['X', 'O']
#elif userin =="O":
# computerLetter, playerLetter = ['O', 'X']
numGames = 1 #to keep track of the user history
#computergenerates who gets to go first
if random.randint(0, 1) == 0:
turn = 'computer'
else:
turn = 'player'
print('The ' + turn + ' will go first.')
while True:
# Reset the board
theBoard = [' '] * 10
del userhistory[:]
gameIsPlaying = True
while gameIsPlaying:
playerLetter = 'X'
computerLetter = 'O'
if turn == 'player':
# Player's turn.
drawBoard(theBoard)
umove = int(raw_input('What is your next move? (1-9)'))
while theBoard[umove] != ' ': #if the move is invalid or occupied
umove = int(raw_input('What is your next move? (1-9)'))
theBoard[umove]=playerLetter #places move onto board
userhistory.append(umove) #records users moves
secondchance.append(umove)#records users moves
#Check to see if its a winner
if ((theBoard[7] == playerLetter and theBoard[8] == playerLetter and theBoard[9] == playerLetter) or # across the top
(theBoard[4] == playerLetter and theBoard[5] == playerLetter and theBoard[6] == playerLetter) or # across the middle
(theBoard[1] == playerLetter and theBoard[2] == playerLetter and theBoard[3] == playerLetter) or # across the bottom
(theBoard[7] == playerLetter and theBoard[4] == playerLetter and theBoard[1] == playerLetter) or # down the left side
(theBoard[8] == playerLetter and theBoard[5] == playerLetter and theBoard[2] == playerLetter) or # down the middle
(theBoard[9] == playerLetter and theBoard[6] == playerLetter and theBoard[3] == playerLetter) or # down the right side
(theBoard[7] == playerLetter and theBoard[5] == playerLetter and theBoard[3] == playerLetter) or # diagonal
(theBoard[9] == playerLetter and theBoard[5] == playerLetter and theBoard[1] == playerLetter)):
drawBoard(theBoard)
print('Hooray! You have won the game!')
del userhistory[len(userhistory)-1] #deleting last element to find the combination just before losing
winningCombinations.append(userhistory) #stores the winning combination into another list
numGames+=1
gameIsPlaying = False
else:
empty = ' '
if empty not in theBoard:
print('The game is a tie!')
break
else:
turn = 'computer'
else:
# Computer's turn.
cmove = getComputerMove()
theBoard[cmove] = computerLetter
if ((theBoard[7] == computerLetter and theBoard[8] == computerLetter and theBoard[9] == computerLetter) or # across the top
(theBoard[4] == computerLetter and theBoard[5] == computerLetter and theBoard[6] == computerLetter) or # across the middle
(theBoard[1] == computerLetter and theBoard[2] == computerLetter and theBoard[3] == computerLetter) or # across the bottom
(theBoard[7] == computerLetter and theBoard[4] == computerLetter and theBoard[1] == computerLetter) or # down the left side
(theBoard[8] == computerLetter and theBoard[5] == computerLetter and theBoard[2] == computerLetter) or # down the middle
(theBoard[9] == computerLetter and theBoard[6] == computerLetter and theBoard[3] == computerLetter) or # down the right side
(theBoard[7] == computerLetter and theBoard[5] == computerLetter and theBoard[3] == computerLetter) or # diagonal
(theBoard[9] == computerLetter and theBoard[5] == computerLetter and theBoard[1] == computerLetter)):
drawBoard(theBoard)
print('Aw! You have lost the game, the computer has beaten you!')
gameIsPlaying = False
else:
empty = ' '
if empty not in theBoard:
print('The game is a tie!')
break
else:
turn = 'player'
Since you're asking for debugging advice, I'll answer at that level.
When you have a sick patient, ask where it hurts. The print command is a blunt, but effective weapon. At critical points in your code, stick in a statement such as
print "CHECKPOINT A", "turn =", turn
In other words, trace both logic flow and useful values. These statements are especially useful at the top or bottom of a block (loop or function).
Next, when you have a long block of code, consider moving some of the logic into a function. In this program, your code to detect a win would be a good candidate: you have 8 long lines of identical code you could isolate and replace with a function call.
I expect that these two will be enough to track down the problem; they handle almost all of my own failures. Rather than repeating long-standing advice, one point after another, I commend to you the blog post how to debug for further suggestions.
I need help figuring out how to calculate the record for wins, losses, and ties. Right now, the code returns the string "loss" when the player loses. I want it to return 1, for one loss. Can anyone help? Here is the code I have so far.
# Tic Tac Toe
import random
def score():
wins = 0
losses = 0
ties = 0
def result(wins, losses, ties):
if result =='win':
wins += 1
if result == 'loss':
losses += 1
else:
ties += 1
def drawBoard(board):
# This function prints out the board that it was passed.
# "board" is a list of 10 strings representing the board (ignore index 0)
print(' | |')
print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
print(' | |')
def inputPlayerLetter():
# Let's the player type which letter they want to be.
# Returns a list with the player's letter as the first item, and the computer's letter as the second.
letter = ''
while not (letter == 'X' or letter == 'O'):
print('Do you want to be X or O?')
letter = input().upper()
# the first element in the tuple is the player's letter, the second is the computer's letter.
if letter == 'X':
return ['X', 'O']
else:
return ['O', 'X']
def whoGoesFirst():
# Randomly choose the player who goes first.
if random.randint(0, 1) == 0:
return 'computer'
else:
return 'player'
def playAgain():
# This function returns True if the player wants to play again, otherwise it returns False.
print('Do you want to play again? (yes or no)')
return input().lower().startswith('y')
def makeMove(board, letter, move):
board[move] = letter
def isWinner(bo, le):
# Given a board and a player's letter, this function returns True if that player has won.
# We use bo instead of board and le instead of letter so we don't have to type as much.
return ((bo[7] == le and bo[8] == le and bo[9] == le) or # across the top
(bo[4] == le and bo[5] == le and bo[6] == le) or # across the middle
(bo[1] == le and bo[2] == le and bo[3] == le) or # across the bottom
(bo[7] == le and bo[4] == le and bo[1] == le) or # down the left side
(bo[8] == le and bo[5] == le and bo[2] == le) or # down the middle
(bo[9] == le and bo[6] == le and bo[3] == le) or # down the right side
(bo[7] == le and bo[5] == le and bo[3] == le) or # diagonal
(bo[9] == le and bo[5] == le and bo[1] == le)) # diagonal
def getBoardCopy(board):
# Make a duplicate of the board list and return it the duplicate.
dupeBoard = []
for i in board:
dupeBoard.append(i)
return dupeBoard
def isSpaceFree(board, move):
# Return true if the passed move is free on the passed board.
return board[move] == ' '
def getPlayerMove(board):
# Let the player type in his move.
move = ' '
while move not in '1 2 3 4 5 6 7 8 9'.split() or not isSpaceFree(board, int(move)):
print('What is your next move? (1-9)')
move = input()
return int(move)
def chooseRandomMoveFromList(board, movesList):
# Returns a valid move from the passed list on the passed board.
# Returns None if there is no valid move.
possibleMoves = []
for i in movesList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
def getComputerMove(board, computerLetter):
# Given a board and the computer's letter, determine where to move and return that move.
if computerLetter == 'X':
playerLetter = 'O'
else:
playerLetter = 'X'
# Here is our algorithm for our Tic Tac Toe AI:
# First, check if we can win in the next move
for i in range(1, 10):
copy = getBoardCopy(board)
if isSpaceFree(copy, i):
makeMove(copy, computerLetter, i)
if isWinner(copy, computerLetter):
return i
# Check if the player could win on his next move, and block them.
for i in range(1, 10):
copy = getBoardCopy(board)
if isSpaceFree(copy, i):
makeMove(copy, playerLetter, i)
if isWinner(copy, playerLetter):
return i
# Try to take one of the corners, if they are free.
move = chooseRandomMoveFromList(board, [1, 3, 7, 9])
if move != None:
return move
# Try to take the center, if it is free.
if isSpaceFree(board, 5):
return 5
# Move on one of the sides.
return chooseRandomMoveFromList(board, [2, 4, 6, 8])
def isBoardFull(board):
# Return True if every space on the board has been taken. Otherwise return False.
for i in range(1, 10):
if isSpaceFree(board, i):
return False
return True
print('Welcome to Tic Tac Toe!')
while True:
# Reset the board
theBoard = [' '] * 10
playerLetter, computerLetter = inputPlayerLetter()
turn = whoGoesFirst()
print('The ' + turn + ' will go first.')
gameIsPlaying = True
while gameIsPlaying:
if turn == 'player':
# Player's turn.
drawBoard(theBoard)
move = getPlayerMove(theBoard)
makeMove(theBoard, playerLetter, move)
if isWinner(theBoard, playerLetter):
drawBoard(theBoard)
result = 'win'
print('Hooray! You have won the game!')
isWinner = True
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
result = 'tie'
print('The game is a tie!')
break
else:
turn = 'computer'
else:
# Computer's turn.
move = getComputerMove(theBoard, computerLetter)
makeMove(theBoard, computerLetter, move)
if isWinner(theBoard, computerLetter):
drawBoard(theBoard)
print('The computer has beaten you! You lose.')
result = 'loss'
isWinner = False
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
result = 'tie'
print('The game is a tie!')
break
else:
turn = 'player'
if not playAgain():
print(result)
break
Instead of doing result = 'win' you could set wins = 0 at the start and when resetting, and when the player wins just do wins += 1. Do the same for ties and losses and then you can extract the complete record from a function which takes wins,losses and ties as arguments.
Your functions score() and result(wins, loses, ties) are definitely not working good.
All variables in function are local variables and because of that this code will print 10 instead of 11:
def make_bigger(x):
x += 1
X = 10
make_bigger(X)
print(x)
Instead of using that functions you may need some function like this:
def pr_score(win, lose, tie):
print('Score:')
print('\twin:', win)
print('\tlose:', lose)
print('\ttie:', tie)
For win / lose / tie counting you need to add:
win = 0
lose = 0
tie = 0
before while True:.
You should also add win += 1 in if isWinner(theBoard, playerLetter): statement and tie += 1 in if isBoardFull(theBoard): statement.
Also code about computer turns should look like this:
if isBoardFull(theBoard):
drawBoard(theBoard)
result = 'tie'
print('The game is a tie!')
else:
# Computer's turn.
move = getComputerMove(theBoard, computerLetter)
makeMove(theBoard, computerLetter, move)
turn = 'player'
if isWinner(theBoard, computerLetter):
drawBoard(theBoard)
print('The computer has beaten you! You lose.')
result = 'loss'
lose += 1
isWinner = False
gameIsPlaying = False
if isBoardFull(theBoard):
drawBoard(theBoard)
result = 'tie'
print('The game is a tie!')
break
For printing result you should add pr_score(win, lose, tie) in if not playAgain():.
If you want ability for another round last break should be more indented.
Also if you add these lines in getPlayerMove(board) after move = input():
if move not in '1 2 3 4 5 6 7 8 9'.split(): #input is incorrect
print('Input is incorrect.\nPlease write nuber!')
elif not isSpaceFree(board, int(move)): #that place isn't free
print('That place is already taken.\nPlease take free place!')
and these lines before while True:
exampleBoard = [' ']
for x in range(1, 10):
exampleBoard.append(str(x))
drawBoard(exampleBoard)
it would be helpful for user.