List indices error in python, tic tac toe game - python

I am doing python lessons from this page.
https://inventwithpython.com/chapter10.html
I have created tic tac toe by typing all the code from above site myself
Sometimes the code works fine. Sometimes I get this error and the game crashes
Traceback (most recent call last):
File "E:\Python\tictac.py", line 139, in <module>
makeMove(theBoard, computerLetter, move)
File "E:\Python\tictac.py", line 40, in makeMove
board[move] = letter
TypeError: list indices must be integers, not NoneType
Here is my code from the game which i typed
import random
def drawBoard(board):
#this functions printts the board
print(' | |')
print(' ' + board[7] + '| ' + board[8] + ' | ' + board[9])
print(' | |')
print('-----------')
print(' ' + board[4] + '| ' + board[5] + ' | ' + board[6])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[1] + '| ' + board[2] + ' | ' + board[3])
print(' | |')
def inputPlayerletter():
#lets the player type the letter which they want to be
letter = ''
while not (letter == 'X' or letter == 'O'):
print('Do you want to be X or O?')
letter = input().upper()
#first letter is users, second belongs to pc
if letter == 'X':
return['X','O']
else:
return['O','X']
def whoGoesFirst():
if random.randint(0,1) == 0:
return 'computer'
else:
return 'player'
def playAgain():
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):
#returns true if player wins
#bo is board le is letter
return((bo[7] == le and bo[5] == le and bo[6] == le) or
(bo[1] == le and bo[2] == le and bo[3] == le) or
(bo[7] == le and bo[4] == le and bo[1] == le) or
(bo[8] == le and bo[5] == le and bo[2] == le) or
(bo[9] == le and bo[6] == le and bo[3] == le) or
(bo[7] == le and bo[5] == le and bo[3] == le) or
(bo[9] == le and bo[5] == le and bo[1] == le))
def getBoardCopy(board):
dupeBoard = []
for i in board:
dupeBoard.append(i)
return dupeBoard
def isSpaceFree(board, move):
return board[move] == ' '
def getPlayerMove(board):
move = ' '
while move not in '1 2 3 4 5 6 7 8 9 '.split() or not isSpaceFree(board, int(move)):
move = input()
return int(move)
def chooseRandomMoveFromList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
def getComputerMove(board, computerLetter):
if computerLetter == 'X':
playerLetter = 'O'
else:
playerLetter = 'X'
for i in range(1,10):
copy = getBoardCopy(board)
if isSpaceFree(copy, i):
makeMove(copy, computerLetter, i)
if isWinner(copy, computerLetter):
return i
move = chooseRandomMoveFromList(board, [1,3,7,9])
if move != None:
return move
if isSpaceFree(board, 5):
return 5
return chooseRandomMoveFromList(board, [ 2,4,6,8])
def isBoardFull(board):
#return true if the board is filled
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)
print('Hooray! Yoou have won the game!')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The gaame is a tie!')
break
else:
turn = 'computer'
else:
#computer turns
move = getComputerMove(theBoard, computerLetter)
makeMove(theBoard, computerLetter, move)
if isWinner(theBoard, computerLetter):
drawBoard(theBoard)
print('The Computer has beaten you! You lose. ')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'player'
if not playAgain():
break

You should convert:
def chooseRandomMoveFromList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
to
def chooseRandomMoveFromList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
The problem is that because of the indentation you don't calculate all free positions. Instead, you check only the first candidate position if it's free and when it's not you return nothing.

Related

'str' object is not callable- tic_tac_toe- Pytnon

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.

doesn't clear the board

I'm making a game of tic tac toe and at the start and end it asks if you "would like to play a game y/n?", if you press yes it works perfectly and if you press no it says "Goodbye" and closes the program like its suppose too, however if you press "yes" just after you've played your first game it doesn't reprint the board, only gives you the one you already filled in. Is there a way to clear the board that anyone can help me with?
board = [" " for x in range(10)]
#insert letter into the board
def insertLetter(letter, pos):
board[pos] = letter
# Is that space avalible?
def spaceIsFree(pos):
return board[pos] == " "
# Prints the board
def printBoard(board):
#Board set up
print(" | |")
print(" " + board[1] + " | " + board[2] + " | " + board[3])
print(" | |")
print("-----------")
print(" | |")
print(" " + board[4] + " | " + board[5] + " | " + board[6])
print(" | |")
print("-----------")
print(" | |")
print(" " + board[7] + " | " + board[8] + " | " + board[9])
print(" | |")
def isWinner(bo, le):
#Look for winner!
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 playerMove():
#Grabs player move, cheak for valid input
run = True
while run:
move = input("Please select a position place an \"X\" (1-9): ")
try:
move = int(move)
if move > 0 and move < 10:
if spaceIsFree(move):
run = False
insertLetter("X", move)
else:
print ("Sorry, this space is already taken!")
else:
print ("Please type a number within the range!")
except:
print("Please type a number!")
def compMove():
# Computers move
possibleMoves = [x for x, letter in enumerate(board) if letter == " " and x != 0]
move = 0
#check for a possible win
for let in ["O", "X"]:
for i in possibleMoves:
boardCopy = board[:]
boardCopy[i] = let
if isWinner (boardCopy, let):
move = i
return move
#check for open corners
cornersOpen = []
for i in possibleMoves:
if i in [1,3,7,9]:
cornersOpen.append(i)
if len(cornersOpen) > 0:
move = selectRandom(cornersOpen)
return move
#check for center move
if 5 in possibleMoves:
move = 5
return move
#check for open edges
edgesOpen = []
for i in possibleMoves:
if i in [2,4,6,8]:
edgesOpen.append(i)
if len(edgesOpen) > 0:
move = selectRandom(edgesOpen)
return move
def selectRandom(li):
# Selects random numbers
import random
ln = len(li)
r = random.randrange(0,ln)
return li[r]
def isBoardFull(board):
#See if the board is full
if board.count(" ") > 1:
return False
else:
return True
def main():
print("Welcom to Tic Tac Toe!")
print ()
printBoard(board)
while not (isBoardFull(board)):
# Do a player move,
# Check if O wins
if not (isWinner(board, "O")):
playerMove()
printBoard(board)
else:
print("Sorry, O's won this time!")
break
# Check If X wins
if not (isWinner(board, "X")):
move = compMove()
if move == 0:
print("Tie Game!")
else:
insertLetter("O", move)
print("Computer placed an O in position", move ,":")
printBoard(board)
else:
print("X's won this time! Good Job")
break
# No one wins - it's a tie
if isBoardFull(board):
print ("Tie Game!")
while True:
# Start/Play again
replay = input ("Would you like to play a game? y/n: ")
if replay == "no":
print ("Goodbye")
break
else:
print()
main()
You only create the board once at the top, then never reset it.
The easiest way to reset the state is simply to not save it globally. Reconfigure your code so board only exists in main, and it manually passed to every function that needs it. Then, when main exits, the board is destroyed and recreated each time that main runs.
To patch your existing code so it works though, I'd just create a function that creates a new board:
def new_board():
return [" " for x in range(10)]
Then, at the top of main, reset it:
def main():
global board
board = new_board()
print("Welcom to Tic Tac Toe!")
print ()
printBoard(board)
I can't recommend this in the long-term, but it's a quick fix.
board is defined in the global scope, so calling main again won't affect it, and you'll remain with the previous data. One option is to explicitly reinitialize it:
else:
board = [" " for x in range(10)]
print()
main()

How can I resolve this loop that asks to duplicate input?

I'm still struggling with Python but it's been a good time. I keep running into this problem and unsure of how to get past it. The issue is that when I run the program, every time I make an input for the game it prompts me with another input asking if I want to play again. When I input yes, it goes forward with the program but after every line after it keeps asking me if I want to play again while I'm already in the process of playing the game. Is there something I've missed because when I compare it to the original code I have it matched in the same way as far as I'm aware. If someone has seen something I've missed or have run into the error before please let me know. Thank you!
import random
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():
# Lets 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 list is the player's letter, the second is the compiuter'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 the 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 their 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 the 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 their 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)
print('Hooray! You have won the game!')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
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.')
gameisPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'player'
if not playAgain():
break```
The problem lies in the second while loop.
while gameIsPlaying:
if turn == 'player':
# Player's turn.
drawBoard(theBoard)
move = getPlayerMove(theBoard)
makeMove(theBoard, playerLetter, move)
if isWinner(theBoard, playerLetter):
drawBoard(theBoard)
print('Hooray! You have won the game!')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
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.')
gameisPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'player'
if not playAgain():
break
The loop will first call the first if statement if turn == 'player':. If this is false then the else statment will be run. Then if not playAgain() will be run. This will happen for every iteration of the loop.
Changing the indentation so that the final if statement is not included in the while gameIsPlaying loop should fix the problem.

After providing move in python code for tic tac toe, letter is not drawn on board

not able to proceed further after providing move number in Python code for tic tac toe. It asks for next move then cell number is provided but makeMove() method is not getting executed. It will ask again next move till dont press enter key twice. Please help me to resolve this code.
#Tic Tac Toe
import random
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():
# Lets the player type which letter they want to be.
#
letter = ''
while not (letter == 'X' or letter == 'O'):
#print('Do you want to be X or O?')
#letter = input().upper()
letter = (raw_input("Do you want to be X or O? ")).upper()
print "Received input is : ", letter.upper()
#
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():
print('Do you want to play again? (yes or no)')
return raw_input().lower().startswith('y')
def makeMove(board, letter, move):
board[move] = letter
def isWinner(bo, le):
#
#
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 their 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 = raw_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 their 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':
#
drawBoard(theBoard)
move = getPlayerMove(theBoard)
if isWinner(theBoard, playerLetter):
drawBoard(theBoard)
print('Hooray! You have won the game!')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'computer'
else:
#
move = getComputerMove(theBoard, computerLetter)
makeMove(theBoard, computerLetter, move)
if isWinner(theBoard, computerLetter):
drawBoard(theBoard)
print('The computer has beaten you! You lose.')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'player'
if not playAgain():
break
Output :
Welcome to Tic Tac Toe!
Do you want to be X or O? x
Received input is : X
The computer will go first.
| |
O | |
| |
| |
| |
| |
| |
| |
| |
What is your next move? (1-9)
5
| |
O | |
| |
| |
| |
| |
| |
O | |
| |
What is your next move? (1-9)
5
| |
O | |
| |
| |
O | |
| |
| |
O | |
| |
The computer has beaten you! You lose.
Do you want to play again? (yes or no)
Replace input() call with raw_input() in getPlayerMove function.
Your code doesn't work, because input() is an equivalent to eval(raw_input()). If user puts a number then input returns an integer value. That means move not in '1 2 3 4 5 6 7 8 9'.split() is always False

Python How to keep score in a tic tac toe game

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.

Categories

Resources