Пользователь
0,0
рейтинг
28 декабря 2012 в 11:15

Разработка → Обучение программированию через игру или как быстро собрать весь мёд из песочницы tutorial

Несколько лет назад я начал преподавать свой любимый язык python школьникам. И возникла такая задача: рассказать про объектную модель, но что бы это было не скучно и как можно нагляднее. И тут меня не сразу, но осенило — пчёлы!



Идея простая: все на свете суть объекты (и субъекты, но сейчас не об этом). Программисты народ ленивый, не стали выдумывать что-то особенное и выдумали себе аналоги реальных объектов. Все выдуманные (виртуальные, другими словами) объекты программисты объединили в классы и в классе описывают общее для однотипных объектов. Потом программисты создают экземпляры виртуальных объектов и запускают их работать.То есть в программах у программистов работают объекты, а не сами программисты. Объекты живут своей виртуальной жизнью, толкают и дергают друг друга, отдают и принимают что-нибудь (данные) друг у друга. Задача программиста сделать так, что бы объекты не просто толкались и дергались, а выполнили нужную программисту задачу.

Мы тоже сделаем модель пасеки и поупражняемся в управлении объектами-пчёлами. К моменту начала пчеловодства обучаемые должны знать основы языка, его основные конструкции и операторы, иметь базовые представления о классах.

Итак — пчела:
class MyBee(Bee):
    pass
Она не просто так сама по себе, она принадлежит к общему классу «Пчёлы». В python это реализуется наследованием: в скобочках указан родительский класс. В классе Bee есть все что нужно для жизни виртуальной пчелы — она рождается, может двигаться и нести мёд.

class MyBee(Bee):
    def __init__(self):
        Bee.__init__(self)
        self.move_at(Point(200,300))
    def on_stop_at_flower(self, flower):
        self.load_honey_from(flower)
    def on_honey_loaded(self):
        if self.honey <= 100:
            self.move_at(Point(300,400))
        else:
            self.move_at(self.my_beehive)

Помимо пчелы в нашем виртуальном мире есть цветы и улей. В цветах есть мёд, его надо собрать и отнести в улей. Пчела может нести до 100 единиц мёда, цветок же содержит от 100 до 200 единиц. Улей хранит весь принесённый в него мёд, но не больше некоего предела (зависит от количества цветов на пасеке). Количество мёда, которое содержит в себе объект, отображается через свойство объекта и называется honey. Что бы посмотреть количество меда у пчелы надо написать так — bee.honey (у цветка — flower.honey, у улья — beehive.honey). Свойства объекта часто называются атрибутами. У нашей пчелы есть еще атрибуты: flowers — список всех цветов на пасеке и my_beehive — родной улей.

С помощью атрибутов мы можем посмотреть состояние объекта. А вот изменить состояние объекта можно с помощью методов. Методы — это такие рычажки, дернул за один — объект полетел, дернул за другой — остановился. Как можно изменить состояние нашей пчелы?
Принимая и загружая мёд, к примеру:
self.load_honey_from(source)  # получить мёд от другого объекта
self.unload_honey_to(target)  # отдать мёд объету
Принимать мёд можно от любого объекта и загружать тоже в любой объект: цветок, улей, и даже пчелу. Мы пишем self впереди каждого метода, потому что как бы даем команду «Грузи мёд!» себе (self — англ. «я сам») изнутри кода класса. Но можно отдать команду и другому объекту:
 other_bee.load_honey_from(self) 
если конечно он нас послушается (мы авторизованы давать ему команды). Аналогично реализуется команда движения:
self.move_at(target)  # двигаться к указанной цели
в качестве цели можно указать точку на экране или другой объект (берутся координаты объекта на момент отдачи команды)

А как окружающий мир взаимодействует с нашей пчелой? Он посылает ей сигналы, толкает в бок: «Смотри, что случилось!» Сигналы — это методы, которые вызывает окружающий мир для объекта-пчелы. Сигналы на нашей пасеке такие:
    def on_stop_at_flower(self, flower):
        """ пчела прилетела к цветку """
        pass
    def on_stop_at_beehive(self, beehive):
        """ пчела прилетела к улью """
        pass
    def on_honey_loaded(self):
        """ мёд в пчелу загружен """
        pass
    def on_honey_unloaded(self):
        """ мёд из пчелы разгружен """
        pass
И как раз в эти узловые для жизни пчелы моменты она может принять решение, что же ей делать дальше. В эти момент ход игры останавливается, как в матрице, и можно спокойно все обдумать, просмотреть все доступные объекты со всех сторон и найти женщину в красном нужный цветок. Обратите внимание: отдача команды self.move_at(finded_flower) не отправит пчелу немедленно к цветку, это просто пометка «лететь туда-то после выхода из события». Последующий вызов self.move_at(other_flower) изменит пометку и пчела полетит к последнему указанному объекту.
Именно в теле методов-сигналов реализуется искусственный интеллект пчелы. Вот, например, код поведения пчелы из мультика (файл my_bee.py)
from beegarden import Bee  # импортируем нужное из библиотек

class MyBee(Bee):
    def __init__(self):
        """ рождение пчелы """
        Bee.__init__(self)
        self.flower = self.flowers.pop()   # выбираем нашим первый попавшийся цветок
        self.move_at(self.flower)  # летим к нему

    def on_stop_at_flower(self, flower):
        """ пчела прилетела к цветку """
        if flower.honey > 0:  # если в цветке еще есть мёд
            self.load_honey_from(flower)  # забираем его
        else:  # цветок пуст
            self.go_next_flower()  # летим к другому цветку, если он есть

    def on_honey_loaded(self):
        """ мёд в пчелу загружен """
        if self.honey == 100:  # полностью ли я заполнен?
            self.move_at(self.my_beehive)   # да, летим к улью
        else:  # еще осталось место
            self.go_next_flower()  # летим к другому цветку, если он есть

    def on_stop_at_beehive(self, beehive):
        """ пчела прилетела к улью """
        self.unload_honey_to(beehive)  # просто разгружаем мёд в улей

    def on_honey_unloaded(self):
        """ мёд из пчелы разгружен """
        self.go_next_flower()  # летим к другому цветку, если он есть

    def go_next_flower(self):
        """ поиск следующего цветка """
        if not self.flower.honey:   # в моём цветке больше нет мёда
            if not self.flowers:  # и цветов не осталось
                if self.honey:  # а во мне есть мёд
                    self.move_at(self.my_beehive)  # летим к улью
                return   # цветов с мёдом больше нет, стоп
            else:  # остались цветы с мёдом 
                self.flower = self.flowers.pop()   # берем следующий из списка
        self.move_at(self.flower)  # и летим к своему цветку
Пчелы должны жить в игровом мире, давайте его создадим
from beegarden import GameEngine, Scene  # импортируем нужное из библиотек
from my_bee import MyBee  # импортируем код класса пчелы

game = GameEngine("My little garden")  # создаем движок нашей игры
scene = Scene(flowers_count=3)  # создаем нужную сцену

bee = MyBee()  # вот оно - рождение пчелы!

game.go()  # и запускаем наш виртуальный мир крутиться...

Но просто собирать мёд в одиночку не интересно, давайте вместе с друзьями
from beegarden import GameEngine, Scene
from my_bee import MyBee

game = GameEngine("My little garden")
scene = Scene(flowers_count=20)  # цветов побольше

bees = []  # список наших пчёл
for i in range(5):  # цикл создания 5 пчёл
    bee = MyBee()  # создаем новую
    bees.append(bee)  # и добавляем её к списку

game.go()  # теперь мы - банда

А потом посоревнуемся с другим ульем

Слева — рабочие пчелы, каждая обрабатывает свой цветок. Справа — жадные, летят к самому тучному. Жадность проигрывает, отчего, интересно?…

Я предлагаю сообществу взять шашки в руки и сделать разминку перед новым годом — кто быстрее и больше всех соберет мёда? Тем более что есть примета: перед новым годом релизы ставить — начальство злить, новое начинать — себя не любить, старое править — со скуки помереть.

Код проекта можно скачать с гитхаба beegarden Для запуска нужен python старше 2.6 и Pygame старше 1.9, тестировалась под Ubuntu и Windows 7/Vista. Для Ubuntu установить Pygame можно так
sudo apt-get install python-pygame
Для Windows 7/Vista: нужно поставить сам пайтон python-2.7.3.msi и потом пайгейм pygame-1.9.1.win32-py2.7.msi
Шашки в руки брать так: клонировать проект в отдельную папку (или просто скачать и раззиповать архив) там смотреть/редактировать файлы my_bee.py и run.py. Соревноваться можно друг с другом, а так же с написанными мной алгоритмами РабочейПчелы и ЖаднойПчелы.

Удачи в наступающем!
Вадим Шандринов @suguby
карма
19,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (31)

  • 0
    Чем-то напоминаетBees! от babaroga для моего Zune
    • 0
      Там тоже можно писать алгоритм поведения?
      • +9
        нет, но пчелы такие же обсаженные
  • +2
    По мне это прекрасно. На моей памяти дети быстро осваивали консоль в играх, какой бы сложной она не была. Притом не просто запоминают машинально, а понимают. Так что игры — один из верных подходов.
    • +1
      Сложность в том что для написания игры или её части (алгоритма) ученики должны знать базовые понятия. Но помогает визуальность — для начала рисуем кружочки в цикле и т.п. Потом — пчеловодство, а во втором семестре — танки %)
    • 0
      а какую консоль, в каких играх? насколько сложных? интересно :)
  • 0
    Вспоминаю «Логомиры» в своей школе. Вот они привили мне вкус к программированию класса эдак с третьего.
    Там, кстати, программируются тоже всяческие животные, а код выглядит примерно как «вперёд 100, налево 90, натянуть скин бегущей лошади 1, натянуть скин бегущей лошади 2».
    • 0
      У нас младших тренируют с помощью тараканов
      • 0
        Кукарача! Эх, детство… С Роботландии и начинал…
  • 0
    промахнулся с ответом — как удалить коммент?
    • 0
      <Комент был удалён в связи с тем, что его автора бес попутал, когда он его писал.>

      Обычно люди делают так.
      • 0
        НЛО прилетело и удалило этот комментарий.
        • 0
          Нужно быть очень дерзким, чтобы просить НЛО удалить комментарий, который ты случайно отправил не в ту ветку. =)
        • 0
          А, понял! То есть я сам себе НЛО, да?
  • +2
    Побольше бы таких статей! :)
  • +1
    Жадные пчёлы проигрывают во многом из-за своей излишней синхронности, но практически выравниваются с обычными, если добавить к поиску цветка присутствующую у обычных проверку:
    if self.is_other_bee_target(flower):
    continue
    • +1
      Ага. Там много где есть что улучшить ;) Выкладывайте свой алгоритм.
  • +2
    Никто не делает так много для страны, как те, кто занимается образованием молодежи, причем образованием актуальным и современным. Огромное уважение, огромное спасибо.
    • +1
      Даже не знаю что сказать. На самом деле я простой программер, с некоторого времени потянуло передать опыт, а рядом нашлась Мытищинская Школа Программистов, поговорил с директором, он согласился. Теперь раз в неделю преподаю, дело сложное, но интересное. Так что — эта дорога открыта для всех :)
      • 0
        Нахожусь в, несколько, схожей ситуации — делаю для университета справочник флоры высших сосудистых растений на основе простенького питоновского фреймворка «camelot».
        Сам «ни разу не программист :)»(асу-шник), на питоне раньше писал в основном скрипты для парсинга логов… но глядя на чудовищные манипуляции друзей-преподавателей и их студентов с электронными таблицами, для этих целей = «сердце кровью обливается».
  • 0
    А кого в школе Паскалем учили?
  • 0
    Уважаемый suguby у вас получилось отличное учебное пособие: большое человеческое спасибо!
    У вас получилось просто и в игровой форме объяснить достаточно сложные понятия — было бы здорово, если бы проект и дальше развивался :)
    • +1
      Думаю еще несколько статей опубликовать, про рекурсию «на пальцах», к примеру.
      • 0
        Тоже в форме учебного пособия?
        • 0
          ага, в таком же стиле. вообще есть курс по пайтону, но он не оформлен, буду вот так постепенно оформлять.
          • 0
            Спасибо, буду следить за вашими публикациями.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      как по Вашему должен выглядеть данный код?
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      А как тогда подключать «движок»? Кто будет посылать все эти on_honey_loaded и т.п.? В вашем случае нужно регистрировать пчел в сцене игры
      bee = Bee()
      scene.add(bee)
      
      А если цикл? А если динамическое создание пчёл?

      мне кажется что наследованием это реализуется элегантнее: есть некий всеобщий класс «пчелы», который живет в виртуальном мире, умеет летать и проч. мы — эти же «пчёлы», но чуть другие — у нас есть алгоритм поведения: мы расширяем всеобщий класс пчёл.
      • НЛО прилетело и опубликовало эту надпись здесь

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.