Я только начинаю изучать Python и думал, что поставлю перед собой задачу, используя уроки, которые я усвоил до сих пор. Я слежу за курсом Udemy «Автоматизация скучных вещей с помощью Python». То, что я до сих пор достиг, касалось основ функций, обработки ошибок, списков и словарей.
Я хотел посмотреть, понял ли я, что я узнал, создав игру в крестики-нолики с учетом определенных функций / задач / целей:
- использовать циклы, функции, методы, списки / словари.
- игроку нужно будет увидеть доску и то, какие места были заняты / оставлены
- Я хотел, чтобы игроки могли выбирать в верхнем / нижнем / смешанном регистре.
- игра должна была учитывать все условия победы, условия проигрыша и патовые ситуации.
- оппоненту (в данном случае ЦП) нужно будет иметь доступ только к оставшимся вариантам. На данный момент это будет случайным образом, но, возможно, я вернусь к коду, чтобы иметь какую-то форму ИИ.
- Когда игра закончится, дайте игроку возможность начать новую игру и следить за счетом.
Это мой код, и, насколько я могу судить, он работает, и мне удалось достичь всех целей, которые я поставил перед собой:
import copy
import time
import random
import sys
##Board design to make it look pretty
def printBoard(board):
print('')
print(board['top-l'] + '|' + board['top-m'] + '|' + board['top-r'])
print('-----')
print(board['mid-l'] + '|' + board['mid-m'] + '|' + board['mid-r'])
print('-----')
print(board['low-l'] + '|' + board['low-m'] + '|' + board['low-r'])
print('')
##Function for initiating the board back to blank
def blankBoard(zeroBoard):
for value in zeroBoard:
zeroBoard[value] = ' '
##Function for initiating a New Game after a game over situation
def newGame(YorN):
print('n ~ Would you like to play again? if yes, type ''Y'': ~ ')
newGame = input()
if newGame.upper() == 'Y':
print(' ~ okay, please wait while we set up a new game! ~ ')
blankBoard(theBoard)
time.sleep(random.randint(1,2))
printBoard(theBoard)
else:
print('n ~ Bye and thank you for playing!! ~ ')
sys.exit()
##Function containing all the win conditions
def winCondition(winner):
if ((winner['top-l'] == winner['top-m'] == winner['top-r'] == 'X') or
(winner['mid-l'] == winner['mid-m'] == winner['mid-r'] == 'X') or
(winner['low-l'] == winner['low-m'] == winner['low-r'] == 'X') or
(winner['top-l'] == winner['mid-l'] == winner['low-l'] == 'X') or
(winner['top-m'] == winner['mid-m'] == winner['low-m'] == 'X') or
(winner['top-r'] == winner['mid-r'] == winner['low-r'] == 'X') or
(winner['top-l'] == winner['mid-m'] == winner['low-r'] == 'X') or
(winner['top-r'] == winner['mid-m'] == winner['low-l'] == 'X')):
print('n ~ Congratulations! You are a winner! ')
return 'win'
##Function containing all the loss conditions
def loseCondition(loser):
if ((loser['top-l'] == loser['top-m'] == loser['top-r'] == 'O') or
(loser['mid-l'] == loser['mid-m'] == loser['mid-r'] == 'O') or
(loser['low-l'] == loser['low-m'] == loser['low-r'] == 'O') or
(loser['top-l'] == loser['mid-l'] == loser['low-l'] == 'O') or
(loser['top-m'] == loser['mid-m'] == loser['low-m'] == 'O') or
(loser['top-r'] == loser['mid-r'] == loser['low-r'] == 'O') or
(loser['top-l'] == loser['mid-m'] == loser['low-r'] == 'O') or
(loser['top-r'] == loser['mid-m'] == loser['low-l'] == 'O')):
print('n ~ Aww man, you''re are a loser! ~ ')
return 'lose'
##Function for Computer Players Choice
def computerChoice(cpuChoice):
theBoardCPU = copy.deepcopy(theBoardChoices)
print(','.join(theBoardCPU.keys()))
cpuChoice = random.choice(list(theBoardCPU.keys()))
print(' ~ ' + cpuChoice + ' ~ ')
del theBoardChoices[cpuChoice]
theBoard[cpuChoice] = 'O'
printBoard(theBoard)
##Blank board to begin with and making a copy of the board for choices remaining, and finally printing a pretty board
theBoard = {'top-l': ' ', 'top-m': ' ', 'top-r': ' ',
'mid-l': ' ', 'mid-m': ' ', 'mid-r': ' ',
'low-l': ' ', 'low-m': ' ', 'low-r': ' '}
theBoardChoices = copy.deepcopy(theBoard)
printBoard(theBoard)
##The actual game
print(' ~ Hello player. What is your name? ~ ')
player1Name = input()
print(' ~ Hello ' + player1Name + ', welcome to tic-tac-toe ~ ')
playerScore = 0
CPUScore = 0
while theBoardChoices != None:
print(' ~ ' +player1Name + ', please type in one of the options for blank spaces: ~ ')
print('')
print(' , '.join(theBoardChoices.keys()))
playerInput = input()
playerChoice = playerInput.lower()
choiceCheck = theBoard.get(playerChoice,'bad choice')
if choiceCheck != 'bad choice':
if theBoard[playerChoice] == ' ':
theBoard[playerChoice] = 'X'
printBoard(theBoard)
del theBoardChoices[playerChoice]
if winCondition(theBoard) == 'win':
theBoardChoices = copy.deepcopy(theBoard)
playerScore = playerScore + 1
print(' ~ the current score is ' + str(playerScore) +'-' + str(CPUScore) + ' ~ ')
newGame(theBoardChoices)
continue
if theBoardChoices == {}:
theBoardChoices = copy.deepcopy(theBoard)
newGame(theBoardChoices)
continue
print(' ~ Please wait. Computer making a choice... ~ ')
time.sleep(random.randint(1,2))
computerChoice(theBoard)
if loseCondition(theBoard) == 'lose':
theBoardChoices = copy.deepcopy(theBoard)
CPUScore = CPUScore + 1
print(' ~ the current score is ' + str(playerScore) +'-' + str(CPUScore) + ' ~ ')
newGame(theBoardChoices)
continue
else:
print(' ~ that space is already taken ~ ')
Мои вопросы по этому коду следующие:
Мои функции условий выигрыша и проигрыша кажутся очень громоздкими, но я не мог придумать другого способа уменьшить их или, желательно, превратить их в одну функцию. Я подумал, что, может быть, я смогу сделать что-то вроде «если эти три ключа = x», а затем «x = O, то проиграют» или «x = X, то проиграют». Но я думаю, что мое понимание функций все еще немного туманно. Есть ли способ создать функцию, которая будет генерировать этот список условий выигрыша / проигрыша, используя мою настройку? Или мне пришлось бы сделать доску списком, а не словарем, чтобы использовать более математический подход, чтобы уменьшить это?
У меня куча вложенных
if
в моем разогнанном заявлении. Я чувствую, что мог бы больше использовать функции, чтобы уменьшить это, но даже в этом случае мне интересно, есть ли проблемы с этим.Я планировал попробовать / за исключением там, но к тому времени, когда я достиг кода, который у меня есть, я не мог найти способ сломать его, чтобы сделать его активным. Стоит ли мне это как-нибудь добавить? Мне кажется, что всегда иметь такую резервную систему — это хорошая привычка, даже если код кажется нерушимым. Или это только сделает код более беспорядочным и бесполезным?
В общем, я знаю, что от старых привычек трудно избавиться, и то же самое можно сказать и о вредных привычках. Я очень хотел бы знать, есть ли в моем коде признаки плохих вещей, которых я могу опасаться, чтобы пресечь их в зародыше, прежде чем продолжить. Я планирую вернуться к этому коду в будущем и добавить к нему (вариант с двумя игроками-людьми или против ЦП или с двумя лицами ЦП друг с другом, какой-то своего рода ИИ, возможность разрешить игрокам устанавливать размер доски и т. Д.).
В любом случае, я с нетерпением жду отзывов!
1 ответ
Как … МЕЖДУНАРОДНАЯ … Думаю, я может дать несколько рекомендаций / советов по этому поводу.
- При создании чего-либо не думайте о том, какие структуры данных или синтаксические функции вы собираетесь использовать. Вы можете выполнить поиск, например, «упражнения по словарю / циклам Python», чтобы попрактиковаться в этих основах, но при создании приложения разделите основную цель на шаги и, следовательно, закодируйте их.
Позже вы определенно получите эти основы, потому что вы будете реализовывать их почти в каждом проекте, который вы делаете.
Что касается кода, попробуйте разделить функции, которые связаны с одним и тем же, в разных файлах .py, например модули (если они вам нравятся), а затем используйте импортИспользуйте это не только для того, чтобы не создавать беспорядка, но и для легкого поиска ошибки или ошибки. Это сделает ваш код чище и удобнее для чтения.
СКОРО РЕДАКТИРУЕТСЯ: