0

I am working on a tic tac toe project for school and am running into an issue with my winning detection. For some reason, it is registering as a win, when no one is getting 3 in a row. I have lists that hold the players past moves and have if statements to check the lists. Thanks for the help in advanced.

import time
import random
import os

board = """
   1     2     3
      |     |     
a  -  |  -  |  -  
 _____|_____|_____
      |     |     
b  -  |  -  |  -  
 _____|_____|_____
      |     |     
c  -  |  -  |  -  
      |     |    """

player1SymbolCharacter = 'X'
player2SymbolCharacter = '0'
index1 = 40
index2 = 46
index3 = 52
index4 = 97
index5 = 103
index6 = 109
index7 = 154
index8 = 160
index9 = 166

def win1():
    print(board)
    print('\nPlayer 1 Won!')
    return True

def win2():
    print(board)
    print('\nPlayer 2 Won!')
    return True

player1tiles = []
player2tiles = []

print(board)

while True:
  player1 = input("Player 1, Enter Your Position (letter, number):")
  if (player1 == "a1"):
    board = board[:index1] + player1SymbolCharacter + board[index1+1:]
    player1tiles.append("a1")    
  elif (player1 == "a2"):
    board = board[:index2] + player1SymbolCharacter + board[index2+1:]
    player1tiles.append("a2")    
  elif (player1 == "a3"):
    board = board[:index3] + player1SymbolCharacter + board[index3+1:]
    player1tiles.append("a3")    
  elif (player1 == "b1"):
    board = board[:index4] + player1SymbolCharacter + board[index4+1:]
    player1tiles.append("b1")    
  elif (player1 == "b2"):
    board = board[:index5] + player1SymbolCharacter + board[index5+1:]
    player1tiles.append("b2")    
  elif (player1 == "b3"):
    board = board[:index6] + player1SymbolCharacter + board[index6+1:]
    player1tiles.append("b3")
  elif (player1 == "c1"):
    board = board[:index7] + player1SymbolCharacter + board[index7+1:]
    player1tiles.append("c1")
  elif (player1 == "c2"):
    board = board[:index8] + player1SymbolCharacter + board[index8+1:]
    player1tiles.append("c2")
  elif (player1 == "c3"):
    board = board[:index9] + player1SymbolCharacter + board[index9+1:]
    player1tiles.append("c3")
    
  os.system('clear')
  print(player1tiles)
  print(player2tiles)

  if "a1" and "a2" and "a3" in player1tiles:
    if win1():
      break
  elif "b1" and "b2" and "b3" in player1tiles:
    if win1():
      break
  elif "c1" and "c2" and "c3" in player1tiles:
    if win1():
      break
  elif "a1" and "b1" and "c1" in player1tiles:
    if win1():
      break
  elif "a2" and "b2" and "c2" in player1tiles:
    if win1():
      break
  elif "a3" and "b3" and "c3" in player1tiles:
    if win1():
      break
  elif "a1" and "b2" and "c3" in player1tiles:
    if win1():
      break
  elif "a3" and "b2" and "c1" in player1tiles:
    if win1():
      break
  
  print(board)
  player2 = input("Player 2, Enter Your Position (number, letter):")
  if (player2 == "a1"):
    board = board[:index1] + player2SymbolCharacter + board[index1+1:]
    player2tiles.append("a1")    
  elif (player2 == "a2"):
    board = board[:index2] + player2SymbolCharacter + board[index2+1:]
    player2tiles.append("a2") 
  elif (player2 == "a3"):
    board = board[:index3] + player2SymbolCharacter + board[index3+1:]
    player2tiles.append("a3") 
  elif (player2 == "b1"):
    board = board[:index4] + player2SymbolCharacter + board[index4+1:]
    player2tiles.append("b1") 
  elif (player2 == "b2"):
    board = board[:index5] + player2SymbolCharacter + board[index5+1:]
    player2tiles.append("b2") 
  elif (player2 == "b3"):
    board = board[:index6] + player2SymbolCharacter + board[index6+1:]
    player2tiles.append("b3") 
  elif (player2 == "c1"):
    board = board[:index7] + player2SymbolCharacter + board[index7+1:]
    player2tiles.append("c1") 
  elif (player2 == "c2"):
    board = board[:index8] + player2SymbolCharacter + board[index8+1:]
    player2tiles.append("c2") 
  elif (player2 == "c3"):
    board = board[:index9] + player2SymbolCharacter + board[index9+1:]
    player2tiles.append("c3") 
  os.system('clear')
  print(player1tiles)
  print(player2tiles)

  if "a1" and "a2" and "a3" in player2tiles:
    if win2():
      break
  elif "b1" and "b2" and "b3" in player2tiles:
    if win2():
      break
  elif "c1" and "c2" and "c3" in player2tiles:
    if win2():
      break
  elif "a1" and "b1" and "c1" in player2tiles:
    if win2():
      break
  elif "a2" and "b2" and "c2" in player2tiles:
   if win2():
      break
  elif "a3" and "b3" and "c3" in player2tiles:
    if win2():
      break
  elif "a1" and "b2" and "c3" in player2tiles:
    if win2():
      break
  elif "a3" and "b2" and "c1" in player2tiles:
    if win2():
      break    
  
  
  print(board)
  • 3
    Don't mix I/O with business logic. In other words, don't use the printable board string as your data structure for the game. Instead use a compact data structure for the game that does not have anything to do with display features, and write a function that can display such board state. – trincot Jan 12 '23 at 19:20
  • Does this answer your question? [How to test multiple variables for equality against a single value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-for-equality-against-a-single-value) – Sören Jan 12 '23 at 19:31
  • @Sören That's similar; this is closer to testing for set equality or testing "list contains all specified elements" (`set() == set()` or `all(item in list_ for item in specified_elements)` respectively) -- can you find a dupe for one of those? – Joshua Voskamp Jan 12 '23 at 19:38
  • @Max Herczeg. You need to add two more, vertical and diagional – toyota Supra Jan 12 '23 at 20:39

2 Answers2

0

The problem is in your ifs:

if "a1" and "a2" and "a3" in player1tiles:

should instead be something like

if set({"a1","a2","a3"}) == set(player1tiles):

# or

if all(tile in player1tiles for tile in ["a1","a2","a3"]):

This is because of logical operator precedence; the expression

if "a1" and "a2" and "a3" in player1tiles:

is equivalent to

if ("a1") and ("a2") and ("a3" in player1tiles)

and in Python, non-empty strings are "truthy", so this all is equivalent to

if (True) and (True) and ("a3" in player1tiles)

which of course is equivalent to

if ("a3" in player1tiles)

On a completely unrelated note, much of your code is some form of "copy, paste, edit" -- have you heard of DRY (Don't Repeat Yourself)? Here's a blog post with an example of refactoring code so that it isn't repetitive.

You may want to ask in codereview.stackexchange.com (once you have working code) for tips to improve your code (see e.g. the comment about not mixing "business logic" and "display logic").

Joshua Voskamp
  • 1,855
  • 1
  • 10
  • 13
0

Change the if conditions in order to check if every single string is in the list separately. Previously the if statement where checking only the last element. For example in the following if condition:

elif "a3" and "b2" and "c3" in player1tiles:

the statement was checking only if "c3" was in the list. Change this in order to in

elif "a3" in player1tiles and "b2" in player1tiles and "c3" in player1tiles: