Учим Python, делая крутые игры 2018. Invent your owncomputer gameswith python
Скачать 6.56 Mb.
|
ИИ случайного хода против ИИ лучшего углового хода Давайте испробуем другую стратегию. В строке 274 замените вызов функ- ции getWorstMove() вызовом getRandomMove(). 274. move = getRandomMove(board, computerTile) Когда вы запустите программу сейчас, вывод будет выглядеть пример- но так: Приветствуем в игре "Реверси"! #1: X набрал 32 очков. O набрал 32 очков. #2: X набрал 44 очков. O набрал 20 очков. #3: X набрал 31 очков. O набрал 33 очков. #4: X набрал 45 очков. O набрал 19 очков. #5: X набрал 49 очков. O набрал 15 очков. -- пропуск-- #249: X набрал 20 очков. O набрал 44 очков. #250: X набрал 38 очков. O набрал 26 очков. Количество выигрышей X: 195 (78.0%) Количество выигрышей O: 48 (19.2%) Количество ничьих: 7 (2.8%) Алгоритм случайного хода getRandomMove() справился немного лучше, чем алгоритм худшего хода. Это логично, потому что разумный выбор обычно лучше, чем выбор хода наугад, но выбор наугад немного лучше, чем целена- правленный выбор худшего хода. Искусственный интеллект игры «Реверси» 317 ИИ лучшего углового-граничного хода против ИИ лучшего углового хода Выбор угловой клетки, если она доступна, — хорошая мысль, потому что фишка в углу не может быть перевернута. Помещение фишки в граничные клетки кажется неплохой идеей, так как существует меньше способов окру- жить и перевернуть такую фишку. Но разве это преимущество оправдывает отказ от ходов, которые переворачивают больше фишек? Давайте выясним, столкнув алгоритм лучшего углового угла и алгоритм лучшего углового- граничного хода. Измените алгоритм в строке 274, чтобы использовать функцию getCornerSideBestMove() 274. move = getCornerSideBestMove(board, computerTile) Затем снова запустите программу. Приветствуем в игре "Реверси"! #1: X набрал 27 очков. O набрал 37 очков. #2: X набрал 39 очков. O набрал 25 очков. #3: X набрал 41 очков. O набрал 23 очков. -- пропуск-- #249: X набрал 48 очков. O набрал 16 очков. #250: X набрал 38 очков. O набрал 26 очков. Количество выигрышей X: 152 (60.8%) Количество выигрышей O: 89 (35.6%) Количество ничьих: 9 (3.6%) Ух ты! Это неожиданно. Оказывается, выбор граничных клеток вместо клетки, переворачивающей больше фишек, — плохая стратегия. Преимуще- ство граничной клетки не перевешивает ущерб от переворачивания мень- шего количества фишек противника. Можем ли мы быть уверены в этих результатах? Давайте запустим программу еще раз, но сыграем 1000 партий, заменив код в строке 278 в файле AISim3.py на NUM_GAMES = 1000. Теперь про- грамма, наверное, будет работать на протяжении нескольких минут, вам же понадобилось бы несколько недель, чтобы сделать то же самое вручную! Вы увидите, что более точные статистические данные, полученные после 1000 партий, в целом согласующиеся статистике 250 партий. Кажется, выбор хода, переворачивающего наибольшее количество фишек, — более удачная идея, чем выбор граничной клетки. Таким образом, с помощью программирования мы выяснили, какая игровая стратегия работает лучше всего. Когда вы слышите, что ученые ис- пользуют компьютерные модели, имеется в виду именно это. Они использу- ют модели для воссоздания какого-то реального процесса, а затем проводят тесты в этой модели, чтобы узнать больше о реальном мире. Заключение В этой главе не описывалась новая игра, а были сымитированы различ- ные стратегии для игры «Реверси». Если бы мы считали, что граничные ходы в «Реверси» — это хорошая идея, нам пришлось бы провести недели, даже ме- сяцы, вручную играя в «Реверси» и внимательно записывая результаты, что- бы проверить, так ли это на самом деле. Но если нам известен способ научить компьютер самостоятельно играть в «Реверси», тогда мы можем сделать так, чтобы он испытывал различные стратегии за нас. Только подумайте, компью- тер выполняет миллионы строк нашей программы на Python за считанные секунды! Эксперименты с моделями игры «Реверси» могут помочь вам узнать больше о том, как играть в нее в реальной жизни. Вообще-то эта глава могла бы послужить основой для хорошего научного проекта. Вы могли бы исследовать, какой набор ходов приводит к наиболь- шему числу выигрышей в сравнении с другими наборами ходов, и могли бы составить гипотезу о том, какая стратегия лучшая. После тестирования не- скольких моделей, вы могли бы определить наверняка, какая стратегия рабо- тает лучше всего. С программированием вы можете сделать проект на основе моделирования любой настольной игры! И все это потому, что вы знаете, как поручить компьютеру делать это, шаг за шагом, строка за строкой. Вы умеете общаться на языке компьютера, заставлять его обрабатывать для вас боль- шие объемы данных и выполнять сложные числовые расчеты. Это была последняя текстовая игра в этой книге. Конечно, такие игры могут быть интересны, хоть они и просты. Но в большинстве современных игр используется графика, звук и анимация, что делает игру более захваты- вающей. В следующих главах этой книги вы узнаете, как создавать игры с гра- фикой, используя модуль Python под названием pygame. Создание графики 319 17 СОЗДАНИЕ ГРАФИКИ До сих пор все наши игры были исклю- чительно текстовые. Текст отображался на экране при выводе, текст набирался игроком при вводе. Использование толь- ко текста упрощает процесс обучения программированию. В этой главе мы созда- дим более занимательные программы с графикой, исполь- зуя модуль pygame. Главы 17–20 научат вас использовать модуль pygame для разработки игр с графикой, анимацией, звуком и вводом с помощью мыши. В этих главах мы напишем исходный код для простых программ, отражающих методы pygame . Затем, в главе 21? мы соберем все выученные ранее идеи для созда- ния игры. В ЭТОЙ ГЛАВЕ РАССМАТРИВАЮТСЯ СЛЕДУЮЩИЕ ТЕМЫ: • Установка pygame • Цвета и шрифты в pygame • Сглаженная графика • Атрибуты • Типы данных pygame.font.Font , pygame.Surface, pygame.Rect и pygame. PixelArray • Функции-конструкторы • Функции рисования модуля pygame • Метод blit() для объектов поверхности • События 320 Глава 17 Установка pygame Модуль pygame помогает разработчикам создавать игры, упрощая отобра- жение графики на экране компьютера или процесс добавления музыки в про- граммы. Модуль не поставляется с Python, но, как и сам Python, его можно установить бесплатно. Для этого нужно запустить оболочку командной стро- ки (а не среду разработки Python!) от имени администратора (командная строка в Windows и программа Терминал (Terminal) в macOS/Linux) и выпол- нить следующую команду: >>> pip3 install pygame Система pip самостоятельно скачает и установит подходящую версию pygame . Если возникает ошибка установки, может потребоваться указать пол- ный путь к исполняемому файлу системы pip. К примеру, в Windows это де- лается так: >>> C:\Python36\Scripts\pip3 install pygame Чтобы проверить правильность установки, введите в интерактивной обо- лочке Python следующую команду: >>> import pygame Если после нажатия клавиши Enter ничего не происходит, значит, pygame был установлен успешно. Если появляется ошибка ImportError: No module named pygame , попробуйте переустановить pygame (и убедитесь, что вы правиль- но ввели команду import pygame). Примечание. При написании кода программ Python не сохраняйте файл под именем pygame.py. Если вы это сделаете, строка import pygame импорти- рует ваш файл вместо настоящего модуля pygame и код перестанет работать. Привет, pygame! Для начала мы напишем новую pygame-программу «Привет, мир!», подоб- ную той, которую вы создавали в начале книги. На этот раз вы будете ис- пользовать модуль pygame, чтобы надпись «Привет, мир!» появилась в графи- Создание графики 321 ческом окне, а не в виде текста. В этой главе мы будем использовать модуль pygame только для того, чтобы отображать в окне фигуры и линии, но скоро вам пригодятся эти навыки, когда вы будете создавать свою первую анима- ционную игру. Модуль pygame плохо совместим с интерактивной оболочкой, поэтому пи- сать программы с помощью pygame вы можете только в редакторе. Кроме того, в программах pygame не используются функции print() или input() . Там нет вводимого или выводимого текста. Вместо этого pygame по- казывает вывод путем отображения графики и текста в отдельном окне. Ввод в модуле pygame осуществляется с клавиатуры и мыши посредством событий, описанных в разделе «События и игровой цикл» в конце этой главы. Пример запуска pygame-программы «Привет, мир!» Когда вы запускаете графическую программу «Привет, мир!», должно появиться новое окно, показанное на рис. 17.1. Рис. 17.1. Pygame -программа «Привет, мир!» Самое удобное в использовании окна вместо консоли заключается в том, что текст может появляться в любом месте окна, а не только после текста, который вы вывели до этого. Шрифт может быть любого цвета и размера. Окно представляет собой что-то вроде холста, и вы можете рисовать на нем все, что пожелаете. 322 Глава 17 Исходный код pygame-программы «Привет, мир!» В редакторе файлов создайте новый файл, вы- брав команду меню File ⇒ New File (Файл ⇒ Новый файл). В открывшемся окне введите приведенный ниже исходный код и сохраните файл под именем pygameHelloWorld.py. Затем нажмите клавишу F5 и запустите программу. Если при выполнении про- граммы возникают ошибки, сравните код, который вы набрали, с оригинальным кодом с помощью онлайн-инструмента на сайте inventwithpython. com/diff/. pygameHelloWorld.py 1. import pygame, sys 2. from pygame.locals import * 3. 4. # Настройка pygame. 5. pygame.init() 6. 7. # Настройка окна. 8. windowSurface = pygame.display.set_mode((500, 400), 0, 32) 9. pygame.display.set_caption('Привет, мир!') 10. 11. # Назначение цветов. 12. BLACK = (0, 0, 0) 13. WHITE = (255, 255, 255) 14. RED = (255, 0, 0) 15. GREEN = (0, 255, 0) 16. BLUE = (0, 0, 255) 17. 18. # Назначение шрифтов. 19. basicFont = pygame.font.SysFont(None, 48) 20. 21. # Настройка текста. 22. text = basicFont.render('Привет, мир!', True, WHITE, BLUE) 23. textRect = text.get_rect() 24. textRect.centerx = windowSurface.get_rect().centerx 25. textRect.centery = windowSurface.get_rect().centery 26. 27. # Нанесение на поверхность белого фона. Make sure you’re using Python 3, not Python 2! УБЕ ДИТЕСЬ, ЧТО ИСПО ЛЬЗУЕТЕ PY THON 3, А НЕ PY THON 2! Создание графики 323 28. windowSurface.fill(WHITE) 29. 30. # Нанесение на поверхность зеленого многоугольника. 31. pygame.draw.polygon(windowSurface, GREEN, ((146, 0), (291, 106), (236, 277), (56, 277), (0, 106))) 32. 33. # Нанесение на поверхность синих линий. 34. pygame.draw.line(windowSurface, BLUE, (60, 60), (120, 60), 4) 35. pygame.draw.line(windowSurface, BLUE, (120, 60), (60, 120)) 36. pygame.draw.line(windowSurface, BLUE, (60, 120), (120, 120), 4) 37. 38. # Нанесение на поверхность синего круга. 39. pygame.draw.circle(windowSurface, BLUE, (300, 50), 20, 0) 40. 41. # Нанесение на поверхность красного эллипса. 42. pygame.draw.ellipse(windowSurface, RED, (300, 250, 40, 80), 1) 43. 44. # Нанесение на поверхность фонового прямоугольника для текста. 45. pygame.draw.rect(windowSurface, RED, (textRect.left - 20, textRect.top - 20, textRect.width + 40, textRect.height + 40)) 46. 47. # Получение массива пикселов поверхности. 48. pixArray = pygame.PixelArray(windowSurface) 49. pixArray[480][380] = BLACK 50. del pixArray 51. 52. # Нанесение текста на поверхность. 53. windowSurface.blit(text, textRect) 54. 55. # Отображение окна на экране. 56. pygame.display.update() 57. 58. # Запуск игрового цикла. 59. while True: 60. for event in pygame.event.get(): 61. if event.type == QUIT: 62. pygame.quit() 63. sys.exit() Импорт модуля pygame Давайте рассмотрим каждую из этих строк кода и узнаем, что они делают . 324 Глава 17 Сначала вам нужно импортировать модуль pygame, чтобы получить воз- можность вызывать его функции. Вы можете импортировать несколько мо- дулей в одной строке, разделяя имена модулей запятыми. Код в строке 1 им- портирует модули pygame и sys. 1. import pygame, sys 2. from pygame.locals import * Код во второй строке импортирует модуль pygame.locals. Этот модуль со- держит много констант, которые вы будете использовать с pygame, таких как QUIT (помогает выйти из программы) и K_ESCAPE (обрабатывает нажатие кла- виши Esc). Код в строке 2 также позволяет вам использовать модуль pygames.locals без дополнительного указания кода pygames.locals. перед каждым методом, константой или чем-либо еще, что вы вызываете из модуля. Если вместо кода import sys указать from sys import *, можно вызывать просто функцию exit() вместо sys.exit(). Но в большинстве случаев лучше всего использовать полное имя функции, чтобы знать, в каком модуле она находится. Инициализация pygame Код любой pygame-программы должен содержать вызов pygame.init() после импорта модуля pygame, но перед вызовом любых других функций pygame 4. # Настройка pygame. 5. pygame.init() Эта операция инициализирует pygame, то есть подготавливает модуль к использованию. Вам не нужно знать, что делает init(); просто запомните, что нужно выполнить такой вызов, прежде чем использовать любые другие функции pygame. Настройка окна pygame Код в строке 8 создает окно графического интерфейса пользователя (англ. GUI, graphical user interface) , вызывая метод set_mode() в модуле pygame.display. Создание графики 325 (display — это модуль в составе модуля pygame. Даже у модуля pygame есть свои собственные модули!) 7. # Настройка окна. 8. windowSurface = pygame.display.set_mode((500, 400), 0, 32) 9. pygame.display.set_caption('Привет, мир!') Эти методы помогают настроить окно, в котором будет работать pygame. Как и в игре «Охотник за сокровищами», эти окна используют систему коор- динат, но их система координат организована в пикселях. Пиксель — наименьшая точка на экране вашего компьютера. Пиксель может быть окрашен в любой цвет. Все пиксели на экране работают вместе, отображая изображения, которые вы видите. Мы создадим окно размером 500 пикселей в ширину и 400 пикселей в высоту с помощью кортежа. Кортежи Кортежи подобны спискам, за исключением того, что кортежи использу- ют круглые скобки вместо квадратных и, как и строки, кортежи нельзя изме- нять. Для примера введите следующие команды в интерактивной оболочке: >>> spam = ('Жизнь', 'Вселенная', 'Бытие', 42) >>> spam[0] 'Жизнь' >>> spam[3] 42 >>> spam[1:3] ('Вселенная', 'Бытие') >>> spam[3] = 'привет' Traceback (most recent call last): File " ", line 1, in spam[3] = 'привет' TypeError: 'tuple' object does not support item assignment Как видно из примера, если требуется получить только один элемент кор- тежа или диапазон элементов , то по-прежнему используете квадратные скобки, как и в случае со списком. Однако если вы попытаетесь заменить эле- мент с индексом 3 строкой 'привет' , Python выдаст ошибку . 326 Глава 17 Мы будем использовать кортежи для настройки окон pygame. У метода pygame.display.set_mode() есть три параметра. Первый — это кортеж из двух целых чисел для ширины и высоты окна в пикселях. Чтобы создать окно раз- мером 500×400 пикселей, нужно использовать кортеж (500, 400) для первого аргумента функции set_mode(). Второй и третий параметры касаются проблем, выходящих за рамки этой книги. Просто передайте 0 и 32 соответст венно. Объекты поверхности Функция set_mode() возвращает объект pygame.Surface (который мы для краткости будем называть объектом Surface). Объект — это экземпляр не- которого типа данных, имеющего свои методы. Например, строки в Python являются объектами, потому что они содержат данные (саму строку) и у них есть методы (например, lower() и split()). Объект Surface представляет окно. Переменные хранят ссылки на объекты так же, как они хранят ссылки для списков и словарей (см. раздел «Ссылки на список» в главе 10). Метод set_caption() в строке 9 назначает заголовок окна — 'Привет, мир!'. Заголовок находится в верхнем левом углу окна. Работа с цветом У пикселей есть три основных цвета: красный, зеленый и синий. Объеди- няя эти три цвета в различных пропорциях (что и делает монитор вашего ком- пьютера), вы можете получить любой оттенок. В pygame оттенки представлены кортежами из трех целых чисел. Они называются цветами RGB , и в нашей программе мы будем их использовать для окрашивания пикселей. Посколь- ку неудобно указывать кортеж из трех чисел каждый раз, когда требуется ис- пользовать определенный оттенок, мы создадим константы для хранения кор- тежей, названные по цвету, который представляет соответствующий кортеж. 11. # Назначение цветов. 12. BLACK = (0, 0, 0) 13. WHITE = (255, 255, 255) 14. RED = (255, 0, 0) 15. GREEN = (0, 255, 0) 16. BLUE = (0, 0, 255) Первое значение в кортеже определяет, какое количество красного содер- жится в данном оттенке. Значение 0 сообщает о том, что в оттенке нет красного, а значение 255 указывает на максимальное количество красного цвета. Второе Создание графики 327 значение предназначено для зеленого цвета, третье — для синего. Эти три целых числа образуют кортеж RGB. Например, кортеж (0, 0, 0) не содержит ни крас- ного, ни зеленого, ни синего цветов. Полученный цвет полностью черный, как в строке 12. Кортеж (255, 255, 255) содержит максимальное количество красно- го, зеленого и синего цветов, что в сочетании дает белый цвет, как в строке 13. Мы также будем использовать красный, зеленый и синий цвета, которые на- значаются в строках с 14 по 16. Кортеж (255, 0, 0) содержит максимальное коли- чество красного, и поскольку там нет ни зеленого, ни синего, то в результате бу- дет получен цвет. Аналогично (0, 255, 0) — зеленый цвет, а (0, 0, 255) — синий. Вы можете смешивать количества красного, зеленого и синего цветов и по- лучать любой оттенок. Таблица 17.1 представляет некоторые часто используе- мые цвета и их соответствующие значения RGB. На веб-сайте |