Как проверить, совпадают ли все элементы в списке списков

#python #python-3.x #list

Вопрос:

Я работаю над игрой в крестики-нолики на python (чтобы улучшить свои навыки работы на python) и столкнулся со следующей проблемой: у меня есть список списков, как показано ниже, которые определяют, выиграл игрок или нет, в зависимости от того, все ли значения по вертикали, горизонтали или диагонали имеют одинаковое значение.

 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]]]
 

Итак, в настоящее время у меня есть следующая логика:

 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")
 

Это работает, так как я проверяю только один список в списке. Однако я не уверен, как свериться со всем списком списков, чтобы определить, выиграл ли игрок по диагонали, горизонтали или вертикали. Я хочу иметь возможность сверяться со всеми списками списков.

Я попробовал следующее

 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")
 

Но я просто получаю следующую ошибку TypeError: 'bool' object is not iterable , которая, как я предполагаю, возникает из any(winner))

Каков наилучший способ проверить условие выигрыша?

Ответ №1:

Вам нужно any выбрать между горизонтальным, вертикальным, диагональным и a all на каждом

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

Ответ №2:

Вероятно, проще проверить выигрышную схему игрока, чем равенство 3 позиций на доске.

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

В качестве примечания, вам не нужно разделять 3 направления оси в 3 переменных, вы можете создать единый список шаблонов для работы:

 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]
 

Ответ №3:

 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))
 

Результатом будет:

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

Вы должны просто убедиться, что игра не продолжится после вашей победы.