Dennis
Dennis

Reputation: 17

Why does my FOR loop returns 6 results instead of 1

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

Answers (3)

Sammit
Sammit

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

MD Billal Hossain
MD Billal Hossain

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

Sagar Gupta
Sagar Gupta

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

Related Questions