Reputation: 17
I am currently going through some educational material, provided at pythonprogramming.net, where we try to build a TicTacToe game.
In the code below you can see a method that defines the rules for the winner, but whenever I try to "hard code" winning positions diagonally in my game list and then run the code- I keep getting the following in the terminal output:
Player 2 is the winner diagonally РР
Player 2 is the winner diagonally РР
Player 2 is the winner diagonally РР
Player 1 is the winner diagonally ЯЯ
Player 2 is the winner diagonally ЯЯ
Player 1 is the winner diagonally ЯЯ
If you look at the hardcoded test-case in my game list - It has to be only 1 winner(player 2) and only the last loop has to trigger and print out to the console...
Any suggestions where the issue might be and how it could be solved?
game = [[2, 0, 1],
[0, 2, 0],
[1, 0, 2]]
def win(current_game):
col_dig = list(reversed(range(len(game))))
row_dig = range(len(game))
for row in current_game:
print(row)
if row.count(row[0]) == len(row) and row[0] != 0:
print(f"Player {row[0]} is the winner!")
for col in range(len(game[0])):
check = []
for row in game:
check.append(row[col])
if check.count(check[0]) == len(check) and check[0] != 0:
print(f"Player {check[0]} is the winner vertically!")
for ix in range(len(game)):
diag = []
diag.append(game[ix][ix])
if diag.count(diag[0]) == len(diag) and diag[0] != 0:
print(f"Player {diag[0]} is the winner diagonally РР")
for x, y in zip(col_dig, row_dig):
diag2 = []
diag2.append(game[x][y])
if diag2.count(diag2[0]) == len(diag2) and diag2[0] != 0:
print(f"Player {diag2[0]} is the winner diagonally ЯЯ")
win(game)
Upvotes: 1
Views: 110
Reputation: 169
My answer shows a different approach using unique values. Also don't forget to add the return
statement! I've explained my logic in the comments written inside the code.
game = [[2, 0, 1],
[0, 2, 0],
[1, 0, 2]]
def win(current_game):
col_dig = list(reversed(range(len(game))))
row_dig = range(len(game))
for row in current_game:
if row.count(row[0]) == len(row) and row[0] != 0:
print(f"Player {row[0]} is the winner horizontally!")
return
for col in range(len(game[0])):
check = []
for row in game:
check.append(row[col])
if check.count(check[0]) == len(check) and check[0] != 0:
print(f"Player {check[0]} is the winner vertically!")
return
diag = []
for ix in range(len(game)):
diag.append(game[ix][ix])
# check the length of the unique values in the diagonal
# if only one unique value is present in the diagonal
# hence that player is the winner
if len(list(set(diag))) == 1:
print(f"Player {diag[0]} is the winner diagonally РР")
return
diag2 = []
for x, y in zip(col_dig, row_dig):
diag2.append(game[x][y])
# same logic is applied here.
# check the length of the unique values in the diagonal
# if only one unique value is present in the diagonal
# hence that player is the winner
if len(list(set(diag2))) == 1:
print(f"Player {diag2[0]} is the winner diagonally ЯЯ")
return
win(game)
Upvotes: 0
Reputation: 366
for ix in range(len(game)):
diag = []
diag.append(game[ix][ix])
if diag.count(diag[0]) == len(diag) and diag[0] != 0:
print(f"Player {diag[0]} is the winner diagonally РР")
Here, during each iteration your diag=[]
statement will be excuted and any previously appended value will be removed. So, you need to declare your initialization of diag=[]
before the for loop.
Also, your if condition is executing in each iteration of the loop. Since you are using the if condition within the loop. Thats why you are getting three line for the loop. So, you need to move your if condition outside the loop.
The updated code is like the following:
diag = []
for ix in range(len(game)):
diag.append(game[ix][ix])
if diag.count(diag[0]) == len(diag) and diag[0] != 0:
print(f"Player {diag[0]} is the winner diagonally РР")
Same case for the last portion of your code.
Upvotes: 1
Reputation: 1450
In your diag loops, you are assigning 'diag/diag2' name to empty list in every iteration of the loop, and then testing for winner after appending each element (that is why it was printing 6 times, once for each element of each diagonal = 3 x 2). Let it fill with all diagonal elements first and then test for winner condition.
Also, You should return from the function as soon as you have decided your winner (because ideally there would be only one winner).
After fixing these problems, your code will look like this:
game = [[2, 0, 1],
[0, 2, 0],
[1, 0, 2]]
def win(current_game):
col_dig = list(reversed(range(len(game))))
row_dig = range(len(game))
for row in current_game:
if row.count(row[0]) == len(row) and row[0] != 0:
print(f"Player {row[0]} is the winner!")
return
for col in range(len(game[0])):
check = []
for row in game:
check.append(row[col])
if check.count(check[0]) == len(check) and check[0] != 0:
print(f"Player {check[0]} is the winner vertically!")
return
diag = []
for ix in range(len(game)):
diag.append(game[ix][ix])
if diag.count(diag[0]) == len(diag) and diag[0] != 0:
print(f"Player {diag[0]} is the winner diagonally РР")
return
diag2 = []
for x, y in zip(col_dig, row_dig):
diag2.append(game[x][y])
if diag2.count(diag2[0]) == len(diag2) and diag2[0] != 0:
print(f"Player {diag2[0]} is the winner diagonally ЯЯ")
return
win(game)
Output:
Player 2 is the winner diagonally РР
Upvotes: 0