Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 74fbd0eb33bb08f719b79951bc4e329e > files > 78

xconq-7.5.0-1.20050612.5mdv2009.1.i586.rpm

<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.39
     from ./xcdesign.texi on 12 June 2005 -->

<TITLE>Designing Games with Xconq - Language Syntax</TITLE>
</HEAD>
<BODY>
Go to the <A HREF="xcdesign_1.html">first</A>, <A HREF="xcdesign_30.html">previous</A>, <A HREF="xcdesign_32.html">next</A>, <A HREF="xcdesign_61.html">last</A> section, <A HREF="xcdesign_toc.html">table of contents</A>.
<HR>


<H2><A NAME="SEC129" HREF="xcdesign_toc.html#SEC129">Language Syntax</A></H2>

<P>
GDL is intended to be an easily used, yet powerful, tool for people who 
have little programming experience, but who wish to design Xconq game 
modules. For those who have programmed in Lisp before, GDL uses a 
similar syntax, but <EM>knowledge of Lisp is not required</EM> to 
develop Xconq games. Elements of GDL include such things as numbers, 
lists, and tables.

</P>
<P>
Formally, GDL is a <EM>declarative</EM>, or nonprocedural, language, rather
than an imperative language. This means that most of the time, you can 
declare lists, tables, and forms (which will be discussed later) in 
any order you like. There are two significant, though not unreasonable, 
restrictions however. The first is that any symbol, such as a variable 
or the name of a type, must be defined before it is used. The second is 
that a symbol must be used in an appropriate context or scope. This is 
basically to say that you can only assign properties to things for 
which those properties would make sense. Keep in mind that definitions 
can be overwritten with the use of <CODE>set</CODE> and <CODE>add</CODE> (which will
also be discussed later), and the order in which they are used is 
important.

</P>

<UL>
<LI><A HREF="xcdesign_31.html#SEC130">Lexical Elements</A>
<LI><A HREF="xcdesign_31.html#SEC131">Conventions Used</A>
<LI><A HREF="xcdesign_31.html#SEC132">Forms and Evaluation</A>
<LI><A HREF="xcdesign_31.html#SEC133">Tables</A>
<LI><A HREF="xcdesign_31.html#SEC134">Modifying Objects</A>
<LI><A HREF="xcdesign_31.html#SEC135">Symbols</A>
<LI><A HREF="xcdesign_31.html#SEC136">Lists</A>
<LI><A HREF="xcdesign_31.html#SEC137">Arithmetic Operations</A>
<LI><A HREF="xcdesign_31.html#SEC138">Arithmetic Comparisons</A>
<LI><A HREF="xcdesign_31.html#SEC139">Boolean Comparisons</A>
</UL>



<H3><A NAME="SEC130" HREF="xcdesign_toc.html#SEC130">Lexical Elements</A></H3>

<P>
The Xconq interpreter parses GDL declarations into various lexical 
elements, or tokens. These include numbers, strings, symbols,  
comment delimiters, and list/form/table delimiters.

</P>
<P>
Numbers are introduced by a decimal digit, plus, or minus signs.  They
may contain only decimal digits, a decimal point, and be followed
(immediately, no whitespace allowed) by a percent sign. Numbers are 
used where integer quantities, percentages (which may meaningfully 
exceed 100% in many cases), or parts per 10,000 (0.01% increments) are 
expected. Typically numbers are positive. Unless otherwise stated, 
the default value for properties that take numeric values is <CODE>0</CODE>. 
Also of interest is the fact that <CODE>-1</CODE> is often used to indicate 
special behavior of a property or table element, such as "turning off" 
the property, or inheriting a value set in another table. Examples of 
numeric values include the following: <CODE>99</CODE>, <CODE>65.2%</CODE>, 
<CODE>4.00</CODE>, and <CODE>-1</CODE>.

</P>
<P>
Strings are sequences of characters (letters, digits, punctuation marks, 
etc...) enclosed by doublequotes (<CODE>"</CODE>).
They may contain any character except ASCII NUL (<CODE>'\0'</CODE>).  To
include a doublequote, use backslash, as in <CODE>"a \"quoted\"
string"</CODE>.  To include a nonprinting or eight-bit character (often 
associated with international characters or ANSI graphics), use
backslash followed by three octal digits, which will be interpreted as
an eight-bit character code.  (This is mostly the same syntax as in C.)
Note that game design files may be passed over networks and between
different kinds of computer systems, so non-ASCII characters should not
be inserted verbatim into strings. In places where string values are 
expected, the default is <CODE>""</CODE>, unless otherwise stated.

</P>
<P>
Symbols are sequences of characters that don't include any of the other
special characters.  If you wish to include such characters in a symbol,
enclose it in vertical bars, for example <CODE>|foo bar|</CODE>.  (The bars
are not part of the symbol.)  Symbols are case-sensitive, but this will
be changed eventually. Examples of symbols include: <CODE>acp-per-turn</CODE>, 
<CODE>|coastal waters|</CODE>, and <CODE>size</CODE>.

</P>
<P>
Numbers, strings, and symbols all belong to a kind called an <STRONG>atom</STRONG>. 
There are other elements of GDL which are not atoms; these are comments 
and lists.

</P>
<P>
Comments are enclosed either within <CODE>#| |#</CODE>, or else extend from a 
semicolon <CODE>;</CODE> to the end of the line. A comment is equivalent to 
whitespace, so <CODE>a#|bcd|#e</CODE> is the same as <CODE>a e</CODE>, not 
<CODE>ae</CODE>. The <CODE>#| |#</CODE> style comments can be nested (placed inside 
one another) without trouble, and are allowed to extend across multiple 
lines. Note that <CODE>#</CODE> by itself is nothing special and can be used as 
a normal character in, say, a symbol.

</P>
<P>
Lists are a sequence of atoms and/or other lists enclosed in parentheses. 
Empty lists can either be represented by the symbol <CODE>nil</CODE> or by the 
list <CODE>()</CODE>. There is nothing similar to the "dotted pairs" of Lisp; 
if you don't know what dotted pairs are, then don't worry about it. 
Tables and forms, both of which will be discussed in more detail later, 
are delimited by parentheses in the same manner as lists. Indeed, forms 
can be thought of as lists that start with a special symbol, or keyword. 
Lists might look like <CODE>(100 90 0)</CODE>, <CODE>("Lansing" "Denver")</CODE>, 
<CODE>((10 0 10) (5 10 15))</CODE>, <CODE>(cv bb dd)</CODE>, <CODE>("1 atom")</CODE>, or 
<CODE>nil</CODE>. Some examples of things which are not lists are 
<CODE>"1 atom"</CODE>, which, like it says, is one atom, and: <BR>
<CODE>(10 20 ; This comment can cause problems. )</CODE> <BR>
because everything past the semicolon is ignored. An acceptable 
alternative would be: <BR>
<CODE>(10 20 #| This comment will not cause problems. |#)</CODE>

</P>
<P>
All of the things mentioned above may range up to a very large size. In 
particular, numbers can generally hold values up to 32767 (sometimes 
referred to as TABHI or PROPHI in the documentation), though most 
games use values such as <CODE>99</CODE>, <CODE>999</CODE>, or <CODE>9999</CODE> for a value
which is too large to ever be reached.
Most tables are limited to be 127x127 at largest (which is really quite 
large); this is due to <I>Xconq's</I> present internal constraints on the 
number of unit types, terrain types, et cetera, that may be defined. 
Although strings and symbols are allowed to be quite large, one should 
exercise caution and keep them around a 100 characters or less in length, 
lest bugs (or "unexpected features") be tempted to emerge.

</P>
<P>
True/false values are just numbers, with no special characteristics.

</P>
<P>
<U>GlobalConstant:</U> <B><CODE>true</CODE></B><P>
<A NAME="IDX1"></A>
<U>GlobalConstant:</U> <B><CODE>false</CODE></B><P>
<A NAME="IDX2"></A>
These constants are symbolic forms for <CODE>1</CODE> and <CODE>0</CODE>.  They are
identical to numbers, but more descriptive for parameters that are
boolean-valued.

</P>
<P>
Unit, material, and terrain types are distinct objects.  However, they
can be considered to have numeric "indices" assigned in order of the
types' definition.  These numbers are not directly visible in GDL, but
they often affect sorting and ordering.

</P>
<P>
You may also supply numbers as <VAR>dice specs</VAR>, which are used in
several tables.  The syntax is the familiar
<CODE><VAR>nn</VAR>d<VAR>mm</VAR>[+<VAR>oo</VAR>]</CODE>, where <VAR>nn</VAR> is the number of
dice to throw, <VAR>mm</VAR> is the number of values on each die, and the
optional <VAR>oo</VAR> is an value to be added to the result.  The die are
0-based, so for instance <CODE>3d6</CODE> yields values between 0 and 15,
while <CODE>3d6+3</CODE> is equivalent to the result of rolling 3 6-sided
dice.  The range of each value is severely limited; <VAR>nn</VAR> may range
from 0 to 7, <VAR>mm</VAR> from 0 to 15, and <VAR>oo</VAR> from 0 to 127.
Internally, dice specs are normal integers, in the range 16384 to 32767.

</P>



<H3><A NAME="SEC131" HREF="xcdesign_toc.html#SEC131">Conventions Used</A></H3>

<P>
Descriptions of values in this manual follow the conventions listed here.

</P>
<P>
For parameters described as <VAR>t/f</VAR>, both <CODE>1</CODE>, <CODE>0</CODE> and
<CODE>true</CODE>, <CODE>false</CODE> may be used.  Parameters described as <VAR>n</VAR>
and <VAR>n%</VAR> are numbers.  Parameters described as <VAR>dist</VAR> or
<VAR>length</VAR> are also numbers, but are in the unit of measure for
lengths.  Parameters described as <VAR>str</VAR> or <VAR>string</VAR> are strings.

</P>
<P>
Parameters described as <VAR>u</VAR> or <VAR>ui</VAR>, <VAR>m</VAR> or <VAR>mi</VAR>, and
<VAR>t</VAR> or <VAR>ti</VAR>, are values that must be unit, material, or terrain
types, respectively.

</P>
<P>
Parameters described as <VAR>utype-value-list</VAR> match unit types with
values.  They can have several forms:

</P>

<UL>

<LI>

<CODE>(n1 n2 ...)</CODE> matches <CODE>n1</CODE> with type 0, etc in order.

<LI>

<CODE>((u1 n1) (u2 n2) ...)</CODE> evaluates <CODE>u1</CODE> to get a unit type,
then matches it with <CODE>n1</CODE>.  <CODE>u1</CODE> etc may also be a list of
types, in which case all the types get matched with <CODE>n1</CODE>.

</UL>

<P>
Other types of lists, such as those defined as <VAR>side-value-list</VAR>,
are interpreted similarly.  For all of these, multiple assignments to
the same type etc will overwrite quietly.

</P>
<P>
List values described as <VAR>interpolation-list</VAR> are lists of pairs
used to derive numerical values by interpolating between the listed
values.  The form of an interpolation list is always <CODE>((key1 val1)
(key2 val2) ...))</CODE>, where <VAR>keyi</VAR> and <VAR>vali</VAR> are numbers.  If the
input value <VAR>inp</VAR> to an interpolation matches <VAR>keyi</VAR>, the result
value is <VAR>vali</VAR>.  If it is between <VAR>keyi</VAR> and <VAR>keyi+1</VAR>, then
the result is gotten by linear interpolation, with the result value
falling somewhere between <VAR>vali</VAR> and <VAR>vali+1</VAR>.  Fractional
values always round down.  The <VAR>keyi</VAR> must occur in non-decreasing
order; it is legitimate for two consecutive keys to be identical, in
which the result value will be the value associated with the first key.
If the input value is outside the domain specified by the keys, the
result depends on the particular parameter; some will extrapolate in
some appropriate fashion, while others will generate an error or
warning. To be safe, one should set up key-value pairs for the min and 
max of the input domain.

</P>
<P>
One place where an interpolation list is used is the 
<CODE>acp-damage-effect</CODE> property that may be assigned to unit types. 
Suppose we have a unit type named <CODE>battleship</CODE>, which has 30 hit 
points and 6 action points when fully healthy. When the battleship 
reaches various levels of damage, we want to affect its ability to 
act to simulate such things as a gun turret or propeller being destroyed.
To do this, we can assign the <CODE>acp-damage-effect</CODE> property in 
perhaps the following way: <BR>

<PRE>
(unit-type battleship
(acp-damage-effect ((0 0) (10 2) (20 4) (30 6)))
)
</PRE>

<P>
Now how many action points will the battleship have when it has 15 
hit points? The answer should be 3 action points. When it has 14 hit 
points? 2 action points (remember that fractional parts round down).
When it has 16 hit points? Again, 3 action points. When it has 10 
hit points? 2 action points (this can be read directly from the 
interpolation list). When it has 4 hit points? 0 action points.

</P>
<P>
Some values may be boolean expressions.  Boolean expressions are lists
headed by the keywords <CODE>and</CODE>, <CODE>or</CODE>, and <CODE>not</CODE>, and may
nest recursively.  For instance, the expression

<PRE>
(and (or false (not false)) true)
</PRE>

<P>
is always true.  In some contexts, values other than <CODE>true</CODE> and
<CODE>false</CODE> may appear, in which case the interpretation of those
values depends on the context.

</P>
<P>
Some numeric values are <VAR>stochastic</VAR>, meaning that they are partly
fixed and partly probabilistic in effect.  The most common form of this
is values where the part &#62; 100 is divided by 100, while the value mod
100 is the probability to add 1 to the first part.  Thus a value of 425
works out to a value of 4, 3/4 of the time, and to 5, 1/4 of the time,
on average.

</P>
<P>
Unless otherwise stated, all numeric values default to <CODE>0</CODE>, all
string values default to <CODE>""</CODE>, and all form values default to
<CODE>()</CODE>.  If one of these defaults has a notable consequence, such as
inability to perform some action, that will be mentioned.

</P>



<H3><A NAME="SEC132" HREF="xcdesign_toc.html#SEC132">Forms and Evaluation</A></H3>

<P>
A <STRONG>form</STRONG> is any single expression that appears in the file.
A GDL file consists of a sequence of forms.  Most forms of interest will
be lists whose first element is a symbol identifying the form.  For
instance, a form beginning with the symbol <CODE>side</CODE> declares a side
object.  When the file containing such a form is read, <I>Xconq</I> will
create a side object and fill in any properties as specified by the
form.  (Properties are like properties or attributes - most GDL objects
have some.)

</P>
<P>
In most contexts, <I>Xconq</I> will <STRONG>evaluate</STRONG> an expression before
using it, such as when filling in an object's property.  Numbers and
strings evaluate to themselves, while symbols evaluate to their
bindings, as set by <CODE>set</CODE> or <CODE>define</CODE>.  Lists evaluate to a
list of the same length, but with all the elements evaluated, unless the
first element of the list is a function.  In that case, the remaining
elements of the list are evaluated and given to the function, and its
result will be the result.

</P>



<H3><A NAME="SEC133" HREF="xcdesign_toc.html#SEC133">Tables</A></H3>

<P>
A <STRONG>table</STRONG> is a two-dimensional array of values indexed by types.
Indices can be any pair of unit, material, or terrain type.  The set of
tables is fixed by <I>Xconq</I>, and all are described below.

</P>
<P>
<U>Form:</U> <B><CODE>table</CODE></B> <I>table-name items...</I><P>
<A NAME="IDX3"></A>
This is the general form to fill in a table.  The table named by
<VAR>table-name</VAR> is filled in from the <VAR>items</VAR>.  If an item is an
atom, then every position in the table is filled in with that item,
overwriting any previously-specified values.  If an item is a list, it
must be a three-element list of the form <CODE>(<VAR>type1</VAR> <VAR>type2</VAR>
<VAR>value</VAR>)</CODE>.  If both <VAR>type1</VAR> and <VAR>type2</VAR> are single types,
then <VAR>value</VAR> will be put into the table at the position indexed by
the two types.  If one of <VAR>type1</VAR> or <VAR>type2</VAR> evaluates to a
list, <I>Xconq</I> will iterate over all members of the list while keeping
the other type constant, while if both <VAR>type1</VAR> and <VAR>type2</VAR> are
lists, then <I>Xconq</I> will iterate over all pairs from the two lists.
The values used during iteration depend on whether the <VAR>value</VAR> is a
list.  If <VAR>value</VAR> is an atom, then that value will just be used on
every iteration.  If a list, then <I>Xconq</I> will use successive elements
of the list while iterating.

</P>
<P>
If the first member of <VAR>items</VAR> is the symbol <CODE>add</CODE>, then the
rest of the items will add to the existing contents of the table rather
than clearing to its default value first.

</P>
<P>
The following forms are all equivalent:

<PRE>
(table foo (a y 1) (b y 2) (c y 3) (a z 9) (b z 9) (c z 9))

(table foo ((a b c) y (1 2 3)) ((a b c) (z) 9))

(define v1 (a b c))
(table foo (v1 y (1 2 3)) (v1 z 9))

(table foo ((a b c) (y z) ((1 2 3) (9 9 9))))

(table foo (a y 1) (b y 2) (c y 3))
(table foo add ((a b c) z 9))
</PRE>



<H3><A NAME="SEC134" HREF="xcdesign_toc.html#SEC134">Modifying Objects</A></H3>

<P>
Since forms normally define or create new objects, GDL defines the
<CODE>add</CODE> form to modify existing objects.

</P>
<P>
<U>Form:</U> <B><CODE>add</CODE></B> <I>objects property new-values...</I><P>
<A NAME="IDX4"></A>
This form evaluates the atom or list <VAR>objects</VAR> to arrive at the set
of objects to be modified.  Then it uses the <VAR>new-values</VAR> to write
new data into the property named <VAR>property</VAR> of those objects.  The
<VAR>new-values</VAR> may be a single number or string, or a list.

</P>



<H3><A NAME="SEC135" HREF="xcdesign_toc.html#SEC135">Symbols</A></H3>

<P>
Most of the symbols used in a game module are the predefined ones
described in this manual.  Others are attached to types when the types
are defined, and still others name objects like units and sides.  You
can also define and set your own symbols to arbitrary values.

</P>
<P>
<U>Form:</U> <B><CODE>define</CODE></B> <I>symbol value</I><P>
<A NAME="IDX5"></A>
This form defines the symbol <VAR>symbol</VAR> to be bound to the result of
evaluating <VAR>value</VAR>.  If <VAR>symbol</VAR> is already defined, <I>Xconq</I>
will issue a warning, and ignore this form.

</P>
<P>
<U>Form:</U> <B><CODE>set</CODE></B> <I>symbol value</I><P>
<A NAME="IDX6"></A>
This form rebinds the already-bound symbol <VAR>symbol</VAR> to be bound to
the result of evaluating <VAR>value</VAR>.  If <VAR>symbol</VAR> is <EM>not</EM>
bound already, then <I>Xconq</I> will issue a warning, but proceed anyway.

</P>
<P>
<U>Form:</U> <B><CODE>undefine</CODE></B> <I>symbol</I><P>
<A NAME="IDX7"></A>
This form destroys any binding of the <VAR>symbol</VAR>.  This is allowed for
any symbol, including already-unbound symbols.

</P>



<H3><A NAME="SEC136" HREF="xcdesign_toc.html#SEC136">Lists</A></H3>

<P>
Some transformations can be performed on lists. All of these are transforms 
are non-destructive, which is to say that the original list is not altered, 
but a new list with the transformation applied is returned as a result.

</P>
<P>
<U>Function:</U> <B><CODE>quote</CODE></B> <I>form...</I><P>
<A NAME="IDX8"></A>
This function prevents any evaluation of <VAR>form</VAR>.  (This implies that
the abovementioned evaluation of the argument list does <I>not</I> happen
for this "function".)

</P>
<P>
<U>Function:</U> <B><CODE>list</CODE></B> <I>form...</I><P>
<A NAME="IDX9"></A>
This function makes a list out of all the <VAR>form</VAR>.

</P>
<P>
<U>Function:</U> <B><CODE>append</CODE></B> <I>form...</I><P>
<A NAME="IDX10"></A>
NOTE: If you are not a Lisp programmer, be cautious about inferring what this 
function does based on its name.<BR>
This function "appends" all the <VAR>form</VAR> (which may be lists or not)
into a single list.  Another way to state the above is: <CODE>append</CODE> 
gathers everything following it into one list, "flattening out" any lists 
it encounters, and returns the result.

</P>
<P>
<U>Function:</U> <B><CODE>remove</CODE></B> <I>item list</I><P>
<A NAME="IDX11"></A>
This function removes <VAR>item</VAR> from every place that it occurs in 
<VAR>list</VAR>, returning the resulting list. If <VAR>item</VAR> is not found in 
<VAR>list</VAR>, then <VAR>list</VAR> is returned.

</P>
<P>
<U>Function:</U> <B><CODE>remove-list</CODE></B> <I>list1 list2</I><P>
<A NAME="IDX12"></A>
This function removes each item of list <VAR>list1</VAR> from every place that 
it occurs in <VAR>list2</VAR>, returning the resulting list. If no item in 
<VAR>list1</VAR> is found in <VAR>list2</VAR>, then <VAR>list2</VAR> is returned.

</P>
<P>
Some examples of the above commands:

</P>
<P>
The following three are all equivalent examples of quoting; they leave the 
list contents unevaluated when the list is first read.<BR>
<CODE>(quote not "independent")</CODE><BR>
<CODE>'(not "independent")</CODE><BR>
<CODE>`(not "independent")</CODE><BR>

</P>
<P>
Quoting is useful for things that should not be evaluated immediately, but 
may be used Xconq later during run time (after the game has been read in).<BR>
These things include <CODE>synthesis-methods</CODE> and <CODE>possible-sides</CODE>.

</P>
<P>
Here is an example of appending:<BR>
<CODE>(define light-sea-u* (destroyer frigate))</CODE><BR>
<CODE>(define heavy-sea-u* (battleship carrier))</CODE><BR>
<CODE>(define sea-u* (append light-sea-u* heavy-sea-u*))</CODE><BR>
In the above, two lists are defined. Then those two lists are joined 
into a single list, <CODE>sea-u*</CODE>. Note that <CODE>sea-u*</CODE> would 
be equivalent to the following definition:<BR>
<CODE>(define sea-u* (destroyer frigate battleship carrier))</CODE><BR>
and not:<BR>
<CODE>(define sea-u* ((destroyer frigate) (battleship carrier)))</CODE><BR>
because the lists were flattened.

</P>
<P>
Here is another example of appending:<BR>
<CODE>(define wyrms (red-wyrms blue-wyrms green-wyrms))</CODE><BR>
<CODE>(define dragons (append wyrms dragon-turtle))</CODE><BR>
In this case <CODE>wyrms</CODE> is a list, while <CODE>dragon-turtle</CODE> might be 
an atom. The definition of <CODE>dragons</CODE> would therefore be equivalent to:<BR>
<CODE>(define dragons (red-wyrms blue-wyrms green-wyrms dragon-turtle))</CODE>

</P>
<P>
Here is an example of removing a single item:<BR>
<CODE>(define land-combat-u* (infantry mechinf cavalry armor))</CODE><BR>
<CODE>(define motor-land-combat-u* (remove infantry land-combat-u*))</CODE><BR>
The definition of <CODE>motor-land-combat-u*</CODE> would then be equivalent to:<BR>
<CODE>(define motor-land-combat-u* (mechinf cavalry armor))</CODE>

</P>
<P>
Here is an example of removing multiple items:<BR>
<CODE>(define monsters (daleks sontarans cybermen ice-warriors))</CODE><BR>
<CODE>(define bad-robots (remove-list (sontarans ice-warriors) monsters))</CODE>

</P>
<P>
And here is a more sophisticated example of removing and appending:<BR>
<CODE>(define nco-ranks (chief senior-chief master-chief))</CODE><BR>
<CODE>(define low-ranks (ensign lieutenant-jg lieutenant commander))</CODE><BR>
<CODE>(define high-ranks (captain commodore r-admiral v-admiral admiral))</CODE><BR>
<CODE>(define rank-sets (nco-ranks low-ranks high-ranks))</CODE><BR>
<CODE>(define com-ranks (append (remove nco-ranks rank-sets)))</CODE><BR>
which is equivalent to:<BR>
<CODE>(define com-ranks (append low-ranks high-ranks))</CODE><BR>
which is equivalent to:<BR>
<CODE>(define com-ranks (ensign lieutenant-jg lieutenant commander captain commodore r-admiral v-admiral admiral))</CODE><BR>
One should note that in the above example, a list, <CODE>nco-ranks</CODE>, was 
treated as the item to remove.

</P>
<P>
The above example can also be done in terms of <CODE>remove-list</CODE> instead:<BR>
<CODE>(define all-ranks (append nco-ranks low-ranks high-ranks))</CODE><BR>
<CODE>(define com-ranks (remove-list nco-ranks all-ranks))</CODE>

</P>



<H3><A NAME="SEC137" HREF="xcdesign_toc.html#SEC137">Arithmetic Operations</A></H3>

<P>
GDL supports some basic mathematical operations. Addition, subtraction, 
multiplication, and division are all available. To use an operator, it 
must be at the start of a new form; everything after it until the end of 
that form will be interpreted as operands.

</P>
<P>
All four of the basic operators can operate on numbers, lists of numbers, 
and symbols which are bound to either numbers or lists of numbers, and 
any combination thereof. The only constraint is that all lists must be the 
same lengths as one another, with the exception that empty lists are allowed 
and will simply be skipped over. When a number is operated with a list, 
that number is operated with each item of the list. When a list is 
operated with a list, each item of the first operand list is operated 
with the item in the corresponding position of the second operand list. 
Thus, when a number is operated with a number, a number is always returned 
as the result. When a number is operated with a list or vice versa, a list 
is always returned as the result. When a list is operated with a list, then 
another list is always returned as the result.

</P>
<P>
Operators forms can be nested inside one another. Multiple operators 
within the same operator form are not allowed. Precedence is determined 
by evaluating the innermost (most deeply nested) operators first. 
Association is from left to right.

</P>
<P>
The results of operations are still subject to the same constraints as 
numbers and lists produced without operations. Value limits, such as 
<CODE>32767</CODE> and <CODE>-32768</CODE>, still apply. Because of this, you should 
be careful not to multiply, add, or subtract quantities that are too large 
in numeric magnitude or you may end up with undesired results.

</P>
<P>
Another thing to note about numbers is that, to Xconq, <CODE>10</CODE>, 
<CODE>10%</CODE>, and <CODE>0.10</CODE> are all the same thing. Likewise for 
<CODE>400</CODE>, <CODE>400%</CODE>, and <CODE>4.00</CODE>. Generally, when designing a 
game, you should not have to worry about how these number representations 
are handled internally; that is for the Xconq code writers to worry about. 
However, if you are doing math on numbers, this knowledge does come into 
play, unfortunately. For instance, if you use GDL to multiply a plain 
integer by a percent, you will not get a result that is a percentage of the 
integer. Some of the examples below will show you the correct way to deal 
with this and other similar situations. Also note that dice specs are 
treated as numbers internally in Xconq, and so there is a special way to 
manipulate them as well. Again, this will be demonstrated in the examples 
below.

</P>
<P>
<U>Function:</U> <B><CODE>+</CODE></B> <I>operands...</I><P>
<A NAME="IDX13"></A>
Sums all of the <VAR>operands</VAR> together. If only one operand is present, 
then that operand is returned unaltered. If no operands are present, then 
the additive identity, <CODE>0</CODE>, is returned.

</P>
<P>
<U>Function:</U> <B><CODE>-</CODE></B> <I>operand1 operands...</I><P>
<A NAME="IDX14"></A>
Subtracts all of the <VAR>operands</VAR> from <VAR>operand1</VAR>. If only 
<VAR>operand1</VAR> is present, then <CODE>0</CODE> minus <VAR>operand1</VAR> is 
returned. If no operands are present, then it returns <CODE>nil</CODE>.

</P>
<P>
<U>Function:</U> <B><CODE>*</CODE></B> <I>operands...</I><P>
<A NAME="IDX15"></A>
Multiplies all the operands together. Must have at least two operands 
to multiply, or else it returns <CODE>nil</CODE>, except when no operands 
are specified, in which case it returns the multiplicative identity, 
<CODE>1</CODE>.

</P>
<P>
<U>Function:</U> <B><CODE>/</CODE></B> <I>operand1 operands...</I><P>
<A NAME="IDX16"></A>
Divides all of the <VAR>operands</VAR> into <VAR>operand1</VAR>. If less than 
two operands are present, then it returns <CODE>nil</CODE>.<BR>
NOTE: Unlike Common Lisp, GDL does not support rational numbers, and 
therefore it is not possible for division with a single operand to return 
the reciprocal of that operand as Common Lisp implementations do. 
Furthermore, since all arithmetic is integer arithmetic in GDL, values 
between integers cannot be represented; numbers between <CODE>0</CODE> and 
<CODE>1</CODE> will appear as <CODE>0</CODE>.

</P>
<P>
Here are some examples of addition:<BR>
<CODE>(+ 1 1)</CODE><BR>
  returns <CODE>2</CODE><BR>
<CODE>(+ 1 2 3 4 5)</CODE><BR>
  returns <CODE>15</CODE><BR>
<CODE>(+ 1 (-1 2))</CODE><BR>
  returns <CODE>(0 3)</CODE><BR>
<CODE>(+ (50% 75%) 25%)</CODE><BR>
  returns <CODE>(75% 100%)</CODE><BR>
<CODE>(+ (0.33 0.67) (0.67 1.33))</CODE><BR>
  returns <CODE>(1.00 2.00)</CODE><BR>
<CODE>(define FOOD_RATS_LOSS 20%)</CODE><BR>
<CODE>(define FOOD_ROT_LOSS 10%)</CODE><BR>
<CODE>(define FODD_LOSS (+ FOOD_RATS_LOSS FOOD_ROT_LOSS))</CODE><BR>
  is the same as<BR>
<CODE>(define FOOD_LOSS 30%)</CODE><BR>
<CODE>(+ (10 20) (30 40) (50 60) (70 80) (90 0))</CODE><BR>
  returns <CODE>(250 200)</CODE><BR>
<CODE>(+ 10 25 (+ 20 25))</CODE><BR>
  returns <CODE>80</CODE><BR>
<CODE>(+ -4)</CODE><BR>
  returns <CODE>-4</CODE><BR>
<CODE>(+ 190)</CODE><BR>
  returns <CODE>190</CODE><BR>
<CODE>(+)</CODE><BR>
  returns <CODE>0</CODE>

</P>
<P>
Here are some examples of subtraction:<BR>
<CODE>(- 10 5)</CODE><BR>
  returns <CODE>5</CODE><BR>
<CODE>(- 15 5 4 3 2)</CODE><BR>
  returns <CODE>1</CODE><BR>
<CODE>(- 10 (4 5))</CODE><BR>
  returns <CODE>(6 5)</CODE><BR>
<CODE>(- (10 15) 10)</CODE><BR>
  returns <CODE>(0 5)</CODE><BR>
<CODE>(- (1.00 1.50) (0.25 0.45))</CODE><BR>
  returns <CODE>(0.75 1.05)</CODE><BR>
<CODE>(- 50%)</CODE><BR>
  returns <CODE>-50%</CODE><BR>
<CODE>(define burden 25%)</CODE><BR>
<CODE>(define speed-effect (- burden))</CODE><BR>
  is equivalent to<BR>
<CODE>(define speed-effect -25%)</CODE>

</P>
<P>
Here are some examples of multiplication:<BR>
<CODE>(* 5 5)</CODE><BR>
  returns <CODE>25</CODE><BR>
<CODE>(* 5 4 3 2 1)</CODE><BR>
  returns <CODE>120</CODE><BR>
<CODE>(* -1 (5 10))</CODE><BR>
  returns <CODE>(-5 -10)</CODE><BR>
<CODE>(* (25% 50%) 5)</CODE><BR>
  returns <CODE>(125% 250%)</CODE><BR>
<CODE>(* (2.00 5.00) (10 5))</CODE><BR>
  returns <CODE>(20.00 25.00)</CODE><BR>
<CODE>(*)</CODE><BR>
  returns <CODE>1</CODE>

</P>
<P>
Here are some examples of division:<BR>
<CODE>(/ 14 2)</CODE><BR>
  returns <CODE>7</CODE><BR>
<CODE>(/ 15 2)</CODE><BR>
  also returns <CODE>7</CODE><BR>
<CODE>(/ 80 100)</CODE><BR>
  returns <CODE>0</CODE><BR>
<CODE>(/ 12 (6 4 3 2))</CODE><BR>
  returns <CODE>(2 3 4 6)</CODE><BR>
<CODE>(/ (15 10) 5)</CODE><BR>
  returns <CODE>(3 2)</CODE><BR>
<CODE>(/ (100% 250%) (2 5))</CODE><BR>
  returns <CODE>(50% 50%)</CODE>

</P>
<P>
To take a percentage of a number, you need to do something like the 
following:<BR>
<CODE>(/ (* 4 50%) 100)</CODE><BR>
  which returns <CODE>2</CODE>

</P>
<P>
To properly multiply a number by a decimal factor, you must do something 
like the following:<BR>
<CODE>(/ (* 5 4.00) 100)</CODE><BR>
  which returns <CODE>20</CODE><BR>
<CODE>(/ (* 40 0.25) 100)</CODE><BR>
  which returns <CODE>10</CODE><BR>
<CODE>(/ (* 3.00 3.00) 100)</CODE><BR>
  which returns <CODE>9.00</CODE>, or <CODE>900</CODE> if you prefer to see it that way

</P>
<P>
To properly multiply a number by a fraction, try something like the 
following:<BR>
<CODE>(/ (* full-speed 4) 5)</CODE><BR>
  which returns four-fifths of <CODE>full-speed</CODE>

</P>
<P>
[ TODO: Write examples of dice spec manipulation. ]

</P>



<H3><A NAME="SEC138" HREF="xcdesign_toc.html#SEC138">Arithmetic Comparisons</A></H3>

<P>
Xconq supports most of the typical Lisp arithmetic comparison operators 
in GDL.  In the case where only one expression is present in the comparison 
form, the result is always non-<CODE>nil</CODE>.  If any comparison fails, the 
result is <CODE>nil</CODE>.  If no comparison fails, then a true result like 
Lisp's <CODE>t</CODE> is returned.

</P>
<P>
<U>Function:</U> <B><CODE>=</CODE></B> <I>exp...</I><P>
<A NAME="IDX17"></A>
Test if all expressions are equal.

</P>
<P>
<U>Function:</U> <B><CODE>/=</CODE></B> <I>exp...</I><P>
<A NAME="IDX18"></A>
Test if any expression is not equal to another one.

</P>
<P>
<U>Function:</U> <B><CODE>&#62;</CODE></B> <I>exp...</I><P>
<A NAME="IDX19"></A>
Test if the list of expressions is monotonically decreasing.

</P>
<P>
<U>Function:</U> <B><CODE>&#62;=</CODE></B> <I>exp...</I><P>
<A NAME="IDX20"></A>
Test if the list of expressions is monotonically nondecreasing.

</P>
<P>
<U>Function:</U> <B><CODE>&#60;</CODE></B> <I>exp...</I><P>
<A NAME="IDX21"></A>
Test if the list of expressions is monotonically increasing.

</P>
<P>
<U>Function:</U> <B><CODE>&#60;=</CODE></B> <I>exp...</I><P>
<A NAME="IDX22"></A>
Test if the list of expressions is monotonically nonincreasing.

</P>



<H3><A NAME="SEC139" HREF="xcdesign_toc.html#SEC139">Boolean Comparisons</A></H3>

<P>
Xconq supports the three primary boolean comparisons.  These comparisons 
are used in places such scorekeepers tests.  However, boolean comparisons 
are also used in side-and-side-class lists, and these follow special 
evaluations rules which do not conform to those listed below.  Always pay 
attention to the context of the boolean expression so that you can 
understand its evaluation behavior.

</P>
<P>
<U>Function:</U> <B><CODE>and</CODE></B> <I>exp...</I><P>
<A NAME="IDX23"></A>
The result is the last expression if all the operands are non-<CODE>nil</CODE>.
If any are false, then the result is <CODE>nil</CODE>.

</P>
<P>
<U>Function:</U> <B><CODE>or</CODE></B> <I>exp...</I><P>
<A NAME="IDX24"></A>
The result is the first non-<CODE>nil</CODE> expression.
If all are false, then the result is <CODE>nil</CODE>.

</P>
<P>
<U>Function:</U> <B><CODE>not</CODE></B> <I>exp</I><P>
<A NAME="IDX25"></A>
The result is <CODE>nil</CODE>, if the expression is non-<CODE>nil</CODE>.
Otherwise, the result is equivalent to Lisp's <CODE>t</CODE>.

</P>

<HR>
Go to the <A HREF="xcdesign_1.html">first</A>, <A HREF="xcdesign_30.html">previous</A>, <A HREF="xcdesign_32.html">next</A>, <A HREF="xcdesign_61.html">last</A> section, <A HREF="xcdesign_toc.html">table of contents</A>.
</BODY>
</HTML>