#python #tic-tac-toe
#python #крестики-нолики
Вопрос:
Это одна из моих первых программ для онлайн-курса Python, который я прохожу. Я собрал некоторый код, который выполняет большую часть работы, но у меня все еще возникают проблемы с тем, чтобы заставить моего компьютерного игрока перейти к использованию библиотеки случайных чисел и прочитать их на доске. Я пытался переместить код внутри DrawMove()
непосредственно в основной код, но безуспешно. В настоящее время я настроил его так, чтобы два игрока могли играть друг против друга, но я хочу добавить randrange
к игроку ‘X’, чтобы игрок мог играть против компьютера.
import itertools
from random import randrange
board = [[1,2,3],
[4,'X',6],
[7,8,9]]
def InitialBoard(board):
print(" ------- ------- ------- n| | | |n| ",board[0][0]," | ",board[0][1]," | ",board[0][2]," |")
print("| | | |n ------- ------- ------- n| | | |")
print("| ",board[1][0]," | ",'X'," | ",board[1][2]," |n| | | |n ------- ------- ------- ")
print("| | | |n| ",board[2][0]," | ",board[2][1]," | ",board[2][2]," |n| | | |")
print(" ------- ------- ------- ")
def DisplayBoard(gameMap, playerMove, row, column):
try:
if board[row][column] == 'X' or board[row][column] == 'O':
print("This space is occupied by X, please try another one.")
return False
gameMap[row][column] = playerMove #add parameters to our function
for row, column in enumerate(gameMap):
print(" ------- ------- ------- n| | | |n| ",board[0][0]," | ",board[0][1]," | ",board[0][2]," |")
print("| | | |n ------- ------- ------- n| | | |")
print("| ",board[1][0]," | ",'X'," | ",board[1][2]," |n| | | |n ------- ------- ------- ")
print("| | | |n| ",board[2][0]," | ",board[2][1]," | ",board[2][2]," |n| | | |")
print(" ------- ------- ------- ")
return gameMap
except IndexError: #handles index error
print("Out of range, please choose a number between 0-2.")
return False
except Exception as e: #handles general errors, prints description of type of error
print(str(e))
return False
def VictoryFor(current_game):
#horizontal
for row in board:
column1 = row[0] #all the same on top row
column2 = row[1]
column3 = row[2]
if column1 == column2 == column3:#checks if top row same
print(f"Player {row[0]} is the winner!")#f string is used to pass variables inside of curly braces
#vertical
if board[0][0] == board[1][0] == board[2][0]:
print("Winner in first column!")
for row in board:
print(row[0])
elif board[0][1] == board[1][1] == board[2][1]:
print("Winner in second column!")
for row in board:
print(row[1])
elif board[0][2] == board[1][2] == board[2][2]:
print("Winner in third column!")
for row in board:
print(row[2])
#diagonal
if board[0][0] == board[1][1] == board[2][2]:
print("Diagonal Winner down!")
if board[2][0] == board[1][1] == board[0][2]:
print("Diagonal Winner up!")
def DrawMove(board):#computer move
row_choice = int(randrange(2))
columnn_choice = int(randrange(2))
#main
play = True
players = ['X','O']#computer is X, player is O. Computer makes first move.
while play:
board = [[1, 2, 3],
[4,'X',6],
[7, 8, 9]]
game_won = False
player_cycle = itertools.cycle(['X','O'])
InitialBoard(board)
while not game_won:
current_player = 'O'#computer has made move in center of board, your turn now
current_player = next(player_cycle)
played = False
while not played:
print(f"Player: {current_player}")
column_choice = int(input("Pick a column 0-2:"))
row_choice = int(input("Pick a row 0-2:"))
played = DisplayBoard(board, playerMove = current_player, row = row_choice, column = column_choice)
if VictoryFor(board):
game_won = True
again = input("The game is over, play again? Type (y/n)")
if again.lower() == "y":
print("Restarting")
elif again.lower() == "n":
print("Goodbye")
play = False
else:
play = False
Комментарии:
1. Вопрос для меня неясен. В чем ваша конкретная проблема программирования?
Ответ №1:
Это может быть лучше подходит для https://codereview.stackexchange.com / но с одного места можно начать рассматривать вашу board
переменную как «состояние игры».
Вместо того, чтобы позволить ИИ выбирать любую строку / столбец, он должен выбирать только строку / столбец, которые еще не заняты.
Таким образом, вы можете думать о своей доске как о начальном значении, которое в конечном итоге заполняется неиграбельными пробелами, и вместо «случайного числа» вы можете думать о нем как о случайном «розыгрыше» из этого пула вариантов. Подумайте, что «рисовать из колоды карт» больше, чем «скажите мне случайное число».
Я думаю, что это было бы более эффективно, чем надеяться случайным образом выбрать правильную позицию.
Например, в тривиальной 1-строчной версии tic-tac-toe:
row1 = [1, 2, 3]
mask = [1, 1, 1] # initial state
# human places an X at position 2:
mask = update() # mask for row1 becomes [1, 0, 1]
# AI now can determine that position 2 is not a valid spot:
valid_spots = list(filter(bool, [i*j for i,j in zip(row1, mask)])) # [1,3]
# choose a valid spot from the available indexes
choice_index = random.randint(0, len(valid_spots)-1)
new_move = row1[choice_index]
Ответ №2:
вы сбрасываете доску каждый раз, когда запускается цикл воспроизведения while
Комментарии:
1. Это хороший комментарий, но он не отвечает на вопрос OP.
2. я отложил это, потому что в op сразу же используется случайное значение, поскольку сразу после этого они сбрасывают плату, и это может восприниматься как неработающее