Noughts And Crosses game loop iterating too many times - python

This is my noughts and crosses code i am still early on in making it and I am trying to do it as independently as possible without too much help from google- this is a simple question but why is it that when you get 3 in a row within the 2d list that the loop I have made continues to iterate one last time before ending? thanks a lot
won = False
sum = 0
for i in range (3):
if grid[i][i] == "X":
sum +=1
elif grid[i][i] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
sum = 0
for i in range (3):
if grid[row][i] == "X":
sum +=1
elif grid[row][i] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
sum = 0
for i in range (3):
if grid[i][column] == "X":
sum +=1
elif grid[i][column] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
return won
#############################main program#############################
grid = [["-","-","-"],
["-","-","-"],
["-","-","-"]]
for x in grid:
print (x)
win = False
while win == False:
print("\nCrosses\n")
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
grid[row][column] = ("X")
for x in grid: print (x)
win = checkwin(grid, row, column)
print("\nNoughts\n")
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
grid[row][column] = ("O")
for x in grid: print (x)
win = checkwin(grid, row, column)```

After your check whether last placed X made the player win, you don't exit the loop in any case (the while loop condition is only checked when an iteration starts, not all the time) - the program always continues and allows O player to move, even if win is already true. To change that behaviour, you need to break from the loop if the X player won, using break keyword. Your loop would look like this:
while win == False:
print("\nCrosses\n")
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
grid[row][column] = ("X")
for x in grid: print (x)
win = checkwin(grid, row, column)
if win:
break
print("\nNoughts\n")
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
grid[row][column] = ("O")
for x in grid: print (x)
win = checkwin(grid, row, column)

Related

TypeError: list indices must be integers or slices, not tuple (Python 3.11)

I am trying to create a noughts and crosses game in python, and I got an error in the bold text area in checkGridRow(). This is where I want to check if the game has been won by any player by checking for "XXX" or "OOO" in a horizontal row. At the end of the code, I use the parameter of "position" as the Y position in the grid and so pass 0, 1 and 2 to check all the rows. However I have run into the error in the title, and I don't know what it means despite searching, as I have no tuples in my code (as far as I can see). I am a beginner so please try to explain in relatively simple terms, thank you for helping
grid = [["_","_","_"],["_", "_", "_"],["_", "_", "_"]]
game = True
def checkGridRow(position):
n = 0
***if grid[position,n]!= "_":***
if grid[position,n]== grid[position,n+1] and grid[position,n+1]==grid[position,n+2]:
game = False
return game
def checkGridCol():
tempList = ""
c1 = [grid[0,0], grid[1,1], grid[2,2]]
c2 = [grid[2,0], grid[1,1], grid[0,2]]
if not any("_" in i for i in c1):
for var in c1:
tempList+= var
if tempList == "XXX":
game = False
elif tempList == "OOO":
game = False
return game
def PlayerTurnX():
column = int(input("enter column >> 1,2,3: "))
column = column -1
while str(column+1) not in "123":
column = int(input("enter column 1,2,3: "))
column = column-1
row = int(input("enter row >> 1,2,3: "))
row = row-1
while str(row+1) not in "123":
row = int(input("enter row >> 1,2,3: "))
row= row-1
if grid[row][column]=="_":
grid[row][column] = "X"
elif grid[row][column]!= "_":
print("Space taken")
row = int(input("enter row >> 1,2,3: "))
row = row-1
for item in grid:
print(item[0]+" "+item[1]+" "+item[2])
def PlayerTurnO():
column = int(input("enter column: >> 1,2,3: "))
column = column-1
while str(column+1) not in "123":
column = int(input("enter column >> 1,2,3: "))
row = int(input("enter row: >> 1,2,3: "))
row = row-1
while str(row+1) not in "123":
row = int(input("enter row: >> 1,2,3: "))
row = row-1
if grid[row][column]=="_":
grid[row][column] = "O"
else:
print("Space taken")
column = int(input("enter column>> 1,2,3: "))
column = column-1
n=n-1
for item in grid:
print(item[0]+" "+item[1]+" "+item[2])
while game:
print("Player X, your turn!")
PlayerTurnX()
checkGridRow(0)
checkGridRow(1)
checkGridRow(2)
checkGridCol()
print("")
print("")
print("Player O, your turn!")
PlayerTurnO()
checkGridRow(0)
checkGridRow(1)
checkGridRow(2)
checkGridCol()
I've tried searching the error message and still cannot figure out where the tuple is, as far as I know tuples look like this myTuple = (x, y, z)
grid[position,n] is not the correct syntax for accessing a nested list.
Use grid[position][n] instead.

How do I get the correct outputs for this chess board?

I am trying to make a program of a chess board, When a user inputs an x and y value it will either output "black" or "white".
x = int(input("Please enter your (x) first number 1-8::"))
y = int(input("Please enter your (y) second number 1-8::"))
column = x % 2
row = y % 2
if column %2 == 0 and row %2 == 1:
print("")
print("white")
elif row %2 ==0 and column %2 == 1:
print("")
print("black")
Whenever i input 1 for "x" and 2 for "y" it outputs "black", great this is the correct output. But whenever i input some other numbers such as 2 and 2, it gives me a blank output. Whenever i input 1 and 4, it outputs "black" which the correct output should have been "white. How do i make it so that whenever user inputs two numbers ranging from 1 to 8, it outputs the correct colour tile? I am not trying to make the code more advanced but would appreciate some help!
This is the chess board i am basing the colours on.( Do not mind the text on the picture)
Instead of looking at x and y separately, just check the sum.
If the sum is even, it's black, if the sum is odd, it is white.
I added a lookup of the name in a python dict, but you can just do it with if conditions if you prefer.
x = int(input("Please enter your (x) first number 1-8::"))
y = int(input("Please enter your (y) second number 1-8::"))
color_picker = {0: "Black", 1: "White"}
if not 0<x<9 or not 0<y<9:
print("Input valid number!!")
else:
color
print(color_picker[(x+y)%2])
Let me know if it helps.
if column %2 == 0 and row %2 == 1:
...
elif row %2 ==0 and column %2 == 1:
...
This covers the case where column is even and row is odd, and the case where row is even and column is odd.
But what about the cases where they are both even, or both odd?
x = int(input("Please enter your (x) first number 1-8::"))
y = int(input("Please enter your (y) second number 1-8::"))
column = x
row = y
if (column + row) %2 == 0:
print("")
print("black")
elif (column + row) %2 == 1:
print("")
print("white")
else:
print("Input valid number!!")

Noughts and Crosses Issue part 2

Keeping in mind I am a beginner programmer,
i've ran into another problem with my noughts and crosses code in my attempt to add functionality to not allow players to place on the same grid space more than once- however I cannot figure out why it is that when you enter a position for the first go it immediately states that you >Cannot place on a full grid space even though it is impossible for any spaces to be full.
won = False
sum = 0
for i in range (3):
if grid[i][i] == "X":
sum +=1
elif grid[i][i] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
sum = 0
for i in range (3):
if grid[row][i] == "X":
sum +=1
elif grid[row][i] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
sum = 0
for i in range (3):
if grid[i][column] == "X":
sum +=1
elif grid[i][column] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
return won
#############################main program#############################
grid = [["-","-","-"],
["-","-","-"],
["-","-","-"]]
for x in grid:
print (x)
win = False
repeat = False
while win == False:
print("\nCrosses\n")
while repeat == False:
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
if grid[row][column] == "X" or "O":
print("Cannot place on a full grid space")
else:
repeat == True
grid[row][column] = ("X")
for x in grid: print (x)
win = checkwin(grid, row, column)
if win:
break
repeat = False
print("\nNoughts\n")
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
grid[row][column] = ("O")
for x in grid: print (x)
win = checkwin(grid, row, column)```
I tried out your code and found a couple of issues that were tripping you up. Following is a revised version of your code with the corrections having a comment.
def checkwin(grid, row, column): # Added the function definition
won = False
sum = 0
for i in range (3):
if grid[i][i] == "X":
sum +=1
elif grid[i][i] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
sum = 0
for i in range (3):
if grid[row][i] == "X":
sum +=1
elif grid[row][i] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
sum = 0
for i in range (3):
if grid[i][column] == "X":
sum +=1
elif grid[i][column] == "O":
sum -=1
if sum == 3 or sum == -3:
won = True
return won
#############################main program#############################
grid = [["-","-","-"],
["-","-","-"],
["-","-","-"]]
for x in grid:
print (x)
win = False
repeat = False
while win == False:
print("\nCrosses\n")
while repeat == False:
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
if grid[row][column] == "X" or grid[row][column] == "O": # Revised the test
print("Cannot place on a full grid space")
else:
repeat = True # Removed second "=" sign
grid[row][column] = ("X")
for x in grid: print (x)
win = checkwin(grid, row, column)
if win:
break
repeat = False
print("\nNoughts\n")
column = int(input("Enter a Column\n"))
row = int(input("Enter a Row\n"))
grid[row][column] = ("O")
for x in grid: print (x)
win = checkwin(grid, row, column)
Following are the highlights.
The sample code was missing the function definition for checking for a winner so that was added.
The "if" test for empty grid positions needed to be corrected checking for not having an "X" nor having an "O".
The update of "repeat" variable only needed one "=", not "==" (that's an equality check).
After that the program seemed to play properly. Give that try.

Error in repeating input in a tictactoe game

I am trying to prevent the user from inputting a square that is already marked, but the for loop moves on to the next player's input without decrementing the value of i by one, so the player 1 can repeat his input. How do I fix this?
arr = [[0,0,0],[0,0,0],[0,0,0]]
grid = grid(arr)
grid.print_grid()
for i in range(9):
row = int(input("Enter the row name: "))
col = int(input("Enter the column name: "))
if(arr[row][col] == 0):
if(i%2):
arr[row][col] = 1
else:
arr[row][col] = 2
else:
print("\nThat square has already been marked! Please select another square")
i = i-1
continue
grid.print_grid()
res = grid.grid_checker()
if (res == 1):
print("\nPlayer 1 wins the game!")
break
elif(res == 2):
print("\nPlayer 2 wins the game!")
break
elif(i == 8):
print("\nThe game has ended in a draw!")
You need to store another variable to keep track of whose turn it is. You cannot modify the variable you are looping on while you are in the loop body. This means that i cannot be manipulated while you are running in the loop. Here's how I would change it.
turn = 0
while True:
row = int(input("Enter the row name: "))
col = int(input("Enter the column name: "))
if(arr[row][col] == 0):
if(i%2):
arr[row][col] = 1
turn = turn + 1
else:
arr[row][col] = 2
turn = turn + 1
else:
print("\nThat square has already been marked! Please select another square")
continue
grid.print_grid()
res = grid.grid_checker()
if (res == 1):
print("\nPlayer 1 wins the game!")
break
elif(res == 2):
print("\nPlayer 2 wins the game!")
break
elif(turn == 8):
print("\nThe game has ended in a draw!")
Here we're saving the turn number in the variable turn and only incrementing the variable when we can confirm a player has successfully completed their turn.
Why you cannot modify i: For optimisations, loops are often expanded by python before they are converted to assembly instructions. For example a simple loop like this:
for i in range(9):
print(i)
May be expanded to something like this:
i = 0
print(i)
i = 1
print(i)
# and so on, upto
i = 9
print(i)
This is done to avoid having to jump around in memory. So as you can see here, i is reassigned for every iteration of the loop. Therefore, even if you change the value of i in the body of the loop, it will simply be reassigned before the next iteration.

Check if condition matches in python

Having trouble figuring out my list comprehension in python. I have 3 conditions that I'm looking for, and I know how to do two of them, but one of the conditions doesn't seem to work right.
My conditions are:
If all the numbers in my list are the same and they are all a specific number, then add points
If all numbers in my list are the same but they do not equal a specific number then do something else
If numbers in list do not match, but they equal a specific number than do something else.
I have 1 working, and I know how to do number 3, but I can't get number 2 working properly. No matter what numbers I put into my list (rolls), this condition still matches True. Can someone please assist? Here is my current code:
def check_conditions(rolls, round_number):
"""
Check if number on rolled die matches one of three conditions
:param rolls:
:param round_number:
:return round:
"""
round_score = ROUND_TOTAL
rolls = str(rolls)
bunco = all(roll == ROUND_NUMBER for roll in rolls)
mini_bunco = all(roll == roll[0] and roll != ROUND_NUMBER for roll in rolls)
if bunco == True:
print("BUNCO!")
round_score += 20
elif mini_bunco == True:
print("MINI-BUNCO!")
round_score += 5
else:
pass
return round_score
OUTPUT:
Starting Round Number 1
You rolled: [2, 3, 3]
MINI-BUNCO!
Points this round: 5
Something like this should get you there...
rolls = [5,5,5,5,5,5]
specificNum = 6
if len(set(rolls)) == 1:
if rolls[0] != specificNum:
print 'Do something'
#imports
import random
#variables
Roll_1_return = False
Roll_2_return = False
round_score = ROUND_TOTAL
#assuming you only want to roll twice
def Rolls():
Roll_1 = random.randrange(1, 10)
Roll_2 = random.randrange(1, 10)
While True:
if Roll_1 == 3:
Roll_1_return = True
return Roll_1_return
break
else:
break
While True:
if Roll_2 == 7:
Roll_2_return = True
return Roll_2_return
break
else:
break
Rolls()
if Roll_1_return == True:
print('Roll 1 is correct!')
round_score + 25
else:
print('Roll 1 is incorrect..')
if Roll_2_return == True:
print('Roll 2 is correct!')
round_score + 25
else:
print('Roll 2 is incorrect..')
if round_score == 50:
print('You won $100!')
elif round_score == 25:
print('You won $50!')
else:
print('Too bad, you lost!')
If I understand correctly, this should give you what you need! If this is not what you wanted, plz do not downvote me! I tried my hardest to understand.

Categories