Учим Python, делая крутые игры 2018. Invent your owncomputer gameswith python
Скачать 6.56 Mb.
|
Создание блок-схем Ваша блок-схема необязательно должна выглядеть так, как показано на рис. 7.1. Главное, чтобы вы понимали свою блок-схему, — это вам поможет, когда вы начнете писать код. Вы можете спроектировать свою блок-схему, на- Проектирование игры «Виселица» с помощью блок-схем 113 чав с полей «Старт» и «Конец», как показано на рис. 7.2. Теперь подумайте о том, что происходит, когда вы играете в игру «Виселица». Для начала ком- пьютер задумывает секретное слово. Затем игрок угадывает буквы. Добавьте поля для этих действий, как показано на рис. 7.3. Новые поля в каждой блок- схеме обведены пунктиром. START END Старт Конец START Ask player to guess a letter END Come up with a secret word Старт Конец Задумываем секретное слово Просим игрока угадать букву Рис. 7.2. Начинаем проектировать Рис. 7.3. Добавляем дополнительные блок-схему с полей «Старт» и «Конец» два поля с описанием шагов в игре «Виселица» Но игра не заканчивается после того, как игрок угадывает букву. Про- грамме необходимо проверить, содержит ли секретное слово данную букву. Ветвление в блок-схемах Существуют два сценария: буква присутствует в слове, или ее в нем нет. Вы до- бавляете два новых блока в схему — по одному для каждого из сценариев разви- тия событий. Так создается разветвление в блок-схеме, как показано на рис. 7.4. START Ask player to guess a letter END Come up with a secret word Letter is in secret word Letter is not in secret word Старт Конец Задумываем секретное слово Просим игрока угадать букву Буква присутству- ет в загаданном слове Буквы нет в загаданном слове Рис. 7.4. Разветвление на две отдельные ветви 114 Глава 7 Если буква присутствует в секретном слове, следует проверить, возмож- но, игрок угадал все буквы и выиграл. Если буквы в слове нет, нужно про- верить, возможно, повешенный человек нарисован полностью, и игрок прои- грал. Добавьте поля для этих действий. Блок-схема теперь выглядит так, как показано на рис. 7.5. START Ask player to guess a letter END Come up with a secret word Letter is in secret word Letter is not in secret word Player guessed all letters and wins Player ran out of guesses and loses Конец Задумываем секретное слово Просим игрока угадать букву Буква присутству- ет в загаданном слове Игрок угадывает все буквы и побеждает Буквы нет в загаданном слове Игрок не угадывает и проигрывает Старт Рис. 7.5. После разветвления шаги продолжаются в разных направлениях Нет необходимости рисовать стрелку из поля «Буква присутствует в за- гаданном слове» к полю «Игрок не угадывает и проигрывает», так как невоз- можно проиграть, правильно угадав букву. Как и невозможно выиграть, не угадав букву, поэтому и для этого действия рисовать стрелку не нужно. Заканчиваем или начинаем игру сначала Когда игрок выиграл или проиграл, спрашиваем его, хочет ли он сыграть заново, чтобы отгадать другое слово. Если игрок не хочет играть, программа завершает работу; в противном случае программа продолжает выполнение и загадывает новое секретное слово. Это показано на рис. 7.6. Проектирование игры «Виселица» с помощью блок-схем 115 START Ask player to guess a letter END Come up with a secret word Letter is in secret word Letter is not in secret word Ask player to play again Player guessed all letters and wins Player ran out of guesses and loses Конец Задумываем секретное слово Просим игрока угадать букву Спрашиваем игрока, хочет ли он сыграть снова Буква присутству- ет в загаданном слове Игрок угадывает все буквы и побеждает Буквы нет в загаданном слове Игрок не угадывает и проигрывает Старт Рис. 7.6. Ветки блок-схемы с запросом, хочет ли игрок сыграть снова Следующая попытка Теперь блок-схема по большей части завершена, но нам все еще кое-чего недостает. Во-первых, игрок не угадывает букву только один раз; он продол- жает угадывать буквы до тех пор, пока не выиграет или не проиграет. Дори- суйте две новые стрелки, как показано на рис. 7.7. А как быть, если игрок назовет ту же самую букву снова? Вместо того что- бы проверять одну и ту же букву повторно, позвольте игроку загадать другую букву. Это новое поле показано на рис. 7.8. Если игрок дважды называет одну и ту же букву, блок-схема возвращает- ся к полю «Просим игрока угадать букву». 116 Глава 7 START Ask player to guess a letter END Come up with a secret word Letter is in secret word Letter is not in secret word Ask player to play again Player guessed all letters and wins Player ran out of guesses and loses Конец Задумываем секретное слово Просим игрока угадать букву Спрашиваем игрока, хочет ли он сыграть снова Буква присутству- ет в загаданном слове Игрок угадывает все буквы и побеждает Буквы нет в загаданном слове Игрок не угадывает и проигрывает Старт Рис. 7.7. Пунктирные линии показывают, что игрок может угадывать снова START Ask player to guess a letter END Come up with a secret word Player already guessed this letter Letter is in secret word Letter is not in secret word Ask player to play again Player guessed all letters and wins Player ran out of guesses and loses Конец Задумываем секретное слово Просим игрока угадать букву Игрок уже называл эту букву Спрашиваем игрока, хочет ли он сыграть снова Буква присутству- ет в загаданном слове Игрок угадывает все буквы и побеждает Буквы нет в загаданном слове Игрок не угадывает и проигрывает Старт Рис. 7.8. Добавляем шаг на тот случай, если игрок назвал букву, которую уже произносил ранее Проектирование игры «Виселица» с помощью блок-схем 117 Обратная связь с игроком Игроку необходимо знать, как он справляется. Программа должна ото- бразить рисунок повешенного человека и секретное слово (с пропусками вместо букв, которые игрок еще не угадал). Этот интерфейс позволит игроку понять, насколько он близок к победе или к провалу. Эта информация обновляется каждый раз, когда игрок пытается угадать букву. Добавьте блок «Показываем игроку виселицу и пропуски» в схему между блоками «Задумываем секретное слово» и «Просим игрока угадать букву», как показано на рис. 7.9. START Show drawing and blanks to player Ask player to guess a letter END Come up with a secret word Player already guessed this letter Letter is in secret word Letter is not in secret word Ask player to play again Player guessed all letters and wins Player ran out of guesses and loses Конец Задумываем секретное слово Показываем игроку виселицу и пропуски Просим игрока угадать букву Спрашиваем игрока, хочет ли он сыграть снова Буква присутству- ет в загаданном слове Игрок угадывает все буквы и побеждает Буквы нет в загаданном слове Игрок не угадывает и проигрывает Игрок уже называл эту букву Старт Рис. 7.9. Добавляем блок «Показываем игроку виселицу и пропуски» для обратной связи с игроком Выглядит неплохо! Эта блок-схема полностью описывает порядок игро- вого процесса приложения «Виселица». Блок-схема поможет вам не упустить ничего из того, что следует учесть при разработке игры. Заключение Вам может показаться скучным рисование блок-схем перед написанием программы. В конце концов, люди желают играть в игры, а не рассматривать блок-схемы! Но гораздо легче вносить изменения и выявлять проблемы, предполагая, как будет работать программа, прежде чем писать ее код. Если вы сразу приступите к написанию кода, то можете обнаружить про- блемы, требующие изменения кода, который уже написан, что будет пустой тратой времени и усилий. И каждый раз, когда вы изменяете свой код, вы рискуете наделать новых ошибок, внося изменения. Намного эффективней знать, что вы хотите построить в итоге, прежде чем приступать к строитель- ству. Теперь, когда у нас есть блок-схема, давайте создадим игру «Виселица» в главе 8! Написание кода игры «Виселица» 119 8 НАПИСАНИЕ КОДА ИГРЫ «ВИСЕЛИЦА» В этой главе вы узнаете много нового. Но не волнуйтесь, — прежде чем при- ступить к написанию кода игры, вы по- знакомитесь с новыми понятиями в ин- терактивной оболочке. Вы изучите методы — функции, назначенные объек- там. А также изучите новый тип данных — список. После того как эти концепции будут понятны, написать рабочий код для игры «Виселица» станет значительно проще. В ЭТОЙ ГЛАВЕ РАССМАТРИВАЮТСЯ СЛЕДУЮЩИЕ ТЕМЫ: • Списки • Оператор in • Методы • Строковые методы split() , lower(), upper(), startswith() и endswith() • Инструкции elif Исходный код игры «Виселица» Код этой игры немного длиннее предыдущих примеров, но большая его часть — это ASCII-код для прорисовки «повешенного». В редакторе файлов создайте новый файл, вы- брав команду меню File ⇒ New File (Файл ⇒ Новый файл). В открывшемся окне введите приведенный ниже исходный код и сохраните файл под именем hangman.py. Затем запустите программу, нажав кла- Make sure you’re using Python 3, not Python 2! УБЕ ДИТЕСЬ, ЧТО ИСПО ЛЬЗУЕТЕ PY THON 3, А НЕ PY THON 2! 120 Глава 8 вишу F5. Если при выполнении программы возникают ошибки, сравните код, который вы набрали, с оригинальным кодом с помощью онлайн-инструмента на сайте inventwithpython.com/diff/. hangman.py 1. import random 2. HANGMAN_PICS = [''' 3. +---+ 4. | 5. | 6. | 7. ===''', ''' 8. +---+ 9. | 10. | 11. | 12. ===''', ''' 13. +---+ 14. 0 | 15. | | 16. | 17. ===''', ''' 18. +---+ 19. 0 | 20. /| | 21. | 22. ===''', ''' 23. +---+ 24. 0 | 25. /|\ | 26. | 27. ===''', ''' 28. +---+ 29. 0 | 30. /|\ | 31. / | 32. ===''', ''' 33. +---+ 34. 0 | 35. /|\ | 36. / \ | Написание кода игры «Виселица» 121 37. ==='''] 38. words = 'аист акула бабуин баран барсук бобр бык верблюд волк воробей ворон выдра голубь гусь жаба зебра змея индюк кит кобра коза козел койот корова кошка кролик крыса курица лама ласка лебедь лев лиса лосось лось ля- гушка медведь моллюск моль мул муравей мышь норка носорог обезьяна овца окунь олень орел осел панда паук питон попугай пума семга скунс собака сова тигр тритон тюлень утка форель хорек черепаха ястреб ящерица'.split() 39. 40. def getRandomWord(wordList): 41. # Эта функция возвращает случайную строку из переданного списка. 42. wordIndex = random.randint(0, len(wordList) - 1) 43. return wordList[wordIndex] 44. 45. def displayBoard(missedLetters, correctLetters, secretWord): 46. print(HANGMAN_PICS[len(missedLetters)]) 47. print() 48. 49. print('Ошибочные буквы:', end=' ') 50. for letter in missedLetters: 51. print(letter, end=' ') 52. print() 53. 54. blanks = '_' * len(secretWord) 55. 56. for i in range(len(secretWord)): # заменяет пропуски отгаданными буквами 57. if secretWord[i] in correctLetters: 58. blanks = blanks[:i] + secretWord[i] + blanks[i+1:] 59. 60. for letter in blanks: # Показывает секретное слово с пробелами между буквами 61. print(letter, end=' ') 62. print() 63. 64. def getGuess(alreadyGuessed): 65. # Возвращает букву, введенную игроком. Эта функция проверяет, что игрок ввел только одну букву и ничего больше. 66. while True: 67. print('Введите букву.') 68. guess = input() 69. guess = guess.lower() 70. if len(guess) != 1: 71. print('Пожалуйста, введите одну букву.') 72. elif guess in alreadyGuessed: 73. print('Вы уже называли эту букву. Назовите другую.') 74. elif guess not in 'абвгдеежзийклмнопрстуфхцчшщъыьэюя': 75. print('Пожалуйста, введите БУКВУ.') 122 Глава 8 76. else: 77. return guess 78. 79. def playAgain(): 80. # Эта функция возвращает значение True, если игрок хочет сыграть заново; в противном случае возвращает False. 81. print('Хотите сыграть еще? (да или нет)') 82. return input().lower().startswith('д') 83. 84. 85. print('В И С Е Л И Ц А') 86. missedLetters = '' 87. correctLetters = '' 88. secretWord = getRandomWord(words) 89. gameIsDone = False 90. 91. while True: 92. displayBoard(missedLetters, correctLetters, secretWord) 93. 94. # Позволяет игроку ввести букву. 95. guess = getGuess(missedLetters + correctLetters) 96. 97. if guess in secretWord: 98. correctLetters = correctLetters + guess 99. 100. # Проверяет, выиграл ли игрок. 101. foundAllLetters = True 102. for i in range(len(secretWord)): 103. if secretWord[i] not in correctLetters: 104. foundAllLetters = False 105. break 106. if foundAllLetters: 107. print('ДА! Секретное слово - "' + secretWord + '"! Вы угадали!') 108. gameIsDone = True 109. else: 110. missedLetters = missedLetters + guess 111. 112. # Проверяет, превысил ли игрок лимит попыток и проиграл. 113. if len(missedLetters) == len(HANGMAN_PICS) - 1: 114. displayBoard(missedLetters, correctLetters, secretWord) 115. print('Вы исчерпали все попытки!\nНе угадано букв: ' + str(len(missedLetters)) + ' и угадано букв: ' + str(len(correctLetters)) + '. Было загадано слово "' + secretWord + '".') 116. gameIsDone = True 117. Написание кода игры «Виселица» 123 118. # Запрашивает, хочет ли игрок сыграть заново (только если игра завершена). 119. if gameIsDone: 120. if playAgain(): 121. missedLetters = '' 122. correctLetters = '' 123. gameIsDone = False 124. secretWord = getRandomWord(words) 125. else: 126. break Импорт модуля random Программа «Виселица» случайным образом выбирает слово из заранее определенного списка и предлагает угадать это слово игроку. Возможность такого случайного выбора обеспечивает модуль random, который импортиру- ется в первой строке кода. 1. import random Переменная HANGMAN_PICS во второй строке немного отличается от пере- менных, с которыми вы уже знакомы. Для понимания следующего кода вы должны познакомиться с несколькими дополнительными концепциями. Константы Строки с 2 по 37 — это одна длинная инструкция присваивания для пере- менной HANGMAN_PICS. 2. HANGMAN_PICS = [''' 3. +---+ 4. | 5. | 6. | 7. ===''', ''' --пропущено-- 37. ==='''] 124 Глава 8 Имя переменной состоит из прописных букв. Таким образом, по согла- шению, обозначаются константы. Константы — это переменные, значения которых не изменяются в процессе работы программы с момента их объявле- ния. Хотя вы можете изменить значение переменной HANGMAN_PICS также про- сто, как и любой другой переменной, имя прописными буквами напоминает вам, чтобы вы этого не делали. Как и в случае со всеми остальными соглашениями по оформлению кода, вы вовсе не обязаны им следовать. Но, соблюдая их, вы сделаете код более по- нятным для других программистов. Списки Значение переменной HANGMAN_PICS состоит из нескольких строк. Это на- зывается списком . В списках, в качестве элементов, могут содержаться раз- личные значения. Введите в интерактивную оболочку следующий код: >>> animals = ['аксолотль', 'аргонавт', 'астрильд', 'альберт'] >>> animals ['аксолотль', 'аргонавт', 'астрильд', 'альберт'] Список animals содержит четыре значения. Список значений начинается и заканчивается квадратными скобками — [] . Строковые значения (слова) помещаются в одинарные кавычки — '' и разделяются запятыми. Эти слова называются элементами списка. Каждый элемент HANGMAN_ PICS — это многострочное строковое значение. Списки позволяют хранить несколько значений, не назначая отдельную переменную для каждого из них. Без списков код выглядел бы примерно так: >>> animals1 = 'аксолотль' >>> animals2 = 'аргонавт' >>> animals3 = 'астрильд' >>> animals4 = 'альберт' Такой код был бы слишком сложен для восприятия и обслуживания, так как содержал бы сотни, а то и тысячи строк. А один список может содержать целый ряд значений. Написание кода игры «Виселица» 125 Доступ к элементам по их индексам Можно получить доступ к любому элементу списка , указав номер эле- мента в квадратных скобках в конце имени переменной. Номер в квадратных скобках называется индексом элемента. В Python первому элементу присваи- вается индекс 0. Второй элемент имеет индекс 1, третий — 2 и так далее. Так как индексы в списках начинаются с 0, а не с 1, их называют списками нуле- вого индекса. Пока вы находитесь в интерактивной оболочке и работаете со списком animals , введите по очереди: animals[0], animals[1], animals[2] и animals[3], что- бы посмотреть, что произойдет. >>> animals[0] 'аксолотль' >>> animals[1] 'аргонавт' >>> animals[2] 'астрильд' >>> animals[3] 'альберт' Напомню, что первый элемент списка 'аксолотль' хранится под индексом 0 , а не 1. Каждому элементу списка присваивается порядковый номер, начи- ная с 0. С помощью квадратных скобок можно использовать элементы списка как любые другие переменные. Например, если в интерактивной оболочке ввести animals[0] + animals[2], мы получим: >>> animals[0] + animals[2] 'аксолотльастрильд' Обе переменные с индексами 0 и 2 — строковые, поэтому они просто объ- единятся. Схематично это преобразование выглядит так: animals[0] + animals[2] 'aardvark' + animals[2] 'aardvark' + 'antelope' 'aardvarkantelope' 'аксолотль' 'аксолотль' 'астрильд' 'аксолотльастрильд' 126 Глава 8 Индекс за пределами диапазона и ошибка IndexError Если указать индекс, значение которого превышает количество записей в списке, выполнение программы будет прервано и появится сообщение об ошибке IndexError . Чтобы увидеть пример такой ошибки, укажите в интерак- тивной оболочке следующий код: >>> |