colobot-data/help/R/tremote5.txt

114 lines
5.4 KiB
Plaintext
Raw Normal View History

\b;Упражнение
Дистанционное управление ботом без использования \l;поста обменом информацией\u object\exchange;. Бот должен проехать по 6 синим отметкам.
Что потребуется:
1) \l;Колесный сборщик\u object\botgr; без батареи. Данный бот будет ведущим.
2) Ведомый \l;тренировочный бот\u object\bottr; запрограммированый заранее на ожидание комманд от ведущего бота.
Ведущий бот будет передавать сразу несколько заявок, не дожидаясь, пока они будут обрабатываться. Мы будем использовать \l;массив\u cbot\array; для эттой цели.
\b;Ведомый
Прежде всего нужно понять, как программа работает. \l;Класс\u cbot\class; \c;order\n; содержит в себе две части: \c;m_type\n; для заявок на выполнение (движение или поворот) и \c;m_param\n; для дистанции или угла поворота¦:
\c;\s;\l;public\u cbot\public; \l;class\u cbot\class; order
\s;{
\s; \l;int\u cbot\int; m_type;
\s; \l;float\u cbot\float; m_param;
\s;}
\n;
Второй \l;класс\u cbot\class; \c;exchange\n; содержит в себе механизм обмена информацией. Мы заявляем \c;\l;статичную\u cbot\static;\n; часть класса \c;m_fifo\n;, которая содержит в себе лист команд для выполнения. Слово \c;статический\n; гарантирует, что \c;m_fifo\n; будет одинаковым во всех \l;классах\u cbot\class;.
\c;\s;{
\s; \l;static\u cbot\static; \l;private\u cbot\private; order m_fifo[] = null;
\n;
Метод \c;put\n; позволит ведущему боту передавать завяки. Заявки могут быть легко добавлены в конце массива \c;m_fifo\n;:
\c;\s; \l;synchronized\u cbot\synchro; void put(order a)
\s; {
\s; m_fifo[sizeof(m_fifo)] = a;
\s; }
\n;
Другой метод \c;get\n; может быть использован ведомым ботом для получения задания. Этот метод возвращает выполненную заявку. Если лист пустой, будет возвращено значение \c;null\n; и бот будет ждать следующих команд. В противном случае первая заявка в списке будет возвращена, а оставшиеся будут "продвинуты вверх". Если массив не может быть "укорочен", то мы будем использовать временной массив \c;copy\n;¦:
\c;\s; \l;synchronized\u cbot\synchro; order get()
\s; {
\s; if ( sizeof(m_fifo) == 0 ) return null;
\s;
\s; order a = m_fifo[0];
\s; order copy[] = null;
\s; for ( int i=1 ; i<sizeof(m_fifo) ; i++ )
\s; {
\s; copy[i-1] = m_fifo[i];
\s; }
\s; m_fifo = copy;
\s; return a;
\s; }
\n;
Основная программа в ведомом боте содержит класс \c;exchange\n; вызываемый через \c;list\n;.
\c;\s;\l;extern\u cbot\extern; void object::Slave5( )
\s;{
\s; exchange list();
\s; order todo;
\n;
Внешний \c;цикл\n; длится вечно. Внутренний \c;цикл\n; ждет заявку с помощью метода \c;get\n; и \c;exchange\n; класса. Как только метод \c;get\n; вернет значение, отличное от \c;null\n;, цикл остановится.
\c;\s; \l;while\u cbot\while; ( true )
\s; {
\s; \l;while\u cbot\while; ( true )
\s; {
\s; todo = list.get();
\s; if ( todo != null ) break;
\s; wait(1);
\s; }
\n;
Теперь мы получили заявку в переменную \c;todo\n;. Значит нам нужно выполнить заказ:
\c;\s; if ( todo.m_type == 1 )
\s; {
\s; move(todo.m_param);
\s; }
\s; else if ( todo.m_type == 2 )
\s; {
\s; turn(todo.m_param);
\s; }
\s; else
\s; {
\s; message("Unknown order");
\s; }
\s; }
\s;}
\n;
\b;Ведущий
В ведущем боте создадим функцию \c;SendOrder\n;, которая будет отправлять заказы к ведомому боту:
\c;\s;void object::SendOrder(float order, float param)
\s;{
\s; exchange list();
\s; order todo();
\s;
\s; todo.m_type = order;
\s; todo.m_param = param;
\s; list.put(todo);
\s;}
\n;
Пока программа для ведущего бота довольно проста:
\c;\s;extern void object::Remote5( )
\s;{
\s; SendOrder(1, 20); // move(20);
\s; SendOrder(2, 90); // turn(90);
\s; SendOrder(1, 20); // move(20);
\s; SendOrder(2, 90); // turn(90);
\s; SendOrder(1, 10); // move(10);
\s; SendOrder(2, 90); // turn(90);
\s; SendOrder(1, 10); // move(10);
\s; SendOrder(2,-90); // turn(-90);
\s; SendOrder(1, 10); // move(10);
\s;}
\n;
Клавиша \key;\key help;\norm; показывает эту инструкцию в любое время.
\t;Смотри также
\l;Язык CBOT\u cbot;, \l;Переменные\u cbot\type; и \l;Категории\u cbot\category;.