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")
Related
I am trying to recreate the card game "War" in python and cant figure out how to loop the code under the comment until every value in the list is gone. So basically the code generates a shuffled deck of cards and pops the cards from the list. I want to have the code repeat until all the cards have been popped from the deck and I have no idea how to do that.
import random
def shuffled_deck():
deck = list(range(2, 15)) *4
random.shuffle(deck)
return deck
userdeck = shuffled_deck()
print("welcome to War!")
user1 = input("Player-1 name: ")
user2 = input("Player-2 name: ")
u1points = 0
u2points = 0
drawturns = 0
# - I want to loop the segment of code under this comment
usercard = userdeck.pop()
u1card = usercard
print(user1 + ": " + str(u1card))
usercard = userdeck.pop()
u2card = usercard
print(user2 + ": " + str(u2card))
if u1card > u2card:
print(str(u1card) + " is greater than " + str(u2card) + ".")
print(user1 + " won this round.")
u1points +=1
elif u2card > u1card:
print(str(u2card) + " is greater than " + str(u1card) + ".")
print(user2 + " won this round.")
u2points +=1
else:
print("It's a draw, try again.")
while u1card == u2card:
drawturns +=1
usercard = userdeck.pop()
u1card = usercard
print(user1 + ": " + str(u1card))
usercard = userdeck.pop()
u2card = usercard
print(user2 + ": " + str(u2card))
if u1card > u2card:
print(str(u1card) + " is greater than " + str(u2card) + ".")
print(user1 + " won this round.")
u1points +=1
u1points + drawturns
elif u2card > u1card:
print(str(u2card) + " is greater than " + str(u1card) + ".")
print(user2 + " won this round.")
u2points +=1
u1points + drawturns
else:
print("It's a draw, try again.")
if u1card == u2card == False:
drawturns = 0
break
You can do:
while len(userdeck)>0:
or, you can write smartly as:
while userdeck:
This is because an empty list is considered as False, whereas a non empty list is considered as True. So, when userdeck is empty, while loop will assume it to be False case, so the loop will stop. This same concept can also be applied for if statements.
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 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
I recently created a tic tac toe game with the min-max function. However, I keep getting an error for stack overflow and recursion depth. How would you optimize this such as that it does not happen. I created the Tic Tac Toe game initially. Then I included the min-max algorithm. If there anyway to make the code faster or optimize the function. This would really help thanks
board = ["."] * 9
wining_comb = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[3,4,6],[0,4,8]]
game = True
key = {
"x": 1,
"O":-1,
}
def new_board():
print (board[0] + "|" + board[1] + "|" + board[2])
print (board[3] + "|" + board[4] + "|" + board[5])
print (board[6] + "|" + board[7] + "|" + board[8])
new_board()
def wining(comb):
global game
for l in range(len(wining_comb)):
a = wining_comb[l][0]
f = wining_comb[l][1]
v = wining_comb[l][2]
if comb[a] == comb[f] == comb[v] == "O" or "x" == comb[a] == comb[f] == comb[v]:
game = False
return a
break
else:
game = True
break
def minmax(board,depth, ismax):
if wining(board) != None:
score = key[wining(board)]
return score
else:
if ismax == True:
bestscore = float('-inf')
for k in range(len(board)):
if board[k] == ".":
board[k] == "x"
score = minmax(board,depth+1,False)
board[k] == '.'
bestscore = max(bestscore, score)
return bestscore
else:
bestscore = float('inf')
for k in range(len(board)):
if board[k] == ".":
board[k] == "O"
score = minmax(board,depth+1,True)
board[k] == '.'
bestscore = min(bestscore,score)
return bestscore
def player1() :
bestscore = float('inf')
bestmove = 0
for k in range(len(board)):
if board[k] == ".":
board[k] == "x"
score = minmax(board,0, False)
board[k] == "."
if score > bestscore:
bestscore = score
bestmove = k
board[bestmove] = "x"
new_board()
def player2():
number = int(input("Please enter your poistion?") )
board[number - 1 ] = "O"
new_board()
wining(board)
while game==True:
player1()
player2()
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")