http://robots.chat.ru
Первая версия (под MS-DOS) - самая популярная (заработал на ней чуть меньше 200 долларов):

Вторая версия (под Windows) - по сути провальная (картинка кликабельна):

Описание языка программирования RW1 от 2001 года (см. http://robots.chat.ru/rw1_r.html) под спойлером:
Code: Select all
ОПИСАНИЕ ЯЗЫКА ПРОГРАММИРОВАНИЯ RW1
-----------------------------------
Copyright (c) 1998-2001, Alexander Shabarshin (shaos@mail.ru)
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++)
{
...
}
Этот цикл будет выполняться 10 раз.
С помощью команды 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
P.S. Ещё почитать: http://www.nedopc.org/nedopc/sdk/rw1_c_r.shtml