Leprekus
Leprekus

Reputation: 54

Find matching elements on the same index in a list of lists?

I am coding a tic tac toe game the game board looks as follows:

game = [[1, 0, 1],
        [1, 1, 0],
        [1, 1, 0],]

I am trying the following function:

def vertical_win(game):
    for column, row in enumerate(game):
        check = []
        check.append(row[0])
        if check.count(check[0]) == len(check) and check[0] != 0:
            print("Winner")

Output:

Winner
Winner
Winner

it is only iterating over the 0th element of each list. And if the number it displays winner for a each number per row instead of matching all three numbers of each list.

Upvotes: 0

Views: 326

Answers (3)

ddejohn
ddejohn

Reputation: 8960

An easy way to get the "columns" of the game board is to use zip():

>>> cols = [*zip(*game)]
>>> cols
[(1, 1, 1), (0, 1, 1), (1, 0, 0)]

From here you can check for a win with a membership test:

if (0, 0, 0) in cols:
    print("player 0 wins")
elif (1, 1, 1) in cols:
    print("player 1 wins")

Putting it together:

def vertical_win(game):
    cols = [*zip(*game)]
    if (0, 0, 0) in cols:
        print("player 0 wins")
    elif (1, 1, 1) in cols:
        print("player 1 wins")

You can very easily extend this to larger board sizes with this small modification:

def vertical_win(game):
    n = len(game)
    cols = [*zip(*game)]
    if (0,)*n in cols:
        print("player 0 wins")
    elif (1,)*n in cols:
        print("player 1 wins")

As for why your code isn't working:

>>> def vertical_win(game):
...     for col, row in enumerate(game):
...             print(col, row)
...             check = []
...             check.append(row[0])
...             print(check)
...
>>>
>>> vertical_win(game)
0 [1, 0, 1]
[1]
1 [1, 1, 0]
[1]
2 [1, 1, 0]
[1]

For all three iterations, the boolean expression if check.count(check[0]) == len(check) and check[0] != 0 for this particular board state is always going to be true because check[0] == 1 and check.count(1) == len([1]) and check[0] == 1 which is != 0.

Upvotes: 1

Shufi123
Shufi123

Reputation: 233

You could write the following:

def vertical_win(game):
    # looping over all the items in the first item of the game
    for column in range(len(game[0])):
        # going over all the other games, and checking if they have the same values in a certain column
        for other in range(1, len(game)):
            # if they don't have the same value in a column break, since it won't be necessary to check
            # if all the items in game have the same value in a specific column, that
            # means that there will be no breaks so the else statement will run
            if game[0][column] != game[other][column]:
                break
        else:
            # return True if didn't break out of loop
            return True
    # return False if we didn't return True at any time
    return False

The function returns true when there is a vertical win, and it is also completely dynamic to the size of the game, so it could even work on a 4x4 grid. Also, if you want to, you can know in which index the win occurs by returning column together with the already returned value when returning True.

Upvotes: 0

Tim Roberts
Tim Roberts

Reputation: 54867

def vertical_win(game):
    for column in range(3):
        score = sum(row[column] for row in game)
        if score == 0 or score == 3:
            print("Winner")

Upvotes: 0

Related Questions