TicTacToe Никто не выигрывает и не перевешивает выбор игрока - PullRequest
0 голосов
/ 26 апреля 2020

Я новый программист, и я начал изучать python и хотел научиться кодировать игру c ta c toe.

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

Для алгоритма выигрыша я не хотел go просматривать все варианты вручную, поэтому я использовал наборы. Я создал набор со всеми условиями выигрыша. Итерируя по каждому подмножеству (строки, столбцы и диагонали), я проверяю, является ли это подмножеством позиций игрока / компьютера.

Проблема в том, что это не работает. Если я пытаюсь что-то сделать, я получаю ValueError: list.remove (x) x, которого нет в списке . Иногда я получаю эту ошибку на линии, где удаляется playerChoice, или с компьютера. Другая проблема, как указано выше, заключается в том, что компьютер может отменить мой выбор.

Я думаю, что проблема заключается в удалении элементов из одного набора и добавлении их в другой, но я не могу найти способ обойти это

Вот код:

import random

board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
playerSymbol = ""
playerPosition = []
aiSymbol = ""
aiPosition = []
possiblePositions = [0, 1, 2, 3, 4, 5, 6, 7, 8]
turn = 0


def drawBoard():
    print(board[0] + " | " + board[1] + " | " + board[2])
    print("___" + "___" + "___")
    print(board[3] + " | " + board[4] + " | " + board[5])
    print("___" + "___" + "___")
    print(board[6] + " | " + board[7] + " | " + board[8])


def choice():
    global playerSymbol
    global aiSymbol

    answer = input("What do you want to play as? (type x or o) ")

    if answer.upper() == "X":
        playerSymbol = "X"
        aiSymbol = "O"
    else:
        playerSymbol = "O"
        aiSymbol = "X"


def won():
    winningPositions = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}]

    for position in winningPositions:
        if position.issubset(playerPosition):
            print("Player Wins :)")
            return True
        elif position.issubset(aiPosition):
            print("AI wins :(")
            return True
        else:
            return False


def play():
    global turn
    choice()

    while not won():
        if turn % 2 == 0:
            pos = int(input("Where would you like to play? (0-8) "))
            possiblePositions.remove(pos)
            playerPosition.append(pos)
            board[pos] = playerSymbol
            turn += 1
            drawBoard()
        else:
            aiTurn = random.randint(0, len(possiblePositions) - 1)
            possiblePositions.remove(possiblePositions[aiTurn])
            aiPosition.append(aiTurn)
            board[aiTurn] = aiSymbol
            turn += 1
            print("\n")
            print("\n")
            drawBoard()
    else:
        print("Thanks for playing :)")


play()

Я открыт для всевозможных предложений и способов улучшения моего кода. Заранее спасибо и будьте здоровы, Кристи

Ответы [ 3 ]

0 голосов
/ 26 апреля 2020

Несколько вещей, которые нужно попробовать:

  • В play(), aiTurn - это индекс позиции на доске в possiblePositions, поэтому вы должны сделать что-то вроде pos = possiblePositions[aiTurn] , ТО possiblePositions.remove(pos), aiPosition.append(pos) и board[pos] = aiSymbol. Прямо сейчас вы микшируете позицию доски и индекс.

  • Это может быть запутанным способом кодирования вещей, хотя, ИМХО, было бы лучше просто поддерживать доску (без списков игроков / ai позиции), и база win() от этого. Например, инициализируйте board = [0,0,0,0,0,0,0,0,0], затем установите board[pos] = 1 для X и board[pos] = -1 для O. Затем ваш win() может проверять строки / столбцы / диагнозы на предмет сумм, равных 3 или -3.

  • Если вы сделаете это таким образом, для перемещения компьютера потребуется чуть больше работы, что-то вроде pos = random.choice([i for i,p in enumerate(board) if p==0]) ... но это спасет вашу работу в другом месте

  • Вам нужны некоторые логики c, чтобы учесть игру дро / кошек

  • Я думаю, что использование global здесь не нужно, эти переменные уже имеют глобальную область видимости и должны быть доступны в каждой функции.

Надеюсь, это поможет!

0 голосов
/ 26 апреля 2020

Две вещи:

  1. В ход ИИ вы генерируете «до длины доступных позиций». Вам необходимо сгенерировать «одну из доступных позиций».

Измените эти строки:

    aiTurn = random.randint(0, len(possiblePositions) - 1)
    possiblePositions.remove(possiblePositions[aiTurn])

на

    aiTurn = random.choice(possiblePositions)
    possiblePositions.remove(aiTurn)
В won() вам нужно перебирать каждую возможную комбинацию, пока сравнение не достигнет True. Однако вы возвращаете либо true, либо false только после первого сравнения. Переместите return False за пределы l oop:

Измените

    for position in winningPositions:
        if position.issubset(playerPosition):
            print("Player Wins :)")
            return True
        elif position.issubset(aiPosition):
            print("AI wins :(")
            return True
        else:
            return False

на

    for position in winningPositions:
        if position.issubset(playerPosition):
            print("Player Wins :)")
            return True
        elif position.issubset(aiPosition):
            print("AI wins :(")
            return True

    return False
0 голосов
/ 26 апреля 2020

Во-первых, лучше напечатать все временное поле и поле с входным номером, потому что неудобно выбирать поле от 0 до 8. Сделайте так, это действительно легко понять (например):

[ ][ ][X]    [1][2][3]
[ ][ ][0]    [4][5][6]
[X][0][X]    [7][8][9]
Choose you box.

Во-вторых, вы должны проверить эту строку

aiTurn = random.randint(0, len(possiblePositions) - 1)

Вы не проверяете случайное значение, но это может быть позже двигаться. Из-за этого Ай может выбрать не пустое поле. Сделайте так:

#for example
if aiTurn in PosiblePositions:
    make_move()
else:
    generate_new_move()

В-третьих, когда вы пытаетесь удалить значение, которого нет в списке, оно вызывает ValueEror:

a = [1, 2, 3]
a.remove(4)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
...