#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
Вы должны просто убедиться, что игра не продолжится после вашей победы.