Учим Python, делая крутые игры 2018. Invent your owncomputer gameswith python
![]()
|
Многострочный текст До сих пор весь текст в наших вызовах функции print() помещался на одной строке и ограничивался кавычками. Но если указать по три кавычки в начале и в конце строки, тогда можно ввести несколько строк текста. Это так называемый многострочный текст . Введите следующий код в интерактивной оболочке, чтобы увидеть при- мер работы с многострочным текстом: >>> fizz = '''Дорогая Алиса! В конце месяца я возвращаюсь к Кате. Твой друг, Борис''' >>> print(fizz) Дорогая Алиса! В конце месяца я возвращаюсь к Кате. Твой друг, Борис Игра «Царство драконов» 79 Обратите внимание на переносы строк во время вывода текста на экран. В многострочных блоках текста символы перехода на новую строку учиты- ваются в составе строк. Так как вы указываете три кавычки подряд, вам не нужно использовать экранирующие символы \n или кавычки другого типа. Такие переносы строк упрощают чтение, когда речь идет о больших объемах текста. Выполнение циклов с помощью инструкций while В строке 11 определяется другая функция, chooseCave() 11. def chooseCave(): Код этой функции предназначен для того, чтобы запросить у игрока, в какую пещеру он хочет войти, 1 или 2. Для осуществления выбора мы вос- пользовались инструкцией while — новым типом цикла, с которым вы еще не работали . В отличие от цикла for, который выполняет определенное количество раз (или итераций), цикл while повторяется до тех пор, пока выполняется опреде- ленное условие. Когда интерпретатор доходит до инструкции while, учитыва- ются условия, указанные после ключевого слова while. Если условие истинно, интерпретатор переходит к блоку while. Если условие ложно, блок while игно- рируется. Вам может показаться, что инструкция while почти то же самое, что и ин- струкция if. Выполнение блоков кода обеих инструкций осуществляется в случае, если условие истинно. Отличие в том, что когда интерпретатор до- стигает конца блока в цикле while, он возвращается к инструкции while, что- бы перепроверить условие. Взгляните на блок def функции chooseCave(), чтобы увидеть цикл while в действии: 12. cave = '' 13. while cave != '1' and cave != '2': В строке 12 создается новая переменная с именем cave, и ей присваивается пустая строка. Затем в строке 13 начинается цикл while. Функция chooseCave() должна убедиться, что игрок входит в пещеру 1 или 2, а не куда-либо еще. Цикл здесь служит для того, чтобы программа продолжала спрашивать игро- 80 Глава 5 ка, пока он не выберет один из двух допустимых вариантов. Этот процесс называется проверкой ввода. Условие также содержит новый оператор, с которым вы еще не знакомы — and . Так же, как — и * — это арифметические операторы, а == и != — операторы сравнения, оператор and — это логический оператор. Давайте более детально рассмотрим логические операторы. Логические операторы Логические операторы имеют дело с выражениями, которые могут быть либо истинными, либо ложными. Эти операторы сравнивают значения и воз- вращают логическое значение. Задумайтесь над предложением «У кошек есть усы, а у собак есть хво- сты». Выражение «У кошек есть усы» истинно, и «У собак есть хвосты» также истинно, таким образом, в целом предложение «у кошек есть усы, а у собак есть хвосты» — истинно. Но предложение «у кошек есть усы, а у собак есть крылья» будет ложно. Даже несмотря на истинность выражения, что «у кошек есть усы», у собак быть не может крыльев, поэтому выражение «у кошек есть усы, а у собак есть крылья» в целом — ложно. Согласно булевой логике, выражение может быть либо полностью истинным, либо абсолютно ложным. Из-за слова and (как со- юза «и») все предложение истинно только в том случае, если истинны обе его части. Если одна или обе части ложны, то и все предложение ложно. Оператор and Для оператора and в Python также необходимо, чтобы все логическое вы- ражение было истинно или ложно. Если логические значения по обеим сто- ронам от ключевого слова and истинны, выражение определяется как истин- ное. Если же одно или оба значения ложны, то и все выражение определяется как ложное . Введите следующие выражения с оператором and в интерактивной обо- лочке: >>> True and True True >>> True and False False >>> False and True False >>> False and False Игра «Царство драконов» 81 False >>> spam = 'привет' >>> 10 < 20 and spam == 'привет' True Оператор and может быть использован для вычисления любых двух логи- ческих выражений. В последнем примере выражение 10 < 20 истинно и вы- ражение spam == 'привет' также истинно, таким образом, два логических вы- ражения, объединенных оператором and, истинны. Если вы вдруг забудете принцип работы логических операторов, можете подсмотреть в следующую таблицу истинности, которая отражает все вари- анты комбинаций логических значений. Таблица 5.1 содержит все комбина- ции для оператора and. Таблица 5.1. Таблица истинности оператора and A and Б Результат True and True True True and False False False and True False False and False False Оператор or Оператор or похож на оператор and, за исключением того, что он принима- ет решение об истинности выражения, если одна (любая) из двух его частей истинна, либо если истинны обе части. Единственный раз, когда оператор or определяет выражение как ложное, — если ложны обе части выражения . Введите следующий код в интерактивной оболочке: >>> True or True True >>> True or False True >>> False or True True >>> False or False False >>> 10 > 20 or 20 > 10 True 82 Глава 5 В последнем примере 10 не превышает 20, но 20 больше 10, поэтому первая часть выражения определяется как ложная, а вторая — как истинная. Так как вторая часть выражения истинна, все выражение целиком становится истин- ным. В таблице 5.2 приведена таблица истинности оператора or. Таблице 5.2. Таблица истинности оператора or A or Б Результат True or True True True or False True False or True True False or False False Оператор not Вместо объединения двух значений оператор not работает только с одним значением. Оператор not вычисляет противоположное логическое значение: истинные выражения определяются как ложные, а ложные — как истинные . Введите следующий код в интерактивной оболочке: >>> not True False >>> not False True >>> not ('черное' == 'белое') True Оператор not также может использоваться для любого логического выра- жения. В последнем примере выражение 'черное' == 'белое' определяется как ложное. Вот почему выражение not ('black' == 'white') в результате истинно. Таблица истинности оператора not приведена в таблице 5.3. Таблице 5.3. Таблица истинности оператора not not A Результат not True False not False True Вычисление логических операций Взгляните снова на строку 13 игры «Царство драконов»: 13. while cave != '1' and cave != '2': Игра «Царство драконов» 83 Условие состоит из двух частей, связанных логическим оператором and. Условие истинно только в случае, если истинны обе его части. В первый раз, когда условие выполнения инструкций while было прове- рено, строка cave оставалась пустой, ''. Пустая строка не равна строке '1', поэтому левая часть выражения истинна. Пустая строка также не равна стро- ке '2', поэтому правая часть выражения также истинна. Таким образом, условие выглядит как True and True. Поскольку оба зна- чения True, все условие определяется как истинное, поэтому интерпретатор переходит к выполнению блока while, в котором программа будет пытаться присвоить значение переменной cave (вместо пустой строки). В строке 14 код запрашивает у игрока выбор пещеры. 13. while cave != '1' and cave != '2': 14. print('В какую пещеру вы войдете? (нажмите клавишу 1 или 2)') 15. cave = input() Код в строке 15 позволяет игроку ввести свой ответ и нажать клавишу Enter. Этот ответ сохраняется в переменной cave. После выполнения этого кода интерпретатор возвращается обратно к инструкции while и перепрове- ряет условие в строке 13. Если игрок ввел 1 или 2, тогда переменной cave будет присвоено значение либо '1', либо '2' (так как функция input() всегда возвращает строковое зна- чение). После этого условие становится ложным, и выполнение программы будет продолжаться после цикла while. Например, если пользователь ввел '1', тогда процесс вычисления будет выглядеть так: while cave != '1' and cave != '2': while '1' != '1' and cave != '2': while False and cave != '2': while False and '1' != '2' : while False and True : while False : Но если игрок ввел 3, 4 или ПРИВЕТ, такой ответ будет недействительным. Тогда условие останется истинным, и интерпретатор будет запускать код 84 Глава 5 в блоке while, чтобы снова спросить игрока. Программа продолжит просить игрока выбрать пещеру, пока он не введет 1 или 2. Это гарантирует, что после выполнения кода переменная cave будет содержать допустимый ответ. Возвращаемые значения функций Код в строке 17 содержит новую инструкцию return. 17. return cave Инструкция return размещается только внутри определяющих функцию блоков def, в нашем случае selectCave(). Помните, как функция input() считы- вает строку и возвращает строковое значение, введенное игроком? Функция selectCave() также вернет значение. Код в строке 17 возвращает значение, ко- торое хранится в переменной cave, — либо '1', либо '2'. После выполнения инструкции return интерпретатор сразу же выходит из блока def (так же, как после выполнения инструкции break программа за- вершает выполнение блока while). Интерпретатор возвращается к строке с вызовом функции. Сам вызов функции будет определять возвращаемое значение функции. Перейдите на мгновение к строке 38, где вызывается функция selectCave() 38. caveNumber = chooseCave() В строке 38, когда программа вызывает функцию chooseCave(), определен- ную в строке 11, вызов функции определяет строковое значение переменной cave , которое затем сохраняется в переменной caveNumber. Цикл while внутри функции chooseCave() гарантирует, что функция chooseCave() вернет только '1' или '2' в качестве возвращаемого значения. Таким образом, переменной caveNumber может быть присвоено только одно из этих двух значений. Глобальная и локальная области видимости переменных У переменных, которые создаются внутри функций, есть свои особенно- сти, как и в случае с переменной cave в функции chooseCave() (строка 12). 12. cave = '' Игра «Царство драконов» 85 Локальная область видимости создается каждый раз, когда вызывается функция. Любые переменные, которые она создаст, будут существовать в ло- кальной области. Представьте, что область видимости — это контейнер для переменных. Особенность локальных переменных в том, что они стираются из памяти, когда функция возвращается, и создаются заново при повторном вызове функции. Значение локальной переменной между вызовами функций не сохраняется. Переменные, которые создаются вне функций, существуют в глобальной области видимости. Может быть только одна глобальная область , и она соз- дается при запуске программы. Когда программа завершает работу, глобаль- ная область уничтожается, и все переменные в ней стираются. Переменная, которая существует в локальной области видимости , назы- вается локальной переменной, а переменная, которая существует в глобаль- ной области видимости, — соответственно, глобальной переменной. Перемен- ная может быть или локальной, или глобальной; она не может быть и той и другой одновременно. Переменная cave создается внутри функции chooseCave(). Это означает, что она создана в локальной области видимости функции chooseCave(). Она будет стерта при возврате функции chooseCave() и при повторном вызове функции chooseCave() будет создана заново. Локальные и глобальные переменные могут иметь одинаковые имена, так как это разные переменные, находящиеся в разных областях видимости. Что- бы это продемонстрировать, давайте напишем новую программу. def bacon(): spam = 99 # Создает локальную переменную с именем spam print(spam) # Выводит 99 spam = 42 # Создает глобальную переменную с именем spam print(spam) # Выводит 42 bacon() # Вызывает функцию bacon() и выводит 99 print(spam) # Выводит 42 Сначала мы создаем функцию с именем bacon(). Внутри функции bacon() мы создаем переменную spam и присваиваем ей значение 99 . В пункте мы вызываем функцию print() для вывода значения этой локальной переменной spam , которое равно 99. В пункте также присутствует глобальная перемен- ная с именем spam с присвоенным ей значением 42. Эта переменная глобаль- ная, так как находится за пределами функции. Когда глобальная переменная spam вызывается в функции print() ( ), выводится значение 42. Когда вызы- 86 Глава 5 вается функция bacon() в пункте , выполняются пункты и , создавая локальную переменную spam и присваивая, а затем выводя ее значение. Таким образом, вызов функции bacon() выводит значение переменной, равное 99. После возврата вызова функции bacon() локальная переменная spam уничто- жается из памяти. Если мы выведем значение переменной spam в пункте , то увидим значение глобальной переменной, равное 42. Если запустить этот код, получим следующее: 42 99 42 Позиция создания переменной определяет ее область видимости. Помни- те об этом при разработке своих программ. Параметры функции Следующая функция, определенная в программе «Царство драконов», на- зывается checkCave(). 19. def checkCave(chosenCave): Обратите внимание на текст chosenCave в круглых скобках. Это пара- метр — локальная переменная, которую использует код функции. Когда вы- зывается функция, аргументы вызова — это значения, присвоенные параме- трам. Давайте на мгновение вернемся к IDLE. Помните, что для некоторых вызовов функций, таких как str() или randint(), вы должны передать одно или несколько значений в круглых скобках. >>> str(5) '5' >>> random.randint(1, 20) 14 >>> len('привет') 6 Этот пример содержит функцию Python, которую вы еще не встречали — len() . Функция len() возвращает количество символов в строке в виде целого Игра «Царство драконов» 87 числа. В данном случае функция определила, что строка 'привет' содержит 6 символов. Когда вы вызываете функцию checkCave(), вы также передаете аргумент. Этот аргумент сохраняется в виде новой переменной с именем chosenCave, ко- торая является параметром функции checkCave(). Ниже представлена короткая программа, которая демонстрирует опреде- ление функции (sayHello) с параметром (name): def sayHello(name): print('Привет, ' + name + '. Твое имя состоит из ' + str(len(name)) + ' букв.') sayHello('Алиса') sayHello('Борис') spam = 'Катя' sayHello(spam) Когда вы вызовете функцию sayHello() с аргументом в круглых скоб- ках, аргумент присваивается параметру name, и код в функции выполняется. В функции sayHello() есть только одна строка кода, которая является вызо- вом функции print(). Внутри вызова функции print() находится несколько строк и переменная name, наряду с вызовом функции len(). В этом примере функция len() используется для подсчета количества символов в имени. Если вы запустите программу, то получите следующий результат: Привет, Алиса. Твое имя состоит из 5 букв. Привет, Борис. Твое имя состоит из 5 букв. Привет, Катя. Твое имя состоит из 4 букв. В случае каждого вызова функции sayHello() выводится приветствие и длина аргумента name. Обратите внимание, что поскольку строка 'Катя' при- своена переменной spam, код sayHello(spam) равносилен коду sayHello('Катя'). Отображение результатов игры Вернемся к исходному коду игры «Царство драконов». 20. print('Вы приближаетесь к пещере...') 21. time.sleep(2) 88 Глава 5 Модуль time содержит функцию sleep() , которая приостанавливает вы- полнение программы. В строке 21 передается целое значение 2, поэтому функция time.sleep() приостановит выполнение программы на 2 секунды. 22. print('Ее темнота заставляет вас дрожать от страха...') 23. time.sleep(2) Здесь программа выводит еще одну строку текста и ждет еще 2 секунды. Эти короткие паузы добавляют интриги в игру, что делает ее гораздо инте- реснее. В программе-шутнике из главы 4 вы вызывали функцию input() для приостановки программы, пока игрок не нажал клавишу Enter. Здесь игроку не требуется ничего делать, только подождать пару секунд. 24. print('Большой дракон выпрыгивает перед вами! Он раскрывает свою пасть и...') 25. print() 26. time.sleep(2) После небольшого ожидания программа определяет, в какой же пещере дружелюбный дракон. Определение пещеры с дружелюбным драконом В строке 28 вызывается функция randint(), которая в случайном порядке возвращает 1 или 2. 28. friendlyCave = random.randint(1, 2) Это целочисленное значение сохраняется в переменной friendlyCave и указывает на пещеру с дружелюбным драконом. 30. if chosenCave == str(friendlyCave): 31. print('...делится с вами своими сокровищами!') Код в строке 30 проверяет, является ли выбранная игроком пещера в пе- ременной chosenCave ('1' или '2') пещерой с дружелюбным драконом. Игра «Царство драконов» 89 Но значение переменной friendlyCave целочисленное, потому что функ- ция randint() возвращает целые числа. Вы не можете сравнивать строки и це- лые числа с оператором ==, потому что они никогда не будут равнозначны друг другу: '1' не равно 1, а '2' не равно 2. Таким образом, значение переменной friendlyCave передается функции str() , которая возвращает строковое значение переменной friendlyCave. Те- перь значения будут одного и того же типа данных и могут быть сопостав- лены друг с другом. Как вариант, мы могли бы также преобразовать значе- ние переменной chosenCave в целочисленное. Тогда код в строке 30 выглядел бы так: if int(chosenCave) == friendlyCave: Если значение переменной chosenCave равно значению переменной friendlyCave , условие определяется как истинное, а код в строке 31 сообщает игроку, что он выиграл сокровище. Теперь нам следует добавить код, который будет выполняться в случае, если условие ложно. Код в строке 32 — это инструкция else . 32. else: 33. print('...моментально вас съедает!') Инструкция else может находиться только после блока if. Блок else вы- полняется, когда условие инструкции if ложно. Это можно представить так: «Если это условие истинно, тогда выполнять блок if, а если ложно, то выпол- нить блок else». В нашем случае инструкция else запускается, когда значение переменной chosenCave не равняется значению переменной friendlyCave. Тогда выполняет- ся функция print() в строке 33 и сообщает игроку, что он съеден драконом. |