Home > Back-end >  How to check if all items within a list of lists are the same
How to check if all items within a list of lists are the same

Time:09-21

I am working on a tic tack toe game in python (to improve my python skills) and am stuck on the following problem: I have a list of lists like below which determine whether or not a player has won depending on if all values either, vertically, horizontally, or diagonally have the same value.

win_horizontal = [[board[0], board[1], board[2]], [board[3], board[4], board[5]], [board[6], board[7], board[8]]]

win_vertical = [[board[0], board[3], board[6]], [board[1], board[4], board[7]], [board[2], board[5], board[8]]]

win_diagonal = [[board[0], board[4], board[8]], [board[2], board[4], board[6]]]

So at present, I have the following logic:

result = False;
result = all(elem == mark for elem in win_horizontal[1])
if result :
    print("All Elements in List are Equal")
else:        
    print("All Elements in List are Not Equal")

This works as I am only checking one list within the list. However, I am not sure how to check against all of the list of lists to determine whether or not the player has won diagonally, horizontally, or vertically. I want to be able to check against all of the list of lists.

I tried the following

def win_check(board, mark):
    win_horizontal = [[board[0], board[1], board[2]], [board[3], board[4], board[5]], [board[6], board[7], board[8]]]
    win_vertical = [[board[0], board[3], board[6]], [board[1], board[4], board[7]], [board[2], board[5], board[8]]]
    win_diagonal = [[board[0], board[4], board[8]], [board[2], board[4], board[6]]]
    
    winner = [win_horizontal, win_vertical, win_diagonal]
        
    result = False;
    result = all(elem == mark for elem in any(winner))
    if result :
        print("All Elements in List are Equal")
    else:        
        print("All Elements in List are Not Equal")

But I just get the following error TypeError: 'bool' object is not iterable which I assume is being raised from any(winner))

What is the best way to check for the winning condition?

CodePudding user response:

You need an any between horizontal, vertical, diagonal, and a all on each

result = any(
    all(elem == mark for elem in win)
    for win in winner
)

CodePudding user response:

It is probably simpler to check for the player's winning pattern rather than equality of the 3 board positions.

player        = 'X'             # last played
winPattern    = [player]*3
boardPatterns = win_horizontal   win_vertical   win_diagonal
if winPattern in boardPatterns:
    print(player,'wins!')

As a side note, you don't have to separate the 3 axis directions in 3 variables, you could build a single list of patterns to work from:

positions = [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]
boardPatterns = [[board[p] for p in axis] for axis in positions]

CodePudding user response:

from typing import Optional, Any

TEAM_A = True
TEAM_B = False

class Board:
  # Calculated victory patterns
  VICTORY_CELLS = [
    [0,1,2], [3,4,5], [6,7,8],  # horizontal
    [0,3,6], [1,4,7], [2,5,8],  # vertical
    [0,4,8], [2,4,6],  # diagonal
  ]
  def __init__(self):
    self._vector: list[Optional[Any]] = [None for _ in range(9)]

  def check_winner(self, marker) -> bool:
    # Get set of indexes where player has put his marker
    player_cells = {i for i, v in enumerate(self._vector) if v == marker}
    # For every victory pattern, if it is a subset of players markers, return True
    return any(player_cells.issuperset(victory) for victory in self.VICTORY_CELLS)

  def __setitem__(self, key, value):
    if isinstance(key, int) and 0 <= key <= 8:
      self._vector[key] = value

board = Board()
board[0] = TEAM_A
board[4] = TEAM_A
print('Team A victory: ', board.check_winner(TEAM_A))
print('Team B victory: ', board.check_winner(TEAM_B))
board[8] = TEAM_A
print('Team A victory: ', board.check_winner(TEAM_A))
print('Team B victory: ', board.check_winner(TEAM_B))

Result will be:

Team A victory:  False
Team B victory:  False
Team A victory:  True
Team B victory:  False

You should just make sure game won't continue after one's victory.

  • Related