0

Objective is to come out of 'final result while loop' (added as comment) once p1 or p2 wins. I have created a global flag which is initially False but once the winningfunc() returns result1 or result 2 equals to 3, flag is turned to True. I understand there might be verbose, but I am new to python or coding of any sort.

Trying to make a simple tic tac toe. Any help is appreciated :)

frame=[[" ","|"," ","|"," "],
      ["-","-","-","-","-"],
      [" ","|"," ","|"," "],
      ["-","-","-","-","-"],
      [" ","|"," ","|"," "]]

# Name assignment
while True:
    p1_name=input("Enter player 1 name: ")
    p2_name=input("Enter player 2 name: ")

    if p1_name.lower()==p2_name.lower():
        print("Both names entered are same, please re-enter!")
    else:
        break
# Notation assignment 
while True:
    p1_nt=input(f"{p1_name}, choose 'X' or 'O' to play with: ")
    if p1_nt.lower()=="x":
        p1_nt="X"
        p2_nt="O"
        print(f"{p1_name} will play with 'X' & {p2_name} will play with 'O'")
        break
    elif p1_nt.lower()=="o":
        p1_nt="O"
        p2_nt="X"
        print(f"{p1_name} will play with 'O' & {p2_name} will play with 'X'")
        break
    else:
        print("Entered notation is wrong, please re-enter!")

# dict 
dc={"1":[4,0],"2":[4,2],"3":[4,4],"4":[2,0],"5":[2,2],"6":[2,4],"7":[0,0],"8":[0,2],"9":[0,4]}

# winning logic definition
flag=False
def winningfunc (): 
    def mf(v1,v2,v3):
        result1=0
        result2=0
        for x in range(v1,v2,v3):
            if frame[dc[str(x)][0]][dc[str(x)][1]]==p1_nt:
                result1+=1
            elif frame[dc[str(x)][0]][dc[str(x)][1]]==p2_nt:
                result2+=1
            else:
                pass
        if result1==3:
            flag=True
            print(f"Congratulations, {p1_name} wins! ")            
        elif result2==3:
            flag=True
            print(f"Congratulations, {p2_name} wins! ")            
        else:
            pass

    mf(1,4,1) # for c4
    mf(4,7,1) # for c2
    mf(7,10,1) # for c0
    mf(1,10,4) # for d1
    mf(3,8,2) # for d2
    mf(1,8,3) # for r0
    mf(2,9,3) # for r2
    mf(3,10,3) # for r3

# loop for payer input

while not flag: # for final result 
    while True: # for p1 data filling 
        s1=input(f"{p1_name} its your turn: ")
        if 0<=int(s1)<=9 and frame[dc[str(s1)][0]][dc[str(s1)][1]]==" ":
            if p1_nt=="X":
                frame[dc[str(s1)][0]][dc[str(s1)][1]]="X"
            else:
                frame[dc[str(s1)][0]][dc[str(s1)][1]]="O"
            break
        else:
            print(f"Wrong entry {p1_name}, try once again!")
    x1=None        
    for x1 in range(len(frame)):
        f1="".join(frame[x1])
        print(f1)
    # Result check for p1
    winningfunc()    


    while True: # for p2 data filling 
        s2=input(f"{p2_name} its your turn: ")
        if 0<=int(s1)<=9 and frame[dc[str(s2)][0]][dc[str(s2)][1]]==" ":
            if p2_nt=="X":
                frame[dc[str(s2)][0]][dc[str(s2)][1]]="X"
            else:
                frame[dc[str(s2)][0]][dc[str(s2)][1]]="O"
            break
        else:
            print(f"Wrong entry {p2_name}, try once again!")

    x2=None
    for x2 in range(5):
        f2="".join(frame[x2])
        print(f2)
    # Result check for p2    
    winningfunc()
Suvo
  • 67
  • 5

1 Answers1

3

To access the global flag, you need to specify that it is global in the beginning of the method. Moreover, you should check if flag is true before player 2's turn. Here is the working code:

frame=[[" ","|"," ","|"," "],
      ["-","-","-","-","-"],
      [" ","|"," ","|"," "],
      ["-","-","-","-","-"],
      [" ","|"," ","|"," "]]

# Name assignment
while True:
    p1_name=input("Enter player 1 name: ")
    p2_name=input("Enter player 2 name: ")

    if p1_name.lower()==p2_name.lower():
        print("Both names entered are same, please re-enter!")
    else:
        break
# Notation assignment 
while True:
    p1_nt=input(f"{p1_name}, choose 'X' or 'O' to play with: ")
    if p1_nt.lower()=="x":
        p1_nt="X"
        p2_nt="O"
        print(f"{p1_name} will play with 'X' & {p2_name} will play with 'O'")
        break
    elif p1_nt.lower()=="o":
        p1_nt="O"
        p2_nt="X"
        print(f"{p1_name} will play with 'O' & {p2_name} will play with 'X'")
        break
    else:
        print("Entered notation is wrong, please re-enter!")

# dict 
dc={"1":[4,0],"2":[4,2],"3":[4,4],"4":[2,0],"5":[2,2],"6":[2,4],"7":[0,0],"8":[0,2],"9":[0,4]}

# winning logic definition
flag=False
def winningfunc (): 
    global flag
    def mf(v1,v2,v3):
        global flag
        result1=0
        result2=0
        for x in range(v1,v2,v3):
            if frame[dc[str(x)][0]][dc[str(x)][1]]==p1_nt:
                result1+=1
            elif frame[dc[str(x)][0]][dc[str(x)][1]]==p2_nt:
                result2+=1
            else:
                pass
        if result1==3:
            flag=True
            print(f"Congratulations, {p1_name} wins! ")            
        elif result2==3:
            flag=True
            print(f"Congratulations, {p2_name} wins! ")            
        else:
            pass

    mf(1,4,1) # for c4
    mf(4,7,1) # for c2
    mf(7,10,1) # for c0
    mf(1,10,4) # for d1
    mf(3,8,2) # for d2
    mf(1,8,3) # for r0
    mf(2,9,3) # for r2
    mf(3,10,3) # for r3

# loop for payer input

while not flag: # for final result 
    while True: # for p1 data filling 
        s1=input(f"{p1_name} its your turn: ")
        if 0<=int(s1)<=9 and frame[dc[str(s1)][0]][dc[str(s1)][1]]==" ":
            if p1_nt=="X":
                frame[dc[str(s1)][0]][dc[str(s1)][1]]="X"
            else:
                frame[dc[str(s1)][0]][dc[str(s1)][1]]="O"
            break
        else:
            print(f"Wrong entry {p1_name}, try once again!")
    x1=None        
    for x1 in range(len(frame)):
        f1="".join(frame[x1])
        print(f1)
    # Result check for p1
    winningfunc()    
    if flag:
        break


    while True: # for p2 data filling 
        s2=input(f"{p2_name} its your turn: ")
        if 0<=int(s1)<=9 and frame[dc[str(s2)][0]][dc[str(s2)][1]]==" ":
            if p2_nt=="X":
                frame[dc[str(s2)][0]][dc[str(s2)][1]]="X"
            else:
                frame[dc[str(s2)][0]][dc[str(s2)][1]]="O"
            break
        else:
            print(f"Wrong entry {p2_name}, try once again!")

    x2=None
    for x2 in range(5):
        f2="".join(frame[x2])
        print(f2)
    # Result check for p2    
    winningfunc()
brandonwang
  • 1,603
  • 10
  • 17
  • Thanks very much ! – Suvo Aug 09 '18 at 19:33
  • Just so that I understand it correctly- "Moreover, you should check if flag is true before player 2's turn" - why? – Suvo Aug 09 '18 at 20:30
  • 1
    This is because if player one wins, the game should end. But if you don't check the flag, the program will ask for player 2's input again since the while loop is still running. – brandonwang Aug 10 '18 at 15:24