вместо этих длинных серий и / или вы должны построить список позиций на доске, которые образуют сегменты (линии), и использовать его как косвенное направление для получения всех шаблонов на доске:
Например:
segments = [ (0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6) ]
boardMarks = [ c if c in "XO" else "." for c in board ]
patterns = [ "".join(sorted(boardMarks[i] for i in s)) for s in segments ]
playerWins = (player*3) in patterns
xWins = "XXX" in patterns
oWins = "OOO" in patterns
draw = not xWins and not oWins and "." not in boardMarks
или, если вы хотите быть более прогнозирующим и объявить ничью раньше, когда больше нет ходов, которые могут выиграть:
draw = not any(canWin in patterns for canWin in ("...","..X","..O",".XX",".OO"))
Поскольку шаблоны отсортированы Есть только 5 комбинаций, которые представляют выигрышную линию
Если вы хотите, чтобы компьютер играл, вы можете использовать эту функцию 'autoPlay', чтобы выбрать позицию на основе системы рейтингов mini-max:
skill = 4 # 1 to 4 (novice to master)
def rating(position,player,board,level=skill+5):
if board[position] in "XO" or not level: return 0
newBoard = board[:position]+[player]+board[position+1:]
isWin = player*3 in ( "".join(newBoard[i] for i in s) for s in segments )
if isWin: return 3**level * 2
nextRatings = [rating(p,"XO"[player=="X"],newBoard,level-1) for p in range(9)]
return 3**level - max(nextRatings,key=abs)
from random import sample
def autoPlay(board,player):
return max(sample(range(9),9),key=lambda p:rating(p,player,board))
Пример использования:
position = autoPlay(board,player)
print("computer plays ",player," at position ",position+1)
board[position] = player