3. неделя

Super Karel

Собственные функции, ветвление, логические циклы, бесконечный цикл

Тема лабораторной

На этом занятии вам предстоит продолжать работать с супер роботом Карлом. Вы будете создавать для Карла простые программы, с помощью которых вы познакомитесь с другими командами и сенсорами робота. Также вы создадите бесконечный цикл.

Цели

  1. Освоить возможность управления роботом с помощью всех доступных команд и сенсоров.
  2. Как можно больше использовать собственные функции, if else ветвления и логические циклы.
  3. Познакомиться с работой бесконечных циклов
  4. Продолжать работать в редакторе Vim

Инструкции

Шаг 1: Setup

Задача 1.1

Создайте каталог ~/labs/lab03.

Задача 1.2

В каталог ~/labs/lab03 скопируйте файл, нужный для компиляции программы робота Карла: Makefile.

У вас в распоряжении следующие команды:

  • cp копирует файлы
  • cp -r копирует не только файлы, но и каталоги (включая и подкаталоги)
  • ls выписать содержимое каталога
  • mkdir _название_ создать каталог
  • cd _название_каталога_ изменить текущий каталог на другой
  • rm -r_название_ стирает все (включая подкаталоги)

Предупреждение

С помощью rm -r nazov можно удалить и то, что вы не хотели. Именно поэтому рекомендуем перед удалениями ввести команду ls в каталоге, чтобы вы были уверены в том, что будет удалено. В командной строке Корзины нет.

Комментарий

Файл Makefile можете найти в каталоге с прошлого занятия ~/labs/lab02. Не забудьте о том, что его следует скопировать в каталог ~/labs/lab03.

Шаг 2: Eternal

На этом этапе вы познакомитесь с другими командами и сенсорами робота Карла, а также создадите бесконечный цикл.

Задача 2.1

Создайте файл eternal.c, в котором робот будет постоянно ходить меж противоположных стен. Код протестируйте на карте empty.kw.

Бесконечный цикл - это такой цикл, в котором условия для его следующей итерации всегда правдиво. Способов для решения подобной задачи несколько.

Для увеличения скорости робота можете использовать команду set_step_delay(). Чем меньше значения, тем у Карла более высокая скорость. Изначальная скорость робота - set_step_delay(1000).

Задача 2.2

Измените код eternal так, чтобы Карл постоянно передвигался с севера на юг и обратно, несмотря на то, в какую сторону он смотрел изначально.

В начале программы робота нужно повернуть на север, для этого используйте, например, сенсор:

  • facing_north() возвращает true, если робот направляется на север, в противном случае, возвращает false

Шаг 3: Super Karel - Training

Робот Карл хочет принять участие в олимпиаде для роботов (так называемая робоолимпиада). Одна из дисциплин, в которой можно принять участие, это бег с препятствиями. Создайте для Карла программу, с помощью которой он сможет преодолеть трассу с препятствиями. training.kw. В случае, если у него это получится, робот Карл станет Супер Карлом.

Задача 3.1

Создайте программу training.c и сохраните файл карты training.kw.

Задача 3.2

Для успешного забега на трассе создайте собственную функцию jump_over(), с помощью которой робот преодолеет именно одно препятствие. Карл будет перескакивать случайное количество барьеров, пока не достигнет значка на карте.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         0
ST.+-----------------------+
 2 | .   .   .   .   .   . |
   |   |   |   |   |   |   |
 1 | > | . | . | . | 1 | . |
   +-----------------------+
     1   2   3   4   5   6   AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (5, 1)   EAST       0         1
ST.+-----------------------+
 2 | .   .   .   .   .   . |
   |   |   |   |   |   |   |
 1 | . | . | . | . | > | . |
   +-----------------------+
     1   2   3   4   5   6   AVE.

Используйте заголовочный файл superkarel.h, подключением которого робот сможет использовать остальные сенсоры:

  • no_beepers_present() Возвращает true, если под Карлом значков нет, и, наоборот, false, если значки под Карлом есть
  • no_beepers_in_bag() Возвращает true, если у Карла рюкзак пуст, и false, если в нем есть значки
  • front_is_blocked() Возвращает true, если перед Карлом стена, и false, если путь перед Карлом чист
  • right_is_clear() Возвращает true, если справа от робота нет стены, иначе false
  • right_is_blocked() Возвращает true, если справа от робота стена есть, иначе false
  • left_is_clear() Возвращает true, аналогично, если слева от Карла нет стены, иначе false
  • left_is_blocked() Возвращает true, если справа от Карла стена, иначе false
  • facing_east() возвращает true, если робот направляется на восток, в противном случае, возвращает false
  • not_facing_east() возвращает true, если робот не направляется na восток, в противном случае, возвращает false
  • facing_west() возвращает true, если робот направляется на запад, в противном случае, возвращает false
  • not_facing_west() возвращает true, если робот не направляется na запад, в противном случае, возвращает false
  • not_facing_north() возвращает true, если робот не направляется na север, в противном случае, возвращает false
  • facing_south() возвращает true, если робот направляется на юг, в противном случае, возвращает false
  • not_facing_south() возвращает true, если робот не направляется na юг, в противном случае, возвращает false

Комментарий

Заголовочный файл superkarel.h является расширенной версией файла karel.h, иными словами, вмещает его в себе. Следовательно, подключать их одновременно нет смысла.

Комментарий

Вместо -lkarel используйте для компиляции параметр -lsuperkarel.

Шаг 4: Super Karel - Olympics

Тренировки робота к Робоолимпиаде достигают своего пика. На этом этапе вы поможете Карлу закончить приготовления и научите его преодолевать барьеры, находящиеся на случайном расстоянии один к другому и любой высоты и ширины.

Задача 4.1

Создайте программу olympics.c, которая будет копией training.c.

Можете использовать для этой цели команду:

cp training.c olympics.c

Задача 4.2

Измените код программы olympics так, чтобы Карл смог перейти препятствия, которые находятся на случайном расстоянии друг от друга. Карл должен остановиться, когда обнаружит под собой значок. Свой код тестируйте на карте olympics.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 5 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 4 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 3 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 2 | .   .   .   .   .   .   .   .   .   . |
   |   |   |	   |	   |	   |   |   |
 1 | > | . | .   . | .   . | 1   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (7, 1)   EAST       0         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 5 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 4 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 3 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 2 | .   .   .   .   .   .   .   .   .   . |
   |   |   |	   |	   |	   |   |   |
 1 | . | . | .   . | .   . | >   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Комментарий

Не забудьте указать правильный файл карты в функции turn_on().

Задача 4.3

Измените код программы olympics таким образом, чтобы робот смог преодолевать случайновысокие барьеры. Свой код тестируйте на картах olympics2.kw и olympics3.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |	   |               |
 4 | .   .   .   . | .   . | .   .   .   . |
   |               |	   |           |   |
 3 | .   .   .   . | .   . | .   .   . | . |
   |   |           |	   |	   |   |   |
 2 | . | .   .   . | .   . | .   . | . | . |
   |   |   |	   |	   |	   |   |   |
 1 | > | . | .   . | .   1 | .   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (6, 1)   EAST       0         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |	   |               |
 4 | .   .   .   . | .   . | .   .   .   . |
   |               |	   |           |   |
 3 | .   .   .   . | .   . | .   .   . | . |
   |   |           |	   |	   |   |   |
 2 | . | .   .   . | .   . | .   . | . | . |
   |   |   |	   |	   |	   |   |   |
 1 | . | . | .   . | .   > | .   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Комментарий

Не забудьте указать правильный файл карты в функции turn_on().

Задача 4.4

Измените код программы olympics так, чтобы Карл смог преодолевать на этот раз случайноширокие барьеры. Код тестируйте на картах olympics4.kw и olympics5.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST      10         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |	   +-------+	   |
 4 | .   .   .   . | .   . | .   . | .   . |
   |               |	   |	   |   |   |
 3 | .   .   .   . | .   . | .   . | . | . |
   |   +---+	   |	   |	   |   |   |
 2 | . | . | .   . | .   . | .   . | . | . |
   |   |   |	   |	   |	   |   |   |
 1 | > | . | .   . | .   . | .   . | 1 | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (9, 1)   EAST      10         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |	   +-------+	   |
 4 | .   .   .   . | .   . | .   . | .   . |
   |               |	   |	   |   |   |
 3 | .   .   .   . | .   . | .   . | . | . |
   |   +---+	   |	   |	   |   |   |
 2 | . | . | .   . | .   . | .   . | . | . |
   |   |   |	   |	   |	   |   |   |
 1 | . | . | .   . | .   . | .   . | > | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Комментарий

Не забудьте указать правильный формат карты в функции turn_on().

Дополнительные задачи

Задача A.1

Измените код программы olympics так, чтобы Карл "прыгал" через барьеры слева направо, если с начала он смотрел на восток, а если на запад, то наоборот - справа налево. Имплементацию проверьте на карте olympics6.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (10, 1)   WEST       0         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                   |                   |
 5 | .   .   .   .   . | .   .   .   .   . |
   |                   |   +-------+	   |
 4 | .   .   .   .   . | . | .   . | .   . |
   |                   |   |	   |	   |
 3 | .   .   .   .   . | . | .   . | .   . |
   |   +-----------+   |   |	   |   |   |
 2 | . | .   .   . | . | . | .   . | . | . |
   |   |           |   |   |	   |   |   |
 1 | . | .   .   . | 1 | . | .   . | . | < |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (5, 1)   WEST       0         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                   |                   |
 5 | .   .   .   .   . | .   .   .   .   . |
   |                   |   +-------+	   |
 4 | .   .   .   .   . | . | .   . | .   . |
   |                   |   |	   |	   |
 3 | .   .   .   .   . | . | .   . | .   . |
   |   +-----------+   |   |	   |   |   |
 2 | . | .   .   . | . | . | .   . | . | . |
   |   |           |   |   |	   |   |   |
 1 | . | .   .   . | < | . | .   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Задача A.2

Дорога, ведущая на территорию Технического университета, за многие года уже успела испортиться и определяется большим (а иногда и меньшим) количеством дыр на ней. Создайте программу road так, чтобы Карл обозначил значком каждую яму, которая еще не обозначена. Дороги, по которым Карлу еще только предстоит пройти: road.kw, road2.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 2)   EAST       2         0
ST.+-------------------+
 2 | >   .   .   .   . |
   |---+   +---+   +---|
 1 | . | 1 | . | . | . |
   +-------------------+
     1   2   3   4   5   AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (5, 2)   EAST       1         0
ST.+-------------------+
 2 | .   .   .   .   > |
   |---+   +---+   +---|
 1 | . | 1 | . | 1 | . |
   +-------------------+
     1   2   3   4   5   AVE.

Задача A.3

Создайте программу stairsbuilder, при помощи которой Карл построит лестницу. Сначала перед Карлом стоит столбик, построенный из значков, количество которых >1. Заданием Карла является построить справа от этого стобика лестницу из значков, при этом на каждой ступеньке количество значков будет всегда на один меньше, чем на предыдущей. Вначале Карлу всегда хватает значков на постройку лестницу, для строительства которой справа от робота всегда есть место. После постройки лестницы Карл должен оказаться на самой верхней ступеньке. Имплементацию опробуйте на картах: stairsbuilder.kw и stairsbuilder2.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 3)   NORTH     99         0
ST.+---------------------------+
 6 | .   .   .   .   .   .   . |
   |                           |
 5 | .   .   .   .   .   .   . |
   |                           |
 4 | 5   .   .   .   .   .   . |
   |                           |
 3 | ^   .   .   .   .   .   . |
   |                           |
 2 | .   .   .   .   .   .   . |
   |                           |
 1 | .   .   .   .   .   .   . |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 4)    WEST     89         5
ST.+---------------------------+
 6 | .   .   .   .   .   .   . |
   |                           |
 5 | .   .   .   .   .   .   . |
   |                           |
 4 | <   4   3   2   1   .   . |
   |                           |
 3 | .   .   .   .   .   .   . |
   |                           |
 2 | .   .   .   .   .   .   . |
   |                           |
 1 | .   .   .   .   .   .   . |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Комментарий

Сутью задания является испытать ваше алгоритмическое мышление. Поэтому, вам нужно решить данную задачу без использования переменных (в том случае, если вы уже с ними знакомы).

Задача A.4

В нижнем ряду карты для робота Карла находятся значки в любом количестве. Сперва робот стоит на начале нижнего ряда (дома). Создайте программу mirror, с помощью которой Карл воссоздаст на ряду выше зеркальное отражение нижнего ряда. То есть, количество значков, находящееся слева снизу, будет соответствовать количеству справа вверху и т.д. При этом правдиво, что на нижнем ряду на каждой позиции находится, как минимум, один значок. Решение проверьте на картах: mirror.kw и mirror2.kw.

Начальная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         1
ST.+---------------------------+
 3 | .   .   .   .   .   .   . |
   |                           |
 2 | .   .   .   .   .   .   . |
   |                           |
 1 | >   2   3   4   5   6   7 |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Конечная позиция

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 2)   WEST       0         7
ST.+---------------------------+
 3 | .   .   .   .   .   .   . |
   |                           |
 2 | <   6   5   4   3   2   1 |
   |                           |
 1 | .   .   .   .   .   .   . |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Комментарий

Сутью задания является испытать ваше алгоритмическое мышление. Поэтому, вам нужно решить данную задачу без использования переменных (в том случае, если вы уже с ними знакомы).

Задача A.5

Рутинное занятие программиста состоит из бесконечного редактирования кода и его компиляции. Каждой программе для компиляции нужен свой свод параметров для последующей сборки. Постоянно повторять команду для компиляции непрактично. Повторяющейся сборкой занимается система make, которая знает, какие параметры для сборки программы на самом деле нужны. Напишите свои собственные параметры для сборки в файл Makefile.

Создайте файл Makefile:

vim Makefile

В файл запишите (перейдите в режим вставки с помощью клавиши i):

eternal: eternal.c
	gcc -std=c11 -Wall -Werror eternal.c -lkarel -lcurses -o eternal

Предупреждение

Используйте TAB (не пробелы). В противном случае система make будет выписывать ошибки.

Комментарий

Некоторые редакторы без предупреждения вместо TAB записывают 4 пробела, что сложно определить сразу. ViM редактор должен опознать работу в Makefile, тем самым предупредив эту проблему. Вы можете заставить редактор ViM писать именно TAB вместо пробелов с помощью команды :set noexpandtab. Все четыре пробелы в начале файла можете заменить командой:

:%s/^    /\t/g

Смысл 1-2 строк в Makefile следующий:

  • Первая строка - это название цели. Часть перед двоеточием - это название цели (компонент, который должен создаться).
  • Часть после двоеточия - это завимости (компоненты, от которых вы будете отталкиваться).
  • Вторая строка описывает команды, с помощью которой вы получаете цель из зависимостей.

Значение отдельных параметров:

  • -std=c11 Мы будем использовать версию языка С 2011го года
  • -Wall Поскольку, нам интересно вас научить не "только" писать работающий код, а код грамотный, мы хотим получать от компилятора все предупреждения (warnings). Код может работать, несмотря на то, что компилятор выписывает всяческие предупреждения
  • -Werror опция, благодаря которой все предупреждения приобретают статус ошибок, что не позволит получить исполняемый файл
  • eternal.c название файла с кодом, который нужно скомпилировать
  • -o eternal название исполняемого файла на выходе (не обязан иметь расширение .exe)

Комментарий

В Makefile добавьте цели и для других файлов training.c и olympics.c. Их сборка будет осуществляться с помощью команд make training и make olympics.

Комментарий

Для копирования строк в редакторе ViM можете перейти в режим выделения (Ctrl+Shift+V). Выделите и скопируйте строки клавишей y, вставьте клавишей p. Совершив ошибку, верните изменения клавишей u.

Комментарий

Редактор ViM облегчает процесс нахождения ошибок и сборки программы. Программу можно скомпилировать прямо внутри редактора ViM, также сразу перейдя на место возможной ошибки при её появлении.

Дополнительные источники

  1. Karel Language Reference
  2. Here you can find the original library of Karel the Robot, including the library installation instructions.
  3. Rudolf Pecinovský: Základy algoritmizace - глава 10
  4. Pavel Herout: Učebnice jazyka C (1. díl) - глава 5.1, 5.4, 5.5
  5. Заголовочный файл робота Карла karel.h
  6. Заголовочный файл супер робота Карла superkarel.h
  7. Файл для компиляции программ для Карла Makefile
  8. Файл для компиляции программ для супер Карла Makefile-superkarel
  9. GNU Make Tutorial
  10. Наше руководство по VIM
  11. ViM Quick Reference Card (.pdf)
  12. Конфигурационный файл Томаша для ViM
  13. Конфигурационный файл Даниела для ViM

Видео