I am making a tic-tac-toe program in python.
I have two questions:
How to create a trick to terminate the move() when we have created a diagonal or a line(xxx or OOO) in the game.
In my program some error is occurring::in line 28::(UnboundLocalError: local variable 'stop' referenced before assignment)
My code is::
import random
board = {"top-l":" ","top-m":" ","top-r":" ","mid-l":" ","mid-m":" ","mid-r":" ","low-l":" ","low-m":" ","low-r":" "}
def print_board(board):
print( board["top-l"] + "|" + board["top-m"] + "|" + board["top-r"])
print("--------")
print( board["mid-l"] + "|" + board["mid-m"] + "|" + board["mid-r"])
print("--------")
print( board["low-l"] + "|" + board["low-m"] + "|" + board["low-r"])
if random.randint(0,1) == 1:
turn = "X"#user
else:
turn = "O"# computer
def instructions():
print("TYPE top FOR TOP ROW, mid FOR MIDDLE ROW AND low FOR LOWEST ROW")
print(" ")
print("TYPE -l FOR LEFT CORNER, -m FOR MIDDLE CORNER AND -r FOR RIGHT CORNER")
print(" ")
print("SO COMMAND FOR TOP RIGHT CORNER SHOULD BE top-r ")
print("AN EMPTY BOARD LOOKS LIKE::")
print_board(board)
def move():
for i in range(10):
print_board(board)
print("CHANCE NO. " + str(i))
if turn == "O":
if i == 1:
print("COMPUTER WILL TAKE THE FIRST TURN(FOR " + turn + ")")
else:
print("IT'S COMPUTER TURN NOW")
y = random.randint(0,9)
move = str(board_list[y])
elif turn == "x":
if i == 1:
print("USER WILL TAKE THE FIRST TURN(FOR " + turn + "). PLEASE ENTER YOUR MOVE")
else:
print("IT'S USERS TURN NOW. PLEASE ENTER YOUR MOVE")
move = input()
print("STEP TAKEN IS ::" + move)
board["move"] = turn
if turn == "x":
tu = 0
turn = "O"
elif turn == "O":
tu = 1
turn = "X"
if board["top-l"] == board["top-m"] == board["top-r"] or board["mid-l"] == board["mid-m"] == board["mid-r"] or board["low-l"] == board["low-m"] == board["low-r"] or board["mid-l"] == board["top-l"] == board["low-l"] or board["mid-m"] == board["top-m"] == board["low-m"] or board["mid-r"] == board["top-r"] == board["low-r"] or board["top-l"] == board["mid-m"] == board["low-r"] or board["top-r"] == board["mid-m"] == board["low-l"]:
stop = 1
else:
stop = 0
if __name__ == "__main__":
board_list = list(board.keys())
tu = int(0)# 0 for computer
# 1 for user
stop = int(0)# 0 = continue
print("PRESENTING YOU TIC-TAC-TOE GAME v1.0 BY DK SHARAMA")
print("PLEASE ENTER YOUR NAME::")
user = str(input())
print("WELCOME " + user)
instructions()
print("TO PLAY PRESS 1 ELSE 0")
play = int(input())
if play == 1:
move()
if stop == 1:
print("GAME OVER")
if tu == 0:
print("COMPUTER WON")
elif tu == 1:
print("USER WON")
elif stop == 0:
print("IT'S A TIE :: NO ONE WON")
Related
I am trying to code a simple coinflip game with a gambling function. My issue is, whenever it runs, it doesn't update the balance variable. Any suggestions?
import random
balance = 10
win = "Congrats! You have won "
lose = "That's too bad, you lost this time! You now have "
start_game = False
while True:
choice = input("Please use one of these commands 'flip', 'balance', or 'end game'. ")
if choice == "flip":
start_game = True
break
elif choice == "balance":
print(balance)
elif choice == "end game":
break
else:
print("Please use one of the listed commands!")
if start_game == True:
while True:
result = random.randint(1,2)
if result == 1:
result = True
elif result == 2:
result = False
gamble_amount = input("How much would you like to flip? You have " + str(balance) + " coins. ")
if str(gamble_amount) == "balance":
print(balance)
elif int(gamble_amount) <= int(balance) and result == True:
int(gamble_amount) * 2
int(balance) + int(gamble_amount)
print(win + str(gamble_amount) + "!" + " You now have " + str(balance) + "!")
elif int(gamble_amount) <= int(balance) and result == False:
int(balance) - int(gamble_amount)
print(lose + str(balance) + " coins!")
I am building a Tic Tac Toe AI. Here are the rules for the AI:
If there is a winning move, play it.
If the opponent has a winning move, block it.
Otherwise, play randomly.
Here's the code:
# main.py
# Prorities:
# - If there is a winning move, play it
# - If the opponent has a winning move, block it.
# - If nothing to block, make a random move.
import random
import time
import copy
boxes = []
for i in range(3):
row = []
for j in range(3):
row.append(" ")
boxes.append(row)
def printBoard():
to_print = ""
to_print += " " + boxes[0][0] + " | " + boxes[0][1] + " | " + boxes[0][2] + " \n"
to_print += "---+---+---\n"
to_print += " " + boxes[1][0] + " | " + boxes[1][1] + " | " + boxes[1][2] + " \n"
to_print += "---+---+---\n"
to_print += " " + boxes[2][0] + " | " + boxes[2][1] + " | " + boxes[2][2] + " \n"
return to_print
turn = random.randint(1, 2)
if turn == 1:
coin = "you (X)"
else:
coin = "the AI (O)"
print("The coin flip shows", coin, "will go first!")
input("Press Enter to begin! ")
def checkWin(boxes):
win = False
who = " "
for i in range(3):
if boxes[i][0] == boxes[i][1] and boxes[i][1] == boxes[i][2]:
who = boxes[i][0]
if who != " ":
win = True
for i in range(3):
if boxes[0][i] == boxes[1][i] and boxes[2][i] == boxes[1][i]:
who = boxes[0][i]
if who != " ":
win = True
if boxes[0][0] == boxes[1][1] and boxes[1][1] == boxes[2][2]:
who = boxes[0][0]
if who != " ":
win = True
if boxes[0][2] == boxes[1][1] and boxes[1][1] == boxes[2][0]:
who = boxes[0][2]
if who != " ":
win = True
return win, who
def checkTie(boxes):
for row in boxes:
for box in boxes:
if box != "X" and box != "O":
return False
return True
def checkMove(boxes, player):
for i in range(3):
for j in range(3):
if boxes[i][j] != "X" and boxes[i][j] != "O":
boxCopy = copy.deepcopy(boxes)
boxCopy[i][j] = player
win, who = checkWin(boxCopy)
if win:
return True, i, j
return False, 0, 0
while True:
print("Check 1")
win, who = checkWin(boxes)
if win and who == "X":
print("Player X has won.")
print(" ")
print(printBoard())
break
elif win and who == "O":
print("Player O has won.")
print(" ")
print(printBoard())
break
elif checkTie(boxes) == True:
print("It has been concluded as a tie.")
break
print("Check 2")
if turn == 1:
print("")
print(printBoard())
row = (int(input("Pick a row to play: ")) -1)
col = (int(input("Pick a column to play: ")) -1)
if ((row < 4 and row > -1) and (col < 4 and col > -1)) and (boxes[row][col] == " "):
boxes[row][col] = "X"
turn = 2
else:
print("Sorry, that is not allowed.")
print(" ")
# Prorities:
# - If there is a winning move, play it
# - If the opponent has a winning move, block it.
# - If nothing to block, make a random move.
else:
print("")
print(printBoard())
print("[*] AI is choosing...")
time.sleep(1)
row = random.randint(0, 2)
col = random.randint(0, 2)
winMove, winRow, winCol = checkMove(boxes, "O")
lossMove, lossRow, lossCol = checkMove(boxes, "X")
if winMove and (boxes[winRow][winCol] != "X" and boxes[winRow][winCol] != "O"):
boxes[winRow][winCol] = "O"
turn = 1
print("Statement 1: Win play")
elif lossMove and (boxes[lossRow][lossCol] != "X" and boxes[lossRow][lossCol] != "O"):
boxes[lossRow][lossCol] = "O"
turn = 1
print("Statement 2: Block play")
elif boxes[row][col] != "X" and boxes[row][col] != "O":
boxes[row][col] = "O"
turn = 1
print("Statement 3: Random play")
else:
print("Statement 4: None")
print("Check 3")
The problem occurs when there is a tie. Either the function checkTie(), or the if statement isn't working. You might see a couple print('Check #') every once in a while. When you run the code and it's a tie, it shows all the checks going by. Which means it is passing through the check. When there is a tie, it just keeps doing the loop and repeating its turn but not making a move.
What is the mistake and how can I do this correctly?
I think your function should be
def checkTie(boxes):
for row in boxes:
for box in row:
if box != "X" and box != "O":
return False
return True
You mistyped ( I think) boxes for row in the second for statement.
def checkTie(boxes):
if any(" " in box for box in boxes):
return False
return True
Change your checkTie function to this
The rest is all good.
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()
I am a first semester student and I am trying to restart my game. Problem is I dont really know how even though the game works fine. I assumed the solution would be to call the function play() again but for the life of me im stuck!
Tried creating a while loop to try and loop the game while still playing
while playing == True:
play()
continue_play = input("Continue playing? (y/n)")
if continue_play.lower() == "n":
playing = False
else:
new_game = play()
show_board()
new_game()
This is the while loop....new game returns 'nonetype' not callable....
below is my actual code for entire game:
playing = True
#Global variables to be used
game_active = True
champion = None
active_player = " X "
#Displays board
def show_board():
print(" 1 2 3")
print("1 " + board[0] + " | " + board[1] + " | " + board[2])
print(" ----+-----+----")
print("2 " + board[3] + " | " + board[4] + " | " + board[5])
print(" ----+-----+----")
print("3 " + board[6] + " | " + board[7] + " | " + board[8])
#play game of TIC TAC TOE
def play():
global board
board = [" ", " ", " ",
" ", " ", " ",
" ", " ", " "]
#display the game board to users
show_board()
#while game is still active
while game_active:
#Whos turn is it?
turns(active_player)
#check if game has met finishing requirements
check_game_done()
#Change player turn
change_player()
#game has ended
if champion == " X " or champion == " O ":
print(champion + " Is the winner!")
elif champion == None:
print(" Draw ")
#function for handling player turns
def turns(player):
print(player + "'s Turn.")
player_position = input("Please choose a number for your move between 1-9: ")
ok = False
while not ok:
while player_position not in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]:
player_position = input(" Please choose a number for your move between 1-9: ")
player_position = int(player_position) - 1
if board[player_position] == " ":
ok = True
else:
print("Sorry this spot is taken.")
board[player_position] = player
show_board()
#function to check over game to see if game completed
def check_game_done():
check_win()
check_draw()
def check_win():
#using global variable from above code
global champion
#rows
winning_row = check_rows()
#columns
winning_column = check_columns()
#diagonals
winning_diagonal = check_diagonals()
if winning_row:
#winner found
champion = winning_row
elif winning_column:
#winner found
champion = winning_column
elif winning_diagonal:
#winner found
champion = winning_diagonal
else:
#no winner found
champion = None
def check_rows():
#call global variable to check if game still active
global game_active
#check rows for winning condition
row1 = board[0] == board[1] == board[2] != " "
row2 = board[3] == board[4] == board[5] != " "
row3 = board[6] == board[7] == board[8] != " "
#winning conditions met?
if row1 or row2 or row3:
game_active = False
#who won?
if row1:
return board[0]
elif row2:
return board[3]
elif row3:
return board[6]
else:
return None
def check_columns():
#call global variable to check if game still active
global game_active
#check columns for winning condition
column1 = board[0] == board[3] == board[6] != " "
column2 = board[1] == board[4] == board[7] != " "
column3 = board[2] == board[5] == board[8] != " "
#Win conditions met
if column1 or column2 or column3:
game_active = False
#who won
if column1:
return board[0]
elif column2:
return board[1]
elif column3:
return board[3]
else:
return None
def check_diagonals():
#call global variable to check if game still active
global game_active
#check diagonals for winning condition
diagonal_1 = board[0] == board[4] == board[8] != " "
diagonal_2 = board[2] == board[4] == board[6] != " "
#win conditon met
if diagonal_1 or diagonal_2:
game_active = False
#who won
if diagonal_1:
return board[0]
elif diagonal_2:
return board[2]
else:
return None
# Checking to see if conditions for a draw have been met
def check_draw():
global game_active
if " " not in board:
game_active = False
return True
else:
return False
# Using function to decide whos turn it is
def change_player():
global active_player
if active_player == " X ":
active_player = " O "
elif active_player == " O ":
active_player = " X "
return None
# Restarting game again
while playing == True:
play()
continue_play = input("Continue playing? (y/n)")
if continue_play.lower() == "n":
playing = False
else:
new_game = play()
show_board()
new_game()
play()
Change the while loop to:
...
while playing == True:
play()
continue_play = input("Continue playing? (y/n)")
if continue_play.lower() == "n":
playing = False
else:
game_active = True
champion = None
play()
show_board()
...
Now it will work.
In spite of seeing a lot of posts about the python indentation error and trying out a lot of solutions, I still get this error:
import random
import copy
import sys
the_board = [" "]*10
def printboard(board):
print(board[7] + " " + "|" + board[8] + " " + "|" + board[9])
print("--------")
print(board[4] + " " + "|" + board[5] + " " + "|" + board[6])
print("--------")
print(board[1] + " " + "|" + board[2] + " " + "|" + board[3])
def choose_player():
while True:
player = input("What do you want to be; X or O?")
if player == "X":
print("You chose X")
comp = "O"
break
elif player == "O":
print("You chose O")
comp = "X"
break
else:
print("Invalid Selection")
continue
return [player, comp]
def virtual_toss():
print("Tossing to see who goes first.....")
x = random.randint(0,1)
if x== 0:
print("AI goes first")
move = "comp"
if x == 1:
print("Human goes first")
move = "hum"
return move
def win(board,le):
if (board[7] == le and board[8] == le and board[9]==le) or (board[4] == le and board[5]==le and board[6] == le)or (board[1] == le and board[2]==le and board[3] == le)or (board[7] == le and board[5]==le and board[3] == le)or (board[9] == le and board[5]==le and board[1] == le)or (board[7] == le and board[4]==le and board[1] == le)or (board[8] == le and board[5]==le and board[2] == le)or (board[9] == le and board[6]==le and board[3] == le):
return True
else:
return False
def make_move(board,number,symbol):
board[number] = symbol
def board_full(board):
count = 0
for item in board:
if item in ["X","O"]:
count+= 1
if count ==9 :
return True
else:
return False
def valid_move(board,num):
if board[num] == " ":
return True
else:
return False
def player_move(board):
number = int(input("Enter the number"))
return number
def copy_board(board):
copied_board = copy.copy(board)
return copied_board
def check_corner(board):
if (board[7] == " ") or (board[9] == " ") or (board[1] == " ") or (board[3] == " "):
return True
else:
return False
def check_center(board):
if (board[5] == " "):
return True
else:
return False
while True:
count = 0
loop_break = 0
print("welcome to TIC TAC TOE")
pla,comp = choose_player()
turn = virtual_toss()
while True:
printboard(the_board)
if turn == "hum":
if board_full() == True:
again = input ("Game is a tie. Want to try again? Y for yes and N for No")
if again == "Y":
loop_break = 6
break
else:
system.exit()
if loop_break == 6:
continue
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
else:
turn = "comp"
printboard(the_board)
continue
else:
if board_full() == True:
again = input ("Game is a tie. Want to try again? Y for yes and N for No")
if again == "Y":
loop_break = 6
break
else:
system.exit()
if loop_break = 6:
continue
copy_board(the_board)
for i in range(0,9):
make_move(copied_board,i,pla)
if(win(copied_board,pla) == True):
make_move(the_board,comp)
turn = "hum"
loop_break = 1
break
else:
continue
if loop_break = 1:
continue
if (check_corner(the_board) == True) or (check_center(the_board)==True):
for i in [7,9,1,3,5]:
if(valid_move(copied_board,i)==True):
make_move(copied_board,i,comp)
if(win(copied_board,comp)==True):
make_move(the_board,i,comp)
print("The AI beat you")
loop_break = 2
count = 1
break
else:
make_move(the_board,i,comp)
turn = "hum"
loop_break = 3
break
if loop_break == 2:
break
elif loop_break == 3:
continue
else:
for i in [8,4,6,2]:
if(valid_move(copied_board,i)==True):
make_move(copied_board,i,comp)
if(win(copied_board,comp)):
make_move(the_board,i,comp)
print("The AI beat you")
count = 1
loop_break = 4
break
else:
make_move(the_board,i,comp)
turn = "hum"
loop_break = 5
break
if loop_break == 4:
break
elif loop_break == 5:
continue
if count == 1:
again = input("Would you like to play again? y/n")
if again == "y":
continue
else:
system.exit()
I know that this is quite a long code, but I will point out the particular area where the error lies. You see, I am getting the following error message:
Traceback (most recent call last):
File "python", line 106
if (win(the_board,pla) == True):
^
IndentationError: unindent does not match any outer indentation level
More specifically, this part of the code:
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
Any help? I cannot get the code to work by any means!!
Try unindenting the previous seven lines of code by one level (the code in that while loop). This should make the indents work correctly. Also, it seems that there is an extra space before the if statement that is causing you errors. Remove this space as well. This would make that part of the code like this:
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
You need to indent the block under while (True): consistently. E.g.:
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break
else:
turn = "comp"
printboard(the_board)
continue
The problem is, the if statement is one indentation back from the rest of the code. You want to align all the code and the error should go away.
while True:
number = player_move(the_board)
if (valid_move(the_board,number) == True) and not(board_full == False):
make_move(the_board,number,pla)
break
else:
print("Invalid Move, try again!")
continue
if (win(the_board,pla) == True):
print ("Yay, you won!!!")
printboard(the_board)
count = 1
break