Anima Robot Warfare 1

Язык программирования RW1


-= Robot Warfare 1 =-

http://robots.chat.ru

Copyright (c) 1998-2001 by
Alexander A. Shabarshin
shaos@mail.ru

November 1998 - June 2001

RW1 Programming Language
Version 2.0 (23.06.2001)

  С О Д Е Р Ж А Н И Е

1. ПСЕВДОКОД RW0
2. ПЛАТФОРМЫ ДЛЯ RW1
  2.1 RW1 PLATFORM 0
  2.2 RW1 PLATFORM 1
  2.3 RW1 PLATFORM 2
  2.4 RW1 PLATFORM 3
3. СТРУКТУРА ПРОГРАММЫ НА RW1
4. КЛЮЧЕВЫЕ СЛОВА ЯЗЫКА RW1
  4.1 ACT
  4.2 AUTHOR
  4.3 BACK
  4.4 BREAK
  4.5 CALL
  4.6 COLOR
  4.7 COMMAND
  4.8 CONTINUE
  4.9 COPYP
  4.10 DEF
  4.11 DO
  4.12 DUMP
  4.13 ELSE
  4.14 END
  4.15 FILL
  4.16 FOR
  4.17 FRONT
  4.18 GOTO
  4.19 IF
  4.20 IFY
  4.21 IFN
  4.22 IMAGE
  4.23 LEFT
  4.24 MAIN()
  4.25 PIXEL
  4.26 PLANE
  4.27 POP
  4.28 RADAR
  4.29 RECV
  4.30 RECVP
  4.31 RET
  4.32 RIGHT
  4.33 ROBOT
  4.34 SAY
  4.35 SELECT
  4.36 SEND
  4.37 SENDP
  4.38 SET
  4.39 SHOT
  4.40 SPY
  4.41 START:
  4.42 STEP
  4.43 TEST
  4.44 TEXT
  4.45 WHILE
  4.46 УСТАРЕВШИЕ КОМАНДЫ
5. ТОНКОСТИ ПРОГРАММИРОВАНИЯ
      

===========================================================

                  "Robot Warfare is a Russian invention, 
                   along with vodka and Tetris ..."

                           Sam James and Harry Fairhead, 
                   COMPUTER SHOPPER (UK), December 1999.



   1. ПСЕВДОКОД RW0

   Язык программирования RW1 изначально создавался как язык
программирования боевых роботов. Для этой цели был 
разработан бинарный формат представления робота RW0. Этот
формат по сути своей является псевдокодом, таким же как
псевдокод виртуальной машины JAVA или P-код в Паскале. 
Псевдокод RW0 получается после копиляции RW1-программы 
компилятором (начиная с версии 2.0 он называется RW1C). Это
дает возможность использовать язык RW1 как универсальный
язык программирования, независящий от конкретного процессора
и системы. Чтобы запустить программу в псевдокоде RW0 на 
какой-либо системе, необходимо, чтобы в этой системе 
работала виртуальная машина RW0, соответствующая какой-либо
поддерживаемой платформе, либо существовало бы некое 
кросс-средство, транслирующее псевдокод RW0 в коды конкретного 
процессора.



   2. ПЛАТФОРМЫ ДЛЯ RW1

   Для того чтобы как-то упорядочить разнообразные области 
применения языка RW1, предлагается четыре направления, 
называемых виртуальными платформами (PLATFORMS). Каждая из
них определяется способом работы с графикой и своей 
спецификой.


   2.1 RW1 PLATFORM 0

   RW1P0 - платформа для боевых роботов. Как правило это 
прямоугольное поле, разбитое на клетки с обЗектами
одного из следующих типов: 
@t_empty   = 0 - соответствует пустому месту;
@t_hole    = 1 - яма, в которую можно упасть;
@t_stone   = 2 - камень, можно расстрелять;
@t_box     = 3 - ящик со снарядами, можно подобрать;
@t_reactor = 4 - ядерный реактор, можно подзарядится;
@t_missle  = 5 - летящий снаряд, может попасть в вас;
@t_robot   = 6 - вражеский робот, его надо уничтожить;
@t_my      = 7 - свой робот (в режиме командных бо╦в);
@t_wall    = 10 - клетка стены вокруг поля боя.
Все роботы функционируют параллельно. Каждому соответствует
своя программа в псевдокоде RW0. Эта платформа является
традиционной и используется в обычных соревнованиях роботов
"Robot Warfare 1", проводящихся еженедельно на 
http://robots.ural.net. 
Более подробно о правилах проведения соревнований
читайте в документе "Чемпионат роботов RW1".
   Кроме того данный подход может быть с успехом применим 
для разработки стратегических игр, в которых юниты будут 
программироваться на языке RW1. С помощью средств передачи 
информации между роботами допускается управление роботом 
c клавиатуры или мышью (пример тому - робот MOUSE). 
   Графика с точки зрения программиста имеет место лишь 
как картинка на роботе, которую можно модифицировать.


   2.2 RW1 PLATFORM 1

   RW1P1 - платформа универсального языка программирования.
Программа на RW1, написанная для такой платформы, получает
в свое пользование графический дисплей. Допускается 
рисовать точки, закрашивать прямоугольники, выводить текст.
Кроме того осуществляется прием информации с клавиатуры.
С помощью механизма внешних команд можно добавить новые
возможности по работе с файлами и цветом.


   2.3 RW1 PLATFORM 2

   RW1P2 - платформа для клеточных игр. Программа на RW1 
имеет доступ к клеточному экрану и библиотеке графических 
квадратных спрайтов, размером с клетку экрана. Программа
оперирует этими спрайтами, выводя их в те или иные клетки
экрана. Есть возможность управлять работой программы с 
клавиатуры и мышью. Таким способом можно запрограммировать
довольно-таки широкий класс задач: игры типа тетриса,
клеточные игры, клеточные автоматы (например игра Жизнь),
текстовые редакторы и т.д.


   2.4 RW1 PLATFORM 3

   RW1P3 - платформа для программирования событий в
виртуальной реальности. Имеет непосредственное отношение к
интернет проекту "Виртбург - виртуальный город" 
http://vburg.narod.ru. На языке RW1 программируются
некие невидимые сущности, называемые "ангелы", которые будут
модифицировать окружающую виртуальную действительность
в зависимости от тех или иных условий, например заставлять
работать лифты, бегать поезда метро, менять изображения 
на стенах, перестраивать структуру зданий на лету и т.д.



   3. СТРУКТУРА ПРОГРАММЫ НА RW1

   Программа на языке RW1 является обычным текстовым 
файлом, который можно создать и отредактировать в любом
текстовом редакторе (кроме навороченных типа Word).
Существует специально созданный для RW1 редактор, который
называется RW1_EDIT.
   Комментарии в тексте программы начинаются с символа % или
с двух символов // (как в языке программирования С) и 
продолжаются до конца строки. 
   Если в строке записывается больше одной команды языка, 
то они должны быть разделены символом ; (точка с запятой).
   Программа начинается с ключевого слова ROBOT, за которым
следует имя робота в кавычках. Далее идет ключевое слово
AUTHOR, за которым следует имя автора в кавычках.
   Программу на языке RW1 можно структурно разбить на 
два блока, разделяемых меткой START: или именем 
главной функции MAIN(), блок обЗявлений и 
блок команд, расположенных соответственно до и после 
метки START:, которая неявно есть в начале 
функции MAIN().
   ROBOT и AUTHOR расположены в блоке обЗявлений. Кроме 
того в блоке обЗявлений могут находиться (для RW1P0) команды 
расцветки робота (COLOR и IMAGE) и 
команды установки оборудования (FRONT, BACK, 
LEFT, RIGHT).
   Одним из важных понятий языка является метка. 
Метка - это слово, составленное из латинских букв,
цифр или символа подчеркивания ('_') длиной до 16 символов, 
за которым следует двоеточие (':'). Самой первой меткой в 
программе должна быть метка START:, либо обЗявление главной
функции (главного цикла) MAIN(), в которой обЗявление этой 
метки присутствует неявно. С этой метки начинается блок 
команд - непосредственно сама программа поведения робота.
   В программе могут быть использованы переменные и массивы.
Массивы необходимо обЗявлять с помощью команды DEF. 
Переменные, в отличие от массивов, обЗявлять не нужно. 
Переменная считается существующей с момента первого 
присвоения этой переменной какого-либо значения. Переменные
и элементы массива могут принимать значения в пределах 
-32768..32767. Имена переменных и массивов составляются из
латинских букв, цифр или символа подчеркивания ('_') длиной 
до 16 символов. Все переменные, массивы и метки должны 
иметь уникальные имена, отличные от ключевых слов языка и 
от имен регистров робота (которые составлены из одной 
буквы - хорошим стилем является использование имен более
чем из одной буквы, чтобы не возникло проблем в будущем). 
Большие и маленькие буквы не различаются (например, имена 
'Name' и 'NAME' будут обозначать одно и то же).
   Числа в языке RW1 являются 16-битными целыми значениями 
со знаком, т.е. могут принимать значения от -32768 до 32767.
Кроме десятичного представления чисел, допускается их
шестнадцатиричное представление (от #0000 до #FFFF или от
0x0 до 0xFFFF), символьное представление (например 'a','Z').
   Следует отметить, что некорректная работа со стеком 
(CALL и RET) приведет программу 
робота в состояние HALT, при котором она считается 
завершенной. К этому же приводит большинство некорректных 
действий программы робота.
   Робот имеет несколько целочисленных регистров. Почти все
регистры только для чтения, кроме регистров A,B,C:
   A - регистр общего назначения A (чтение/запись),
   B - регистр общего назначения B (чтение/запись),
   C - регистр общего назначения C (чтение/запись),
   D - расстояние до обЗекта,
   E - уровень энергии нашего робота,
   I - порядковый номер в игре нашего робота (с 1),
   K - вспомогательный регистр в некоторых командах,
   L - регистр для хранения последнего значения выражения,
   M - количество снарядов нашего робота,
   N - тип обЗекта (см.описание RW1P0),
   P - регистр указателя текущей команды,
   R - случайное число 0..999,
   S - глубина стека возвратов (в начале программы 0),
   T - значение счетчика тактов,
   X - координата Х обЗекта относительно робота,
   Y - координата Y обЗекта относительно робота.
   В версии 2.0 появилась возможность включать файлы в 
программу с помощью команды +. Например в новых версиях 
программ рекомендуется в блоке обЗявлений включать 
файл RW1_STD.RWI в котором описаны полезные 
макроопределения:
   +RW1_STD.RWI
   Еще одна из важных возможностей версии 2.0 - обЗявление 
и использование функций. ОбЗявление функций - это имя со 
скобками (), в следующей строке за которым идет открывающая 
фигурная скобка }, а в конце функции закрывающая фигурная 
скобка } (причем в строке с фигурной скобкой больше ничего
не должно быть). При компиляции программы имя преобразуется
вметку, а закрывающая фигурная скобка - в команду RET.
Использование функции допускается через команду CALL
либо путем записи FUNC(Args), где FUNC - имя
нашей функции, а Args - список аргументов через запятую 
(не больше трех), которые в общем случае могут быть 
выражениями. Аргументы передаются в функцию через регистры
A,B,C. Использование функций в выражениях предусматривается
начиная с версии 2.1.
   Произвольные выражения в RW1 появились в
версии 2.0. В выражениях на языке RW1 могут быть 
использованы числа, регистры, переменные, элементы массива.
Длина выражения ограничивается лишь возможностями 
компилятора - скомпилированный код должен укладываться 
в 255 байт. Используемые операции:
   
   && - логическое И;
   || - логическое ИЛИ;
   == - равено;
   != - неравно;
   >  - больше;
   <  - меньше;
   >= - больше либо равно;
   <= - меньше либо ранво;
   +  - сложение;
   -  - вычитание;
   *  - умножение;
   /  - деление;
   %  - остаток от деления;
   &  - побитовое И;
   |  - побитовое ИЛИ;
   ^  - побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ;
   >> - побитовый сдвиг вправо;
   << - побитовый сдвиг влево;
   -  - унарный минус;
   ~  - унарная операция побитовой инверсии;
   !  - унарная операция логического отрицания;
   [] - скобки индексирования массивов;
   () - скобки для управления приоритетами;
   ?: - условная операция, expr?a:b если expr=1, то 
значение выражения a, иначе b.
   
   Выражения могут быть использованы для присваивания 
значения переменным. Например Var=expr. Кроме того
выражения используются в условиях и циклах. 
См. IF, WHILE, DO, FOR.



   4. КЛЮЧЕВЫЕ СЛОВА ЯЗЫКА RW1

   Ключевые слова обозначают команды препроцессора или 
команды языка. В описании слово Var используется для
обозначения числа, регистра, переменной или элемента
массива, индексированного числом, регистром или переменной.
Любую команду языка можно использовать в виде COM(expr),
COM(expr1,expr2), COM(expr1,expr2,expr3), в зависимости
от количества аргументов. При этом препроцессор это 
скомпилирует в код
   A=expr;COM A
   A=expr1;B=expr2;COM A B
   A=expr1;B=expr2;C=expr3;COM A B C
   соответственно. exprN - произвольные выражения.


   4.1 ACT

   Команда действий робота в RW1P0. 

   ACT Var

   Задействует оборудование (глаз или пушку), размещенное 
в направлении Var ( 0-спереди, 1-справа, 2-сзади, 3-слева
или макросы из RW1_STD.RWI: @FRONT, @RIGHT, @BACK и @LEFT 
соответственно), причем глаз возвращает следующую 
информацию в регистрах робота: D - расстояние до 
обЗекта (1 - соседняя клетка), N - тип обЗекта в 
выбранном направлении, K - уровень энергии, если 
это робот, или степень целостности, если это камень, или 
направление полета, если это снаряд (1 - в робота,
0 - от робота либо в сторону). Занимат 1 такт.


   4.2 AUTHOR

   Команада AUTHOR "author" задает имя автора 
программы и используется для определения авторства.


   4.3 BACK

   В блоке обЗявлений (RW1P0) указывается оборудование 
робота путем использования команд: FRONT, BACK, LEFT, RIGHT,
за которыми идет либо слово EYE (глаз), либо слово 
GUN (пушка). С помощью слова BACK задается 
оборудование сзади, например:

   BACK GUN % пушка сзади


   4.4 BREAK

   Команда BREAK используется для выхода из цикла
FOR, WHILE, DO.
Компилируется препроцессором. См. CONTINUE.


   4.5 CALL

   Команда ветвления. Вызов подпрограммы по метке. 
Занимает 0 тактов.

   CALL label

   где "label" - имя метки, существующей в программе либо
элемент массива меток, к которому обратились по индексу
(например CALL Labels[A]). 
   Вызов подпрограммы влечет занесение адреса следующей 
команды в стек возвратов (а также увеличение регистра 
глубины стека возвратов S на 1) и запись в указатель
команд P адреса метки, т.е. передачу управления на 
эту метку с сохранением адреса возврата в стеке возвратов. 
Глубина стека возвратов не оговаривается, однако так как 
этот стек находится в памяти переменных (начиная с конца 
этой памяти в сторону уменьшения), то фактически 
максимальная глубина стека тем меньше, чем больше 
переменных и элементов массивов используется в программе.
Возврат из подпрограммы осуществляется с помощью
команды RET.


   4.6 COLOR

   Цвет робота задается в блоке обЗявлений ключевым словом 
COLOR и следующим за ним цветом в 16-ричной форме 
RGB, например:

   COLOR FF0000 % красный
   COLOR 00FF00 % зеленый
   COLOR 0000FF % синий
   COLOR FFFFFF % белый
   COLOR C0C0C0 % светло-серый и т.д.

   Допускается лишь одно определение цвета робота в 
программе. Если цвет робота не определен - робот считается
белым. О том как наносить на робота картинку см. IMAGE.
   Кроме того с версии 2.1 эта команда может быть использована
в блоке команд для установки текущего цвета для
графики:

   COLOR Var

   где Var - число, переменная, регистр или элемент 
массива со значением индекса цвета.
См. PIXEL, FILL, TEXT.


   4.7 COMMAND

   Подключение внешних команд COMMAND Var. 
Var - номер, переменная с номером или элемент массива
с номером внешней команды. Возможный вариант использования
COMMAND(expr).


   4.8 CONTINUE

   Команда CONTINUE используется для перехода в начало
цикла FOR, WHILE, DO.
Компилируется препроцессором. См. BREAK.


   4.9 COPYP

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

   COPYP Arr1[N_off1] Arr2[N_off2]

   Копирует последовательность из массива Arr1 в
Arr2, определяя длину последовательности из значения
первого элемента. Поддерживается начиная с версии 2.1.
Другие команды работы с пакетами: 
SENDP, RECVP.


   4.10 DEF

   Слово DEF обозначает команды выделения памяти для
массива. ОбЗявление массива бывает без инициализации и с 
инициализацией. Выполнение команды обЗявления массива без
инициализации занимает 0 тактов.

   DEF name[N_len]

   где "name" - уникальное имя массива, 
отличное от других имен в программе. N_len - число от 1 до 
10000. Следует отметить, что сумма количества всех переменных 
и суммарной длины всех описанных в программе массивов не 
должна превышать 10000. При обЗявлении массива, его
элементы принимают нулевые значения.
   Кроме того массив можно обЗявлять инициализируя значения
его элементов. Команда обЗявления массива с инициализацей 
занимает 1 такт. В следующем примере обЗявляется массив из
10 элементов и инициализируются первые три элемента, все
остальные обнуляются:

   DEF ARR[10]={1,10,5}
      
   При таком обЗявлении в фигурных скобках через запятую 
перечисляются значения элементов массива в виде десятичных 
или шестнадцатиричных чисел, символов. Кроме того 
элементами массива могут быть метки. Если количество 
элементов в фигурных скобках меньше чем длина массива, 
то все оставшиеся элементы принимают нулевые значения. 


   4.11 DO

   Команда препроцессора, описывающая цикл с постусловием:
   
   DO
   {
     ...
   }WHILE(expr)
   
   Цикл продолжается пока условие expr принимает
ненулевое значение. Цикл будет выполняться как минимум один
раз. С помощью команды BREAK можно выйти из цикла, а с 
помощью команды CONTINUE - перейти к началу цикла.
См. WHILE, FOR.


   4.12 DUMP

   Команда для отладки DUMP N_width. Выводит дамп 
памяти массивов и переменных в столбец шириной N_width 
(только в режиме отладки). Занимает 1 такт боевого времени.


   4.13 ELSE

   Команда препроцессора. С помошью слова ELSE 
описывается ветвь "ИНАЧЕ" в условии IF.
   
   IF(expr) command_true
   ELSE command_false
   
   Здесь command_true и command_false могут
быть блоками, ограниченными фигурными скобками { и }. При
этом каждая скобка должна быть в новой строке.


   4.14 END

   Команда конца программы. В версии 2.0 может не 
использоваться, потому-что вставляется препроцессором
автоматически.


   4.15 FILL

   Графическая команда заполнения прямоугольника текущим 
цветом.
   
   FILL VarDX VarDY
   
   Прямоугольник рисуется от последней поставленной точки.
VarDX и VarDY - размер прямоугольника.
Поддерживается с версии 2.1. См. COLOR, PIXEL, TEXT.


   4.16 FOR

   Команда препроцессора, описывающая цикл FOR:
   
   FOR(expr1,expr2,expr3)
   {
     ...
   }
   
   Выражение expr1 инициализирует цикл, expr2
является условием продолжения цикла, а expr3 - выражение
для увеличения/уменьшения счетчика. Например:
   
   FOR(COUNT=0,COUNT<10,COUNT++)
   {
     ...
   }
   
   Этот цикл будет выполняться один раз.
   С помощью команды BREAK можно выйти из цикла, а с 
помощью команды CONTINUE - перейти к началу цикла.
См. WHILE, DO.


   4.17 FRONT

   В блоке обЗявлений (RW1P0) указывается оборудование 
робота путем использования команд: FRONT, BACK, LEFT, RIGHT,
за которыми идет либо слово EYE (глаз), либо слово 
GUN (пушка). С помощью слова FRONT задается 
оборудование спереди, например:

   FRONT EYE % глаз спереди


   4.18 GOTO

   Команда ветвления. Передает управление на метку. 
Занимает 0 тактов. Вид команды:

   GOTO label

   где "label" - имя метки, существующей в программе либо
элемент массива меток, определенный в начале программы. 
Выполнение этой команды записывает в указатель команд 
P адрес метки. См. CALL и
RET.


   4.19 IF

   Команда препроцессора. С помошью слова IF описывается
условие.
   
   IF(expr) command_true
   ELSE command_false
   
   Допускается сокращенная запись IF(expr) command_true.
   Здесь command_true и command_false могут
быть блоками, ограниченными фигурными скобками { и }. При
этом каждая скобка должна быть в новой строке.


   4.20 IFY

   Внутрення команда языка, которая может быть использована 
для оптимизации. Формат команды:
   
   IFY Var1 Var2
   
   Переход на метку Var2 в случае если Var1
имеет НЕНУЛЕВОЕ значение. См. IFN.
Используется препроцессором для реализации условных 
переходов по 0 в циклах.


   4.21 IFN

   Внутрення команда языка, которая может быть использована 
для оптимизации. Формат команды:
   
   IFN Var1 Var2
   
   Переход на метку Var2 в случае если Var1
имеет НУЛЕВОЕ значение. См. IFY.
Используется препроцессором для реализации условных 
переходов по 1 в циклах.


   4.22 IMAGE

   С помощью ключевого слова IMAGE в блоке обЗявлений может
быть задана картинка, соответствующая роботу, следующим 
образом:

   IMAGE 0 0 0 0 0 0 0 0   % 1-я строка, 8 черных точек
   IMAGE 0 0 0 0 0 0 0 0   % 2-я строка,
   IMAGE 0 0 1 1 1 1 0 0
   .....
   IMAGE 0 0 1 A B 0 0 0
   IMAGE 0 0 0 0 0 0 0 0   % 8-я строка,

   где
       0 - ЧЕРНЫЙ        8 - ТЕМНО-СЕРЫЙ
       1 - СИНИЙ         9 - СВЕТЛО-СИНИЙ
       2 - ЗЕЛЕНЫЙ       A - СВЕТЛО-ЗЕЛЕНЫЙ
       3 - БИРЮЗОВЫЙ     B - СВЕТЛО-БИРЮЗОВЫЙ
       4 - КРАСНЫЙ       C - РОЗОВЫЙ 
       5 - ПУРПУРНЫЙ     D - СВЕТЛО-ПУРПУРНЫЙ
       6 - КОРИЧНЕВЫЙ    E - ЖЕЛТЫЙ
       7 - СВЕТЛО-СЕРЫЙ  F - БЕЛЫЙ

   О том как установить цвет робота см. COLOR.


   4.23 LEFT

   В блоке обЗявлений (RW1P0) указывается оборудование 
робота путем использования команд: FRONT, BACK, LEFT, RIGHT,
за которыми идет либо слово EYE (глаз), либо слово 
GUN (пушка). С помощью слова LEFT задается 
оборудование слева, например:

   LEFT GUN % пушка слева

   Кроме того в блоке команд слово LEFT означает
команду поворота налево.


   4.24 MAIN()

   ОбЗявление первой и главной функции программы MAIN() 
завершает блок обЗявлений и начинает блок комнад 
программы на RW1. Кроме того в ней неявно используется метка
START:.


   4.25 PIXEL

   Графическая команда рисования точки текущим цветом.
   
   PIXEL VarX VarY
   
   VarX и VarY - координаты точки.
Поддерживается с версии 2.1. См. COLOR, FILL, TEXT.


   4.26 PLANE

   Команда для RW1P2 и RW1P3. Выбирает
спрайт для редактирования из библиотеки спрайтов.
   
   PLANE Var
   
   См. SET, SELECT.


   4.27 POP

   Команда особождения стека возвратов на один адрес. 

   POP

   Регистр S уменьшается на 1 (если его значение 
было больше 0). Полезна при экстренном выходе из 
подпрограммы для дальнейшего перехода на какую-либо метку 
внутри основной программы путем использования команды GOTO. 
Команда выполняется за 1 такт.


   4.28 RADAR

   Команда поиска в RW1P0. 

   RADAR Var

   Запускает радар на поиск обЗекта типа Var = 0..7 (можно
воспользоваьтся макроопределениями из RW1_STD.RWI.
Координаты найденного обЗекта относительно робота 
помещаются в регистры X и Y, если же оба 
регистра равны 0, то обЗект не найден. В регитстре K 
возвращается квадрант обЗекта (относительно 
робота - против часовой стрелки 0,1,2,3), в регистре 
D - минимальное абсолютное значение координат. 
Занимает 1 такт. Отнимает 1 единицу энергии.


   4.29 RECV

   Команда взаимодействия роботов. Принимает код по "радио"

   RECV Var

   Принятый код записывается в Var (переменная или 
элемент массива). Кроме того в регистры заносится следующая
информация: регистр N - порядковый номер 
робота-передатчика (если N равен 0, то буфер 
принятых сообщений пуст); в X и Y 
записываются относительные координаты робота-передатчика;
в регистр K помещается значение счетчика времени T,
в которое был отправлен код (для определения приемником того, 
насколько давно было отправлено сообщение). При однократном 
использовании команды RECV количество сообщений в 
буфере принятых сообщений уменьшается на одно. Размер 
буфера - 100 сообщений. Команда выполняется за 1 такт.
Код-сообшение отправляется с помощью команды SEND.
Робот-отправитель не может принять свое сообщение.


   4.30 RECVP

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

   RECVP Arr[N_off]

   Получает пакет из "эфира" (см. RECV), записывая 
его длину в поле Arr[N_off]. Поддерживается начиная 
с версии 2.1. Другие команды работы с пакетами: 
SENDP, COPYP.


   4.31 RET

   Команда ветвления. Возврат из подпрограммы в которую мы
попали с помощью команды CALL. Занимает 0 тактов.

   RET

   Выполнение этой команды влечет за собой снятие с 
вершины стека возвратов адреса возврата, уменьшение 
регистра глубины стека S на 1 и передачу управления 
на адрес возврата (запись адреса в указатель команд P).


   4.32 RIGHT

   В блоке обЗявлений (RW1P0) указывается оборудование  
робота путем использования команд: FRONT, BACK, LEFT, RIGHT,
за которыми идет либо слово EYE (глаз), либо слово 
GUN (пушка). С помощью слова RIGHT задается 
оборудование справа, например:

   RIGHT GUN % пушка справа

   Кроме того в блоке команд слово RIGHT означает
команду поворота направо.


   4.33 ROBOT

   Команада ROBOT "robotname" задает имя программы.
Рекомендуется называть файл с программой в соответствии с
именем после ROBOT. Например робот "Old Nick 10" лежит в
файле с именем old_n_10.rw0.


   4.34 SAY

   Команда может использоватся как для отладки, так и для
взаимодействия между роботами. Команда занимает 1 такт. 

   SAY "..."

   В кавычках указывается фраза, которую необходимо вывести
на терминал. Следует учесть, что строка должна состоять 
только из латинских букв, цифр, символов и пробелов. 
Сказанное с помощью SAY может быть "прочитано"
другим роботом из того же боя с помощью команды TEST. 
Если в течение одного такта несколько роботов сказали SAY, 
то с помощью TEST читается фраза 
последнего робота в списке роботов, сказавшего SAY.
   Кроме того SAY может быть использован для вывода
на терминал значений регистров, переменных и элементов 
массива. Для этого соответствующее имя нужно записать 
большими буквами в строке для SAY, указав перед 
ним символ амперсанда &, а после имени поставить 
пробел. Например:
   SAY "N=&N D=&D E=&E M=&M obj[N]=&OBJ[N] !"


   4.35 SELECT

   Команда для RW1P2 и RW1P3. Задает
координаты клетки для дальнейшего вывода спрайта с помощью
команды SET.
   
   SELECT VarX VarY
   
   здесь VarX и VarY - координаты клетки. См. PLANE, SET.


   4.36 SEND

   Команда взаимодействия роботов. Передает код по "радио". 

   SEND Var1 Var2

   Код Var1 (число, переменная или элемент массива) 
отправляется по "радио" роботу с порядковым номером Var2 
(число, переменная или элемент массива). Причем если Var2 
равно нулю, то передача является широковещательной, т.е. 
код получает каждый робот, участвующий в игре. Запись
SEND Var1 равносильна SEND Var1 0.
Команда SENDвыполняется за 1 такт и вызывает 
уменьшение энергии на 1. 
   Код посланный через SEND можно принять с помощью 
команды RECV. Робот-отправитель не может
принять свое сообщение.


   4.37 SENDP

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

   SENDP Arr[N_off] Var

   Отправляет пакет в "эфир" (см. SEND), считывая 
его длину из поля Arr[N_off], а номер робота из Var. 
Поддерживается начиная с версии 2.1. Другие команды работы 
с пакетами: RECVP, COPYP.


   4.38 SET

   Команда для RW1P2 и RW1P3. Выводит
спрайт из библиотеки спрайтов в клетку, заданную с помощью
SELECT. Доускается два варианта использования:
   
   SET VarN     
   SET VarN VarS
   
   Первый вариант используется в RW1P2 и выводит
спрайт VarN в заданную клетку. Второй вариант 
используется в RW1P3 и выводит спрайт 
VarN в заданную клетку на сторону VarS.
   См. PLANE, SELECT.


   4.39 SHOT

   Команда сохранения регистров в памяти. 

   SHOT Arr[N_offset]

   В массив Arr[] начиная с элемента N_offset 
записываются значения всех внутренних регистров робота, 
начиная с элемента N_offset и заканчивая элементом 
N_offset+15 (т.е. предусмотрено место для 16 
регистров - пока используется только 10). Регистры 
записываются в массив следующим образом:
Arr[N_offset+0]=X, Arr[N_offset+1]=Y, Arr[N_offset+2]=D, 
Arr[N_offset+3]=N, Arr[N_offset+4]=K, Arr[N_offset+5]=R, 
Arr[N_offset+6]=T, Arr[N_offset+7]=E, Arr[N_offset+8]=M, 
Arr[N_offset+9]=I, Arr[N_offset+10]=A,Arr[N_offset+11]=B,
Arr[N_offset+12]=C,Arr[N_offset+13]=P,Arr[N_offset+14]=L, 
Arr[N_offset+15]=S.
Команда выполняется за 1 такт.


   4.40 SPY

   Информационная команда в RW1P0. 

   SPY

   Дает информацию о том, попал ли последний выпущенный 
снаряд в цель. Регистры X и Y возвращают 
текущие относительные координаты снаряда (или координаты 
места, куда он попал), регистр N - тип обЗекта 
(номер типа или 0, если снаряд еще в полете, и -1, если
ни один снаряд еще не выпущен. Занимает 1 такт.


   4.41 START:

   Метка START: завершает блок обЗявлений и
начинает блок комнад программы. Кроме того она
неявно описана в обЗявлении главной функции MAIN(),
которая используется в качестве разделителя структурных 
блоков программы в версии 2.0 и выше. 


   4.42 STEP

   Команда движения робота, занимающая 1 такт. 

   STEP

   Производит один шаг по полю в направлении движения 
робота, возвращает в регистре N тип обЗекта 
(см.RW1P0), который помешал сделать шаг, 
или 0, если шаг успешно произведен.


   4.43 TEST

   Команда TEST проверяет последнее сказанное через
команду SAY.
   
   TEST "..."
   
   Если сказанное точно соответствует шаблону, указанному 
в кавычках после слова TEST, то в регистр L заносится 1, 
иначе - 0.  В шаблоне могут быть использованы символы 
* и ?, заменяющие собой: ? - один символ, * - любое 
количество символов (в том чиле и нисколько). Команда 
выполняется за 1 такт.


   4.44 TEXT

   Графическая команда вывода текста текущим цветом.
   
   TEXT "..."
   
   Текст выводится начиная с последней поставленной точки.
Поддерживается с версии 2.1. См. COLOR, PIXEL, FILL.


   4.45 WHILE

   Команда препроцессора, описывающая цикл с предусловием:
   
   WHILE(expr)
   {
     ...
   }
   
   Цикл продолжается пока условие expr принимает
ненулевое значение. Если выражение сразу же принимает 
нулевое значение, то цикл не выполнится ни разу.
С помощью команды BREAK можно выйти из цикла, а с 
помощью команды CONTINUE - перейти к началу цикла.
Кроме того слово WHILE используется при описании цикла
DO. См. DO, FOR.


   4.46 УСТАРЕВШИЕ КОМАНДЫ
      
   Команда для отладки PRINT Var использовалась для
вывода на терминал значения переменной. Сейчас для той же
цели можно использовать команду SAY:
   SAY "&Var "
   Команда IF в форме 
   IF Var1 Op Var2 : label
   сейчас не используется, однако будет компилироваться для
обеспечения совместимости со старыми версиями.
   Запись TEST "str" : label не будет компилироваться
в версии 2.0. Теперь команда TEST используется
иначе:
   TEST "str"
   IFY L label



   5. ТОНКОСТИ ПРОГРАММИРОВАНИЯ

   Язык RW1 до версии 2.0 был ближе к ассемблерным языкам,
чем к языкам высокого уровня. Начиная с версии 2.0 язык RW1
стал C-подобным языком и получил гибкость языка высокого 
уровня. В этой главе мы осветим некоторые вопросы RW1.
   Во-первых, следует осознать, что программа робота 
должна выполняться "вечно", т.е. до убийства робота либо до
окончания игры. Следовательно каркасом программы на RW1 
должен быть "вечный" цикл:
   
   ROBOT "TEST"
   AUTHOR "name"
   FRONT EYE
   LEFT GUN
   MAIN()
   {
     % начало "вечного" цикла
     % тело "вечного" цикла
     ...
   } % конец "вечного" цикла
   % здесь, при необходимости, могут 
   % располагаться подпрограммы
   
   При использовании массивов или применении начальной 
инициализации переменных, каркас программы будет таким:
   
   ROBOT "TEST"
   AUTHOR "name"
   FRONT EYE
   LEFT GUN
   MAIN()
   {
     % начало блока инициализации
     DEF A1[10] % обЗявление массивов
     DEF A2[20] = {1,2,3}
     ...
     I1=0   % начальная инициализация переменных
     JJ=101
     ...
     % конец блока инициализации
     START1: % начало "вечного" цикла
       % тело "вечного" цикла
       ...
     GOTO START1 % конец "вечного" цикла
   }
   % здесь, при необходимости, могут 
   % располагаться подпрограммы
   
   Если какие-то куски кода программы состоят из идентичных
команд, то удобнее воспользоваться подпрограммой, состоящей 
из этих команд, например имеем:
   
   ...
   ACT FRONT
   i=i+1
   STEP
   ACT FRONT
   i=i+1
   STEP
   ACT FRONT
   i=i+1
   STEP
   ...
   
   можно записать так:
   
   ...
   CALL SUB1
   CALL SUB1
   CALL SUB1
   ...
   }

   SUB1()  % метка, обозначающая начало нашей подпрограммы
   {
     ACT FRONT
     i=i+1
     STEP
   }
   
   Также бывает полезно воспользоваться двумерными 
массивами. Так как язык RW1 позволяет оперировать лишь 
с одномерными массивами, то приходиться эмулировать 
двумерный массив следующим образом. Пусть нам нужен 
двумерный массив 10 x 10. Для этого мы описываем
массив длиною 100 и макрос @MAP:
   
   @MAP(2)=((@1)+10*(@2))
   DEF ARR[100]
   
   А в программе обращаемся к элементу [x,y] этого 
массива так:
   
   ARR[@MAP(x,y)]=k  % что означает ARR[x,y]=k
   
   или
   
   k=ARR[@MAP(x,y)]  % что означает k=ARR[x,y]
   
   Бывает полезно пользоваться регистром R, который 
возвращает случайное число от 0 до 999. Например, если 
робот натолкнулся на препятствие, то можно развернуть 
его либо влево, либо вправо:
   
   ...
   % поучаем из числа 0..999 или 0, или 1
   IF(R%2) RIGHT  % если у нас получилось 0, то направо
   ELSE    LEFT   % если у нас получилось 1, то налево
   ...
   
   Наверное достаточно, для начала. Если у Вас есть чем с нами
поделиться, присылайте, будем рады вписать в этот раздел Ваши
алгоритмы и мелкие хитрости на языке RW1.


   SPECIAL THANKS

   Collins Tim 
   Ivanov Uriy 
   Kornukhin Uriy
   Malygin Jaroslav 
   Unegov Stepan 


Автор: Александр Шабаршин
Страница создана 6 декабря 1998
Последние изменения внесены 20 мая 2011