2016-10-18 2 views
0

Я работаю над проблемой практики, когда мы должны вводить список в аргумент функции, который будет представлять плату tic tac toe и возвращать исходный результат. То есть X выигрывает, выигрывает O, Draw или None (пустая строка).Преобразование оператора if в цикл

У меня есть решение, но мне было интересно, есть ли способ, которым я мог бы манипулировать моим алгоритмом в цикле, так как было рекомендовано использовать цикл для сравнения каждого элемента главной диагонали со всеми элементами пересекающихся строк и столбцов, а затем проверить две диагонали. Я новичок в python, поэтому мое решение может быть немного дольше, чем нужно. Как можно реализовать цикл, чтобы проверить результат платы tic tac toe?

def gameState (List): 
    xcounter=0 
    ocounter=0 
    if List[0][0]==List[0][1] and List[0][0]==List[0][2]: 
     return List[0][0] 
    elif List[0][0]==List[1][0] and List[0][0]==List[2][0]: 
     return List[0][0] 
    elif List[0][0]==List[1][1] and List[0][0]==List[2][2]: 
     return List[0][0] 
    elif List[1][1]==List[1][2] and List[1][1]==List[1][0] : 
     return List[1][1] 
    elif List[1][1]==List[0][1] and List[1][1]==List[2][1]: 
     return List[1][1] 
    elif List[1][1]==List[0][0] and List[1][1]==List[2][2]: 
     return List[1][1] 
    elif List[2][2]==List[2][0] and List[2][2]==List[2][1]: 
     return List[2][2] 
    elif List[2][2]==List[1][2] and List[2][2]==List[0][2]: 
     return List[2][2] 
    elif List[2][2]==List[1][1] and List[2][2]==List[0][0]: 
     return List[2][2] 
    for listt in List: 
     for elm in listt: 
      if elm=="X" or elm=="x": 
       xcounter+=1 
      elif elm=="O" or elm=="o": 
       ocounter+=1 
    if xcounter==5 or ocounter==5: 
     return "D" 
    else: 
     return '' 
+3

Вы пробовали использовать петлю? Какие у вас проблемы? Кроме того, 'List' - это неправильное имя переменной, так как это тоже встроенный Python, и в какой-то момент использование встроенного подобного решения вызовет проблемы. – enderland

+1

Является ли этот «рабочий» код? Если да, спросите его на [Обзор кода] (http://codereview.stackexchange.com/) –

+0

Похоже, у вас есть цикл, уже реализованный при использовании вложенных операторов 'for'. –

ответ

5

Прежде всего, есть только восемь способов выиграть в TicTacToe. У вас есть девять операторов сравнения и возврата, поэтому один лишний. Фактически, при дальнейшем рассмотрении вы проверяете 00, 11, 22три раз (случаи 3, 6 и 9) и полностью пропустил02, 11, 20 кейс.

С точки зрения проверки с петлей, вы можете разделить из проверки строк/столбцов из диагоналей следующим образом:

# Check all three rows and columns. 

for idx in range(3): 
    if List[0][idx] != ' ': 
     if List[0][idx] == List[1][idx] and List[0][idx] == List[2][idx]: 
      return List[0][idx] 
    if List[idx][0] != ' ': 
     if List[idx][0] == List[idx][1] and List[idx][0] == List[idx][2]: 
      return List[idx][0] 

# Check two diagonals. 

if List[1][1] != ' ': 
    if List[1][1] == List[0][0] and List[1][1] == List[2][2]: 
     return List[1][1] 
    if List[1][1] == List[0][2] and List[1][1] == List[2][0]: 
     return List[1][1] 

# No winner yet. 

return ' ' 

Обратите внимание, что это обеспечивает ряд пустых ячеек не сразу взял, как победа никому. Вы должны проверить только на победы «реального» игрока. Под этим я имею в виду, что вы не хотите обнаруживать три пустые ячейки в первой строке и возвращать указание на основании этого, если вторая строка имеет фактический победитель.


Конечно, существует множество способов реорганизации такого кода, чтобы сделать его более легко читаемым и понятным. Один из способов отделить логику для проверки одного линии, а затем вызвать, что для каждой строки:

# Detect a winning line. First cell must be filled in 
# and other cells must be equal to first. 

def isWinLine(brd, x1, y1, x2, y2, x3, y3): 
    if brd[x1][y1] == ' ': return False 
    return brd[x1][y1] == brd[x2][y2] and brd[x1][y1] == brd[x3][y3] 

# Get winner of game by checking each possible line for a winner, 
# return contents of one of the cells if so. Otherwise return 
# empty value. 

def getWinner(brd): 
    # Rows and columns first. 

    for idx in range(3): 
     if isWinLine(brd, idx, 0, idx, 1, idx, 2): return brd[idx][0] 
     if isWinLine(brd, 0, idx, 1, idx, 2, idx): return brd[0][idx] 

    # Then diagonals. 

    if isWinLine(brd, 0, 0, 1, 1, 2, 2): return brd[1][1] 
    if isWinLine(brd, 2, 0, 1, 1, 0, 2): return brd[1][1] 

    # No winner yet. 

    return ' ' 

Тогда вы можете просто использовать:

winner = getWinner(List) 

в вашем коде и вы либо вернуть победителя, либо пустую индикацию, если ее нет.

Смежные вопросы