Для анализа данных в Galaxy Communicator реализован анализатор и выполнитель выражений и макросов. Он используется для фильтрования, выполнения запросов над таблицами, а так же для написания макро- функций, которые можно выполнять над таблицами, которые доступны макроязыку.
На данный момент доступны 3 таблицы:
Обращение к таблицам возможно с помощью префикса – имени таблицы. Например: Race.Wpn или ShipGroup.Weight.
Для запросов и фильтров нужно указывать выражение. Выражение может состоять из операндов и операций.
Операнды могут быть, как стоковые или числовые константы, так и названием поля обрабатываемой таблицы.
Кроме этого операндом может быть вызов функции реализованной в макроязыке.
Операции делятся на унарные и бинарные.
Унарных операций две: унарный минус, и отрицание(not). Все остальные операции бинарные(+,-,*,/, and, or, >, <, >=, <=, <>, =, ==, &, |). Операция == применяется для сравнения строк без учета регистра.
Стоит отдельно рассмотреть операцию разыменовывания '^' - это операция позволяет формировать обращение к нужной планете. Имя планеты является левым операндом, правым может быть произвольное выражение, которое может обращаться к полям данной планеты. Например, для определения размера нужной планеты можно написать '#1'^.size или var1^.size, если значение переменной var1 во время выполнения будет равно названию или номеру планеты, то результат выражения будет равен размеру этой планеты. В списке кораблей так же можно обращаться к полям dest и from с помощью операции разыменовывания. Например, что бы отфильтровать корабли, которые находятся вместе с кораблями нужной вам расы на одной планете нужно достаточно установить фильтр dest^.fleet('RaceName')>0.
Кроме операции разыменования есть альтернативная возможность обращения не только к планете, но и к расе и к кораблю. Для этого в макроязык встроены операторы выборки одной записи из таблицы WinRace, WinPlanet, WithGroup, имеющие следующий синтаксис:
WithRace
<expression> [ as 'name'] do {<operator>;} EndWith;При выполнении оператора, происходит поиск значения выражения в соответствующей таблице и формирование таблицы состоящей из одной записи. К расе нужно обращаться по имени, к кораблю по номеру. Список операторов выполняется уже в контексте новой таблицы, и все обращения к полям будут выполнены как обращения к полям этой таблицы. Name - необязательный параметр в этой конструкции, но его использование дает возможность в последствие обращаться к данной таблице по этому имени, уже без апострофов.
Например, макрос:
macro GetDrive;
begin
WithRace me as 'mytable' do
result:=mytable.drv;
EndWith;
end;
Будет возвращать значение технологии двигателей главной расы.
Если нужно сформировать таблицу из нескольких записей, удовлетворяющих определенному условию, то нужно воспользоваться операторами WithRaces, WithPlanets, WithGroups. Синтаксис аналогичный оператору выборки одной записи. Различие в том, что выражение является фильтром, который будет применен к данной таблице. Т.е. более медленный аналог макроса GetDrive можно написать в таком виде:
macro GetDrive;
begin
WithRaces 'name="'+me+'"' do do
result:=drv;
EndWith;
end;
Стоковые константы указываются в кавычках (одинарных или двойных), возможно вложение одних кавычек в другие. Стоит учитывать, что все операции сравнения над стоками производится с учетом регистра. Т.е. 'World'<>'WorLD'. Это обусловлено тем, что все без исключения сервера Galaxy, так же различают регистры, и вполне возможно некорректная работа выполнителя в случаях, когда у Вас в галактике, кто-то этим пользуется.
Пример: “Normal 'string' constant”
Для числовых констант возможно написание, как с фиксированной точкой, так и в экспоненциальной форме.
Пример: 1e-3, 0.001
Поле таблицы совпадает с его названием при отображении.
Поле может быть написано без учета регистра.
Кроме этого есть константы:
#NL – константа перевода на новую строку
Но для 3 таблиц (Расы, Планеты, Список Групп) есть дополнительные вычислимые поля.
Все поля этих таблиц перечислены ниже.
Поля расы
Name |
имя расы |
Drv |
Технология по двигателям |
Wpn |
Технология по оружию |
Shld |
Технология по защите |
Crg |
Технология по перевозке |
Pop |
общее население |
Ind |
общая индустрия |
# |
число планет |
State |
Статус |
Votes |
число голосов |
Rating |
Простой рейтинг расы |
Level |
Комплексный рейтинг расы |
Team |
Команда, для игры серии Team |
VisiblePlanets |
равно 1, если Вы видите, хотя бы одну планету данной расы, иначе 0 |
VisibleShips |
равно 1, если Вы видите, хотя бы один корабль данной расы, иначе 0 |
DDrv |
прирост технологии двигателей за этот ход |
DWpn |
прирост технологии оружия за этот ход |
DShld |
прирост технологии защиты за этот ход |
DCrg |
прирост технологии перевозок за этот ход |
DPop |
прирост населения за этот ход |
DInd |
прирост индустрии за этот ход |
D# |
прирост планет за этот ход |
DVotes |
прирост голосов за этот ход |
Поля планеты
Num |
номер планеты для Galaxy Plus |
Name |
имя планеты |
Size |
Размер планеты |
Pop |
Население планеты |
Ind |
Индустрия планеты |
Res |
Ресурс планеты |
Production |
Установленное производство |
$ |
Промышленность |
Mat |
Материалы |
Col |
Колонисты |
L |
Свободный производственный потенциал |
Race |
Владелец расы или Uninhabited или Unidentified |
Qlty |
вес корабля, производимый планетой при POP=Size и IND=Size |
OutCap |
Количество промышленности планетой за ход |
OutWgt |
вес корабля, производимый планетой за ход |
Battle |
Размер битвы на планете, если битвы не было, то значение 0 |
BestETA |
через сколько ходов прилетит на планету наблюдатель. Имеет значение 0, при наличии наблюдателя и -1, при отсутствии летящих кораблей на данную планету |
YourFleet |
масса вашего флота на орбите планеты |
FriendFleet |
масса союзного флота на орбите планеты |
AlienFleet |
масса вражеского флота на орбите планеты |
DestTo(Pl) |
Расстояние от данной планеты до указанной (параметр - строка) |
Ships(Race), Fleet(Race) |
Масса флота расы, на орбите планете (параметр срока) |
Team |
Команда, для игры серии Team |
CanSendTo(Pl) |
Находится ли данная планета в области доступных для перелета планет |
StrName |
Строковое представление имени планеты, равно name, если имя не пустое, иначе #<num> |
Поля для кораблей
Grp |
группа, или -1, если корабль не Ваш |
# |
Количество кораблей в группе |
Name |
имя типа корабля |
Drv |
Технология по двигателям |
Gun |
Характеристика корабля по количеству пушек |
Wpn |
Технология по оружию |
Shld |
Технология по защите |
Crg |
Технология по перевозкам |
Attack |
Эффективная атака |
Defence |
Эффективная защита |
Cargo |
Размер трюма |
Q |
Количество загруженного груза в трюм |
Typ |
тип загруженного груза |
Dest |
Планета назначения |
From |
Планета, откуда летит корабль |
R |
Расстояние до планеты назначения, либо 0, если корабль не летит |
Weight |
вес корабля |
Fleet |
Название флота, либо пустая строка |
State |
статус корабля |
Speed |
Скорость корабля |
ESpeed |
Скорость пустого корабля |
CSpeed |
Скорость полностью загруженного корабля |
D |
Характеристика корабля по двигателю |
W |
Характеристика корабля по мощности пушек |
S |
Характеристика корабля по защите |
C |
Характеристика корабля по трюму |
Race |
имя расы владельца |
Bomb |
Бомбардировка одного корабля в группе |
WarShip |
Имеет значение 1, если это боевая группа кораблей имеющая вес более 1 или насчитывает более 1 корабля, иначе значение 0. |
Waitl |
Имеет значение 1, если группа готова к запуску (находится на орбите, имеет двигатель, и это не группа общей массой менее 2). |
ETA |
Количество ходов, необходимое для преодоления расстояния R до планеты назначения |
CanSendTo(Planet) |
Имеет значение количество ходов, требуемое для полета до Planet, если группа может быть отправлена на данную планету, иначе -1 |
Team |
Команда, для игры серии Team |
DestTo(Pl) |
Расстояние от планеты назначения до указанной (параметр - строка) |
Кроме этих полей каждая таблица имеет поле Count и функцию Current(NewPos). Count - возвращает количество записей в таблице, нумерация идет от 0 до count. Функция Current позволяет менять текущую запись в таблице в значение NewPos. Например, sum(#*Weight) может быть переписана на макроязыке следующим образом:
macro mysum;
var
summa, i;
begin
summa:=0;
for i:=0 to shipgroup.count do
shipgroup.current(i);
summa:=summa+shipgroup.#*shipgroup.Weight;
endfor;
result:=summa;
end;
Причем, этот макрос может быть выполнен в любом окне запроса, так как содержит обращение к shipgroup и не зависит от текущей активной таблицы.
Синтаксис макроязыка
Для написания полноценных макросов разработан макроязык. Для этого нужно создать файл gcomm.mac в каталоге расположения gcomm.exe и в этот файл вставляются все описания макросов.
Синтаксис описан ниже:
Макрос объявляется следующим образом:
Macro <ident>[(<ident>{,<ident>})];
Var <ident>{,<ident>};
Begin
{<operator>;}
End;
,где в части VAR указывается список переменных, тип переменных определяется во время выполнения и может динамически меняться.
Кроме этого всегда есть зарезервированная переменная result, значение которой определяет результат функции.
Ниже приведен синтаксис операторов языка
<operator> ::=
if <expression> then {<operator>;} [else {<operator>;}] endif
for <ident>:= <expression> to <expression> do {<operator>;} endfor
while <expression> do {<operator>;} endwhile
<ident>:=<expression>
<function call>
Стоит отметить что, возможно, использовать рекурсию.
Функции макроязыка
PlanetDest("планета1", "планета2") |
Результат функции - расстояние между двумя планетами |
sum(<выражение>) |
Агрегационная функция, выполняет <выражение> для каждой строки таблицы, и вычисляет сумму этих выражений |
avg(<выражение>) |
Агрегационная функция, выполняет <выражение> для каждой строки таблицы, и вычисляет среднее этих выражений |
count |
возвращает количество строк в данной таблице |
me |
возвращает имя расы, за которую был загружен отчет |
FloatToStr(<число>[,<N>,<D>]) |
Преобразование
числа в строковое представление, при этом можно
указать общее число чисел (N), и число знаков после
запятой(D). По умолчанию N=10, D=2. |
sqrt, sqr, sin, cos, ln, exp, round, trunc |
математические функции с вещественным аргументом |
AddCommand("команда") |
добавление команды в приказ, при этом команда выполняется |
StrPos(<подстрока>,<строка>) |
Нахождение первого вхождения подстроки в строке, результат позиция в строке, иначе 0 |
StrChar(<строка>, N) |
Быстрое получение N символа из строки |
StrCopy(<строка>, P,N) |
Выделение подстроки из строки с позиции P и длиной N символов |
StrLen(<строка>) |
Получение длины строки |
StrCut(<строка>, P,N) |
Удаление подстроки из строки с позиции P и длиной N символов |