cual man page on DragonFly

Man page or keyword search:  
man Server   44335 pages
apropos Keyword Search (all sections)
Output format
DragonFly logo
[printable version]

CUAL(6)								       CUAL(6)

NAME
       Cual - Cuyo Animation Language

       Cual  is	 the  main  language  used to describe the animations in cuyo.
       Strictly speaking it's the stuff between the  <<	 >>  brackets  in  the
       level description files (xxx.ld).

       On the other hand this man page aims at being a complete description of
       how to write levels for cuyo.  But it's still under construction.   See
       the  file  "example.ld"	to  get	 an  idea of how the rest of the level
       description works.  There's also a bit of example Cual code  in	"exam‐
       ple.ld".	 And of course, all the existing levels are examples.

       Note that Cual is probably still very buggy.  So if strange things hap‐
       pen and you're sure it's not your fault, tell me (cuyo@karimmi.de).

HOW IT WORKS
       The level description is organized in sections.	There is a global sec‐
       tion  and every level has its own section, which is a subsection of the
       global section.	It is common practice to place each level in  a	 sepa‐
       rate  file, which then basically starts by opening its section and ends
       by closing it.

       A section is defined by name = {contents}.  name is the name of the new
       section and contents contains the definitions that pertain to that sec‐
       tion.  This is a sequence of definitions of  the	 form  name  =	stuff.
       Here  stuff can be {contents} as above, or it can be a single datum, or
       it can be a comma-separated list of data.  Inside such a list, datum  *
       number can be used as a shorthand for datum, ..., datum, i.e. a number-
       fold repetition of datum.  A datum  can	be  an	identifier,  a	string
       (enclosed  by '"'), a word, or a number.	 In place of a number <expres‐
       sion> can be used, where expression is an arbitrary expression made  up
       from  literal  numbers, previously defined numeric data, and the opera‐
       tors +, -, *, / and %.

       Definitions can also depend on versions.	 See section VERSIONING below.

       Apart from definitions, a section can  also  contain  cual  definitions
       (see below).  These have to be enclosed in << and >>.

       Each  blob has its own (main) Cual procedure which does the drawing and
       the animation stuff.  The procedure only depends on  the	 kind  of  the
       blob, that is, it is the same for blobs of the same kind.  However each
       blob has its own instance of the variables.

       In every game step, the procedure of each of the blobs is called	 once.
       (There  are  12.5 game steps per second.)  It has to draw the blob each
       time, even if nothing has changed.  (However, there's an internal  rou‐
       tine  in cuyo which checks if the same is drawn as in the last step and
       which then supresses the drawing.)

       There may be other procedures associated to a kind of blob,  which  are
       executed	 at special events, for example when a falling blob lands.  In
       contrast to the main procedure, these event handlers are not allowed to
       draw  anything.	 See section EVENT HANDLERS for a list of the existing
       events.

       The name of the main procedure of a blob (the one which draws the blob)
       is  the	name of the kind of the blob.  Normally, that name is the word
       listed after pics= entry in the .ld file; but if that "word" contains a
       dot,  only  the	part  before  the  dot makes up the name.  (E. g. with
       pics=redblob.xpm,greenblob.xpm, the names  are  "redblob"  and  "green‐
       blob".)

       The  name  of  an event handler procedure is the name of the kind, fol‐
       lowed by a dot, followed by the event name.  (E.g.  "redblob.land"  for
       the landing event of the redblob from above.)

       [Explain the default procedures.]

LEVEL DATA
   String valued data
       name   The  name	 of  the level.	 This appears in the list of levels as
	      well as in the level intro.

       description
	      This is an optional further description  of  the	level  in  its
	      intro.

       author The name of the level author(s) for credit at the beginning of a
	      level.

   Identifier valued data
       bgpic  Background picture (file name).  If too small, placed at bottom.
	      Defaults to none.

       toppic Appearance  of the top border coming down (file name).  Defaults
	      to none.

       explosionpic
	      Appearance of the explosions (file name).	 Has a default.

   Number valued data
       numexplode
	      The size that a group of blobs has to reach in order to explode.
	      This  is	only  the  level-wide default.	Each kind can override
	      this.  Whether the group does explode is also controlled by  be‐
	      haviour.	See section VARIABLES AND CONSTANTS for details.

       toptime
	      Time  the	 border	 takes	to come down, in number of game steps.
	      Each game step lasts 80ms.  The default value is	50  (i.e.  one
	      pixel every four seconds).

       topoverlap
	      Placement	 of  toppic  relative to the actual border.  More pre‐
	      cisely, number of pixels the lower  border  of  the  picture  is
	      below the actual border.	Defaults to the height of the picture.

       topstop
	      When  the	 border	 comes down at the end of the level, number of
	      pixels it should stop before the bottom.	Set this to  the  same
	      value as topoverlap if you want your toppic to be comletely vis‐
	      ible at the end.	Defaults to 0.

       chaingrass
	      Must be 0 or 1.  If set to 1, chain reactions are	 necessary  to
	      kill the grass.  Defaults to 0.  More precisely, chaingrass only
	      controls the default for behaviour for grass blobs.  See section
	      VARIABLES AND CONSTANTS for details.

       mirror Must  be	0  or  1.  If set to 1, the level appears upside-down.
	      Defaults to 0.

       randomfallpos
	      Must be 0 or 1.  If set to 1, the initial fall position is  ran‐
	      domized horizontally.  Defaults to 0.

       neighbours
	      Determines  in  which  directions	 the blobs can connect to each
	      other in order to form groups.   This  is	 only  the  level-wide
	      default.	 Each  kind  can override this.	 See section VARIABLES
	      AND CONSTANTS for values.	 Defaults to neighbours_rect.

       hexflip
	      In hex mode, determines whether the even or the odd columns  are
	      shifted  upwards.	 By default (hexflip = 0), the odd columns are
	      shifted. 1 means: shift even columns of player 1; 2 means: shift
	      even  columns  of	 player 2; 3 means: shift even columns of both
	      players.

       randomgreys
	      The expected time between two randomly appearing greys  in  game
	      steps (80ms).  Use -1 for none at all, which is the default.

       nogreyprob
	      The  probability	that a grey does not appear.  See greyprob and
	      colourprob in section KIND DATA for details.  The default is 0.

       aiu_color, aiu_grass, aiu_grey,	aiu_two_above,	aiu_monochromic_verti‐
       cal, aiu_height
	      Parameters  for  the  AI	player's  utility  function.   Default
	      respectively to <10*(number of kinds)>, 20,  10,	<aiu_color/2>,
	      <aiu_color>,  and	 10.   See section THE AI UTILITY FUNCTION for
	      details.

   Colour valued data
       (A colour is an RGB triple of numbers between 0 and 255.)

       bgcolor
	      The background colour.  Defaults to white.

       textcolor
	      Colour of any text.  This includes the beginning-of-level infor‐
	      mation,  message()s,  and score.	Defaults to a certain shade of
	      dark grey.

       topcolor
	      The colour of the top border comming down (where not  determined
	      by toppic).  Defaults to a certain shade of light grey.

   Other data
       startdist
	      Distribution  of	blobs  at the beginning of the level.  It is a
	      list of strings, the format of which is described in the section
	      STARTDIST.

       pics, greypic, startpic, emptypic
	      Lists of kinds.  These can be either file names referring to the
	      picture to be used, or declarations of kinds  that  have	to  be
	      defined  later on.  The different keywords (e.g. pics, emptypic)
	      define different defaults.  In fact, only the first three may be
	      real  lists, emptypic is limited to exactly one entry.  In these
	      lists, it is advisable to	 use  *	 whenever  possible.   Besides
	      being  shorter  to write, it also speeds up loading of the level
	      and cuts down memory usage.  This is because cuyo does some ini‐
	      tializations only once for each entry with multiplier.

	      The  intentions  of these lists are normal blob kinds resp. grey
	      blob kind resp. grass blob kind  resp.  nothing-blob.   However,
	      the  only differences between pics, greypic and startpic are the
	      default values for behaviour,  colourprob,  goalprob,  greyprob,
	      versions	and  distkey  (see  there).   All of these can also be
	      overridden individually.	Also, the default drawing code is dif‐
	      ferent.	(The  default  drawing code for startpic does not draw
	      connections.)

       kind   Each kind can have its own section.  See KIND DATA below for the
	      entries of that section.

KIND DATA
       numexplode, neighbours
	      Defining	these  data  in	 the  section  of a kind overrides the
	      level-wide value for the kind.  See section  LEVEL  DATA	for  a
	      description of these data.

       pics   A	 list of file names of pictures to be used for this kind.  The
	      nth entry can later be accessed in cual with file=n-1.

       colourprob
	      The probability that this kind appears as one of the two steered
	      falling  blobs.	More  precisely, this is a nonnegative integer
	      weight.  For determining the actual probability,	the  value  is
	      divided  by  the	sum of the colourprobs of all kinds.  This sum
	      must be positive.	 The default is	 1  for	 kinds	declared  with
	      pics=  and  0 for all other kinds.  The probability is also used
	      for + in startdist.  For more details see section STARTDIST.

       goalprob
	      This affects the semantics of * in startdist in the same way, as
	      colourprob does for +.  The default is 1 for kinds declared with
	      startpic= and 0 for all other kinds.

       greyprob
	      The probability that this kind appears as a grey blob.  This  is
	      similar  to colourprob, but there is a difference: For greyprob,
	      nogreyprob is included in the sum, so that it might happen  that
	      no blob appears at all.  There is a notable difference between a
	      positive nogreyprob and a positive  greyprob  in	kind  nothing,
	      when  several  lines  of	grey blobs appear: In the latter case,
	      empty blobs appear in the wall of greys, making holes.   In  the
	      former  case,  the  wall	is  made  less	high.  Usually this is
	      preferable.  The default is 1 for kinds declared	with  greypic=
	      and 0 for all other kinds.  The value also affects the semantics
	      of - in startdist.  In this case, nogreyprob is not included  in
	      the sum.

       versions
	      At  the creation of a blob, its version variable is initialized.
	      Usually, it is chosen at random from 0 to versions-1, but start‐
	      dist  provides  the possibility to specify it exactly.  See sec‐
	      tion STARTDIST for details.  The default is 1.

       distkey
	      An alphanumerical key, which is used in  startdist  to  identify
	      this  kind  of  blob.   The default is A for kinds declared with
	      startpic and undefined for all other kinds.  See section	START‐
	      DIST for details.

CUAL DEFINITIONS
       Inside << >>, variable and procedure definitions are expected.

       procname = code ;
	      Defines  a  "procedure".	 The  next  section describes how code
	      looks like.  Example:

		redblob = {
		  schema16; 0*;
		  1; A,B,C; *;
		};

       var varname1 [= def1 [: reapply]], varname2 [= def2 [: reapply]], ... ;
	      Defines variables with default values.  If no default is	speci‐
	      fied,  zero  is used.  See section VARIABLES AND CONSTANTS about
	      the meaning of the default value and the optional suffix : reap‐
	      ply.

       default varname1 = def1 [: reapply], varname2 = def2 [: reapply], ... ;
	      Changes  the  default for already defined variables.  Again, the
	      suffix : reapply is optional.  This is useful to give to a  sin‐
	      gle  kind	 a  different default for a variable than to the other
	      kinds.  Also, the default of a system variable  can  be  changed
	      this way.

CODE
       A code fragment can be one of the following:

       { code; code; ...}
	      Executes one command after the other.

       code, code, ...
	      This  is	useful for simple animations.  Executes exactly one of
	      the commands: In the n-th call, the n-th	command	 is  executed.
	      After  the  last command, the first one is executed again.  How‐
	      ever, if one of the commands is "busy" (see section  BUSIENESS),
	      this  one	 will  be executed until it stops being busy, and only
	      after that, the next command will be executed.

       procname
	      Executes	the  procedure	procname,  which  has  to  be  already
	      defined.	 The  result  is the same as if the code from procname
	      would have been inserted in that place.

       &procname
	      Executes the procedure procname; however, every instance of such
	      a	 procname  is the same.	 This concerns busieness and the state
	      of an animation sequence.	 (See sections	BUSIENESS  and	AMPER‐
	      SAND-CALL.)

       busy   Does nothing except being busy.  (See section BUSIENESS.)

       varname = expr
	      Sets  the	 variable.   See  section  VARIABLES AND CONSTANTS for
	      details.

       The same with +=, -=, *=, /=, %=, .+=, .-=.
	      Does what you would expect.

       [ varname = expr ] code
	      Sets the variable varname to expr, executes code and then resets
	      the variable to the old value.

       number A shortcut for file = number.

       letter A	 shortcut  for pos = number, where different letters mean dif‐
	      ferent numbers: A: 0, B: 1, ..., Z: 25, a: 26, ..., z: 51

       *      Draw the icon specified by the variables	kind,  file  and  pos.
	      May also draw only a part of the icon, if specified by the vari‐
	      able qu (see section VARIABLES AND CONSTANTS).

       *@(position)
	      Like *, but draws the icon at some other position.  This drawing
	      is performed after all drawing by *.  If *@ is used from several
	      blobs, the further order of drawing is  not  specified.	It  is
	      guaranteed,  however,  that  at any given time this order is the
	      same for all positions.  (See section  VARIABLES	AND  CONSTANTS
	      for more details about @.)

       @(position)*
	      Like *, but draws the icon at some other position.  This drawing
	      is performed before all drawing by *.  If @* is used  from  sev‐
	      eral  blobs,  the further order of drawing is not specified.  It
	      is guaranteed, however, that at any given time this order is the
	      same  for	 all  positions.  (See section VARIABLES AND CONSTANTS
	      for more details about @.)

       if expr if-arrow if-code ;
       if expr if-arrow if-code else [else-arrow] else-code ;
	      The arrows can be either "->" or "=>".  If you  use  "->"
	      arrows,  it  does	 exactly what you would expect.	 If the
	      if-arrow	is "=>", then once the	expression  gets  true,
	      the if-code will be executed every subsequent time (with‐
	      out testing the condition), as long as it is "busy".  For
	      more details see section BUSIENESS.  If the else-arrow is
	      "=>", then once the expression gets false, the  else-code
	      will  be	executed every subsequent time as long as it is
	      busy.  The else-arrow may only be	 omitted,  if  the  if-
	      arrow  is	 "->".	Then the else-arrow also is "->".  (But
	      this might change in the future.)

       switch {
	 expr1 arrow1 code1 ;
	 expr2 arrow2 code2 ;
	 ...
       }      The arrows can be either "->" or "=>".  Does the same as:

		if expr1 arrow1 code1
		else => if expr2 arrow2 code2
		...

	      The last expr may be omitted.  This is equivalent to set‐
	      ting it to true.

       bonus(expr)
	      The player gets expr bonus points.

       message(String)
	      The  string is displayed (blinking) on the screen.  To be
	      used together with bonus(...).  Example:

		bonus(50);
		message("You get 50 bonus points");

       explode
	      Makes the blob explode.  For the next 8 steps or so,  the
	      blob  is	still  what it was before, but the explosion is
	      drawn over the graphics.	After that, it's changed  to  a
	      nothing-blob.

       lose   The players immediately lose the level.

       sound(Filename)
	      Plays the given sound file.

       You can also omit the code completely.  Then, of course, it does
       not do anything.	 This can be useful as part of ,-sequences.

       There's a shortcut for drawing: You may omit the ";"  between  a
       number, a letter and the "*".

EXPRESSIONS
       The  only  data type in cual is int.  Bools are represented by 0
       and 1, like in C.  (And any number other than 0	is  interpreted
       as true, if a boolean is expected.)

       Of course, variables, constants and numbers are expressions, and
       you can use parentheses.	  There	 are  the  following  operators
       (listed here in order of increasing precedence):

	      ||     Boolean or

	      &&     Boolean and

	      ==, !=, <, >, <=, >=
		     Comparison

	      ==..   A special comparison

	      !	     Boolean not

	      +, -   Add, substract

	      :	     Special operator

	      *, /, %
		     Multiply, divide, modulo

	      &, |, .+, .-
		     Bitwise  and, bitwise or, setting of bits (same as
		     bitwise or), unsetting of bits

	      -	     Unary minus

	      .	     Testing of bits (a.b is the same as a&b != 0)

       / and % work  mathematically  correct  and  do  not  make  funny
       changes	when  the sign of the numerator changes.  More specifi‐
       cally, if b is positive, then a/b is the largest integer n  such
       that  n*b<=a.  If b is negative, then a/b is the largest integer
       n such that n*b>=a.  In both cases a%b is such that  (a/b)*b+a%b
       = a.  Examples:

       13/5=2	    13%5=3
       -13/5=-3	    -13%5=2
       13/-5=-3	    13%-5=-2
       -13/-5=2	    -13%-5=-3

       The following are the special operators:

       expr1 == expr2 .. expr3
	      Is  true, if expr1 lies between expr2 and expr3.	You may
	      also omit one of expr2 and expr3.	  (Then,  it  does  the
	      same  as	<=  resp.  >=.)	  The  precedence  implies that
	      x==y==2..3 is the same as	 x==(y==2..3)  and  is	neither
	      (x==y)==2..3  nor	 x==(y==2)..3.	Note that this operator
	      might change in the future. (I  plan  to	make  something
	      like "expr in set" in Pascal.)

       expr1 : expr2
	      Is true (that is, 1) with probability expr1/expr2

       neighbour_pattern
	      neighbour_pattern	 is  a sequence of six or eight charac‐
	      ters 0, 1 and ?.	It is true if the sequence fits to  the
	      neighbour	 sequence  of the blob.	 The neighbour sequence
	      is a string of "0"s and "1"s with a "1" for  each	 neigh‐
	      bour  of	the  same kind, starting above and going clock‐
	      wise.  This way, you get a string of "0"s and  "1"s  (six
	      or eight, depending on wether this level is in hex mode).

	      Example: 1???0??? is true iff the blob above this blob is
	      of the same kind and the blob below it  is  of  different
	      kind.

	      For an empty blob the semantics is slightly different: If
	      in some direction there  is  no  neighbour,  because  the
	      field  ends there, the entry in the neighbour sequence is
	      1 nevertheless.  So for an empty blob 1???0???  is  true,
	      iff  the	blob above this blob does not exist or is empty
	      as well, and the blob below this blob exists and	is  not
	      empty.

	      If  some blob changes its kind during a step, the expres‐
	      sion will still test the neighbours as they were	at  the
	      beginning	 of  the  step.	 (See the section VARIABLES AND
	      CONSTANTS for details.)

       The following functions exist:

       rnd(expr)
	      Returns a random value between 0 and expr-1

       gcd(expr1, expr2)
	      Returns the greatest common divisor of expr1 and expr2

VARIABLES AND CONSTANTS
       The following kinds of variables and constants exist:

       —  User defined variables (see section  CUAL  DEFINITIONS).   At
	  the  start  of the level (or at the creation of the blob) the
	  value is the default value you provided.  If you supplied the
	  default  with	 : reapply, whenever a blob's kind changes, the
	  value of the variable is also set to the default of  the  new
	  kind.	  There	 is  a	subtlety:  This only happens if the new
	  value of kind is in fact different from the old one.

       —  System variables.  These variables  are  always  defined  and
	  have	special	 meanings, e.g. file and pos.  Some of them are
	  read-only.

       —  User defined constants.  These are defined in	 the  main  .ld
	  part, not in cual (not inside << >>).

       —  System  constants.   Some of them depend on properties of the
	  level, some are really constant.

       Of each variable, there's one instance in each blob.   Normally,
       you access the instance in your own blob, but with the following
       syntax, you can access variables of other blops:

	 varname@@(x, y; side)
	 varname@@(x; side)
	 varname@@(; side)
	 varname@(dx, dy; side)
	 varname@(dx; side)
	 varname@()

       If x and y are given, these are absolute coordinates in the grid
       of  blops,  that	 is  the  variable  is taken from the blob with
       loc_x=x and loc_y=y (see under The system variables).  If only x
       is  given,  it specifies one of the two blobs that are currently
       falling.	 If there is only one such blob left, because the other
       one  got stuck on some tower, the remaining blob's coordinate is
       0.  Otherwise one of the two has coordinate 0, the other 1.

       In the @ variants, the coordinates are relative to  the	current
       blob.  The variant @@(; side) refers to the semiglobal blob, the
       variant @() to the global blob (See section  THE	 GLOBAL	 BLOB).
       The  extra part ; side is optional and specifies the side of the
       game.  This is only meaningful in two-player  mode.   side  =  <
       specifies  the  left player, side = > the right player, side = =
       the player to which the current blob pertains, and side = !  the
       other  player.  @() and @@() can also be given as @ respectively
       @@.

       This can be done for both, reading and  writing	variables.   It
       also works for system variables (but not for constants).

       In  hex	mode levels, for odd dx, dy should be a "half integer",
       that is a number ending in ".5".	 This is the only place in Cual
       where  non-integers  appear.  Especially, ".5" is not allowed in
       composite expressions.  Therefore, also	integer	 dy  is	 always
       allowed.	 If a half-integer is expected and an integer is given,
       it is assumed to be rounded to above, that is 5 then  represents
       4.5 and -5 represents -5.5.

       Caution: With mirror=1 the absolute and the relative coordinates
       use different coordinate systems.  Handle with extreme care.

       Accessing foreign variables is not as easy as it might  look  at
       first  glance;  it  might  easily  introduce a dependence of the
       internal order of execution of the blob codes.  For this reason,

       —  reading variables with @ or @@ always returns	 the  value  of
	  the  variable	 it  had  at the beginning of the current step,
	  that is, before any of the blob codes has been executed.

       —  when writing variables with @ or @@, the write operation will
	  only	be executed at the end of the current step.  (The write
	  operations are stored in a kind of queue.)

       This is also true if a blob  accesses  its  own	variables  with
       @(0,0).

       The  operators +=, -=, etc.  are also performed in the future if
       the left hand side is an @-variable.  (To be more  precice,  the
       right hand side is calculated instantanousely.)

       For illustration, look at the following six statements:

       1)   X += 1
       2)   X@(0, 0) += 1
       3)   X = X + 1
       4)   X = X@(0, 0) + 1
       5)   X@(0, 0) = X + 1
       6)   X@(0, 0) = X@(0, 0) + 1

       Only  1)	 and  3)  do  the  same;  they simply increment X by 1.
       Statement 4) sets X to one more than it was at the beginning  of
       the  step.   Statements 2), 5) and 6) cause the value of X to be
       changed in the future (after the current step): X is set to  one
       more than:

       2)     the  value  of  X	 just  before the change (that is, X is
	      incremented in the future),

       5)     the current value of X,

       6)     the value of X at the beginning of the step.

   Some more details
       —  Whenever you try to access a variable	 at  a	location  which
	  doesn't  exist,  you	will get the default value.  If default
	  values depend on the kind, the default pertaining to the blob
	  executing the code is used.  This may change in the future.

       —  Changing  a  variable	 which	doesn't exist does nothing (and
	  does not result in an error).

       [Add explanation of time slices; roughly:
	  @-access of variables in reality don't access	 the  value  at
	  the  beginning/end  of  the game step, but of the time slice.
	  The call of the main procedure of all blobs  happens	in  the
	  same	time  slice,  but  each other kind of event has its own
	  time slice.]

   The system variables
       file   Specifies the file number from which  to	take  the  icon
	      that is drawn by "*".  This variable is reset to 0 before
	      the drawing procedure is executed.

       pos    Specifies the position in the file of the	 icon  that  is
	      drawn  by	 "*".	This  variable is reset to 0 before the
	      drawing procedure is executed.

       kind   The kind of the blob.  There are constants for the possi‐
	      ble values of this variable.  If you change the kind, you
	      should be aware of three things:

	      —	 Expressions like "001???01" test the neighbour pattern
		 at  the  beginning of the current step.  So the change
		 of the variable kind will not be reflected.

	      —	 In the current step, the program to draw the blob  has
		 already  been	invoked	 (it  might even be the program
		 which changed this variable); so  in  this  step,  the
		 blob  will  still look like one of the old kind.  How‐
		 ever, if things are drawn  after  the	kind  has  been
		 changed, icons from the new kind are taken.

	      —	 Defaults  of  the  new	 kind  that are declared with :
		 reapply are applied.  This happens at	the  same  time
		 that kind changed, but only if the new kind is differ‐
		 ent from the old one.

       version
	      Is assigned a hopefully distinctive value at  the	 blob's
	      creation.	 See versions in section KIND DATA for details.

       qu     Tells  "*" which part of the icon to draw.  It's possible
	      to draw the whole icon, or only one of its quarters.   If
	      a	 quarter  is drawn, you may specify independently which
	      of the quarters to take and at which position to draw it.
	      Use the constants (see below).  This variable is reset to
	      "draw all" before the drawing procedure is executed.

       out1, out2
	      Set these Variables for debug output.  The values will be
	      printed  on top of the blob.  These variable are reset to
	      "output nothing" before the  drawing  procedure  is  exe‐
	      cuted.   (In  fact,  "output  nothing" is one special big
	      value.)

       weight When calculate_size is set in  behaviour,	 size  will  be
	      regularly	 updated  to the sum of weight in the connected
	      component.  The default is 1.

       inhibit
	      Set this variable to a sum of the constants DIR_...; this
	      will  inhibit  that  this	 blob  connects	 into the given
	      directions.  This is not for the	graphics  but  for  the
	      calculation  of  the  connected components and the explo‐
	      sions.

       behaviour
	      This is a bit field.  Refer to The  Constants  below  for
	      the  meaningful  of  its	bits.	The  default  is calcu‐
	      late_size+explodes_on_size     for     normal	 blobs,
	      explodes_on_explosion+explodes_on_chainreaction  for grey
	      blobs,   floats	for   the   empty   blob   and	  goal‐
	      blob+explodes_on_explosion+explodes_on_chainreaction   or
	      goalblob+explodes_on_chainreaction (depending on	whether
	      chaingrass is set) for grass blobs.

       falling_speed, falling_fast_speed
	      These  variables	are  only used in the semiglobal blobs.
	      They define the vertical speed  of  the  steered	falling
	      blobs.   The  unit is pixels per game step.  The defaults
	      are 6 and 32.

   The system read-only variables
       time   The number of time steps since the level was started.

       turn   Is 1 resp. 2 if the blob is falling and just being turned
	      by  the  user  and  0 otherwise.	(1 in the first turning
	      step, 2 in the second one.)  Be aware that  if  the  user
	      presses  the  turn  key fast several times, some of these
	      steps may be omitted.  (Use the turn event if you want to
	      be  sure	that a program block is executed once for every
	      turn.)

       connect
	      Contains internal data.  Will be removed.	 Probably.

       size   The size of the component of the	blob.	(That  is,  how
	      many blobs are connected.)

       basekind
	      The  value  of the constant generated for the name of the
	      kind of the blop.	 Example:

		pics = orange, pear, apple * 3, banana, apple

	      Here, all four  kinds  apple  have  the  same  value  for
	      basekind, and this value is apple.

       loc_x, loc_y
	      The  absolute  coordinates of the blob.  (0,0) = top left
	      corner

       loc_xx, loc_yy
	      The absolute coordinates of the blob in pixels.  This  is
	      not  always  the	same as loc_x*32 and loc_y*32, particu‐
	      larly for the steered falling blobs.

       loc_p  The player of the blob (1 or 2)

       falling
	      true, if the blob is falling or it  is  a	 preview  of  a
	      falling  blob.   (Falling	 in the sense of steered by the
	      player.  Grey blobs are not falling in that sense.)

       falling_fast
	      True, if the blob is falling  fast,  that	 is,  the  user
	      pressed the down key.

       informational
	      True, if the blob is one of the info-blobs at the side of
	      the game area.  In this sense, the previews of the  fall‐
	      ing blobs also count as info-blobs.

       players
	      The number of players.

       exploding
	      When the blob is exploding, the position in the explosion
	      animation (1 to 8); 0 else.

	      Currently, there is one exception: if the	 explosion  has
	      been  triggered  by  the	explode command, then exploding
	      will have value 1 only after the current game step  [more
	      precisely:  time	slice; fix that].  Reason: when reading
	      exploding@(x,y), we maybe don't know yet that  the  other
	      blob calls explode.

   The Constants:
       Constants for behaviour:

       goalblob
	      Set goalblob if this blob should act like grass: You will
	      have to get rid of it to win the level  and  making  this
	      blob explode will give more points.

       calculate_size
	      When  this  bit is set, size will be regularly updated to
	      the sum of weight in the connected component.

       explodes_on_size
	      When this bit is set,  a	connected  component  explodes,
	      when it has size>=numexplode.

       explodes_on_explosion, explodes_on_chainreaction
	      When  these  bits	 are set, the blob explodes whenever an
	      explosion that was triggered by explodes_on_size	happens
	      in  its  neighbourhood.  explodes_on_chainreaction refers
	      to those triggering explosions that  are	the  second  or
	      later  part  of  a chain reaction.  explodes_on_explosion
	      refers to the other ones.

       floats When this bit is set, the blob keeps its	vertical  posi‐
	      tion  even if there is an empty blob below.  This bit has
	      no effect on the steered falling blobs.

       Constants for kind:

       <name of kind of blob>
	      For each kind of blob, there's one constant with the name
	      of  that	kind. Use it to check if a blob is of that kind
	      using kind@(x,y) == aKind or to change to that kind using
	      kind  =  aKind.	See kind under The system variables for
	      the side-effects of setting kind.

	      Sometimes it is necessary to perform arithmetic on kinds,
	      for  example  when several have been declared using the *
	      multiplier.  The values of the constants	are  successive
	      in  the  order,  in  which  the kinds have been declared.
	      When a name is used several times, the first use	defines
	      the value.  Example:

		startpic = apple, orange
		pics = orange, pear, apple * 3, banana
		greypic = pineapple

	      This  initializes 2 kinds with the defaults for startpic,
	      6 kinds with the defaults for pics, and 1 kind  with  the
	      defaults	for  greypic.  The value of the constant orange
	      is 1 more than that of apple, pear is 2 more than orange,
	      banana  is  4 more than pear and pineapple is 1 more than
	      banana.  We do not specify  what	these  values  actually
	      are.

	      This  constant also exists for the empty kind, if one has
	      been declared using emptypic.  In this case  the	value's
	      relation to the other values is not specified at all.

       global, semiglobal
	      Denote  the  kind of the global, respectively semiglobal,
	      blob.

       nothing
	      Is the same as the constant for the empty kind.  Is  pro‐
	      vided,  because  sometimes, you don't have an empty kind,
	      but you still need to test if a blob is empty.

       outside
	      The value of kind if the coordinates are outside	of  the
	      game board.

       Constants for neighbours:

       neighbours_rect
	      A	 blob  connects up, down, left, and right.  This is the
	      default.

       neighbours_horizontal
	      A blob connects left and right.

       neighbours_vertical
	      A blob connects up and down.

       neighbours_diagonal
	      A blob connects diagonally.

       neighbours_hex6
	      When used in the level-wide  neighbours,	this  sets  hex
	      mode.   A	 blob  connects	 up,  down,  left with a slight
	      upwards shift, left with a slight downwards shift,  right
	      with  a  slight  upwards	shift,	and right with a slight
	      downwards shift.

       neighbours_hex4
	      When used in the level-wide  neighbours,	this  sets  hex
	      mode.   A blob connects left with a slight upwards shift,
	      left with a slight downwards shift, right with  a	 slight
	      upwards shift, and right with a slight downwards shift.

       neighbours_knight
	      A blob connects in knight moves (Two forward and then one
	      sideways.	 Forward is one of up,	down,  left  or	 right.
	      Sideways is perpendicular to forward.  This makes a total
	      of eight directions.).

       neighbours_eight
	      Combines neighbours_rect with neighbours_diagonal.

       neighbours_3D
	      A more obscure mode created especially for  3d.ld.   When
	      used in the level-wide neighbours, this sets hex mode.  A
	      blob connects up, down, two (but not one)	 to  the  left,
	      and  two	to the right.  In even columns it also connects
	      right with a slight upwards shift.   In  odd  columns  it
	      also connects left with a slight downwards shift.

       neighbours_none
	      A blob does not connect at all.

       Constants for qu:

       Q_ALL  Value for qu, which means "draw the complete picture".

       Q_TL, Q_TR, Q_BL, Q_BR
	      Values  for  qu.	 "TL" means draw top-left quarter, etc.
	      (See the "*" command in the Code section.)

       Q_SRC_DST
	      SRC and DST may be TL, TR, BL, BR.  Take quarter SRC  and
	      draw it at position DST.

       Miscellanious constants:

       DIR_XX To  be used with the variable inhibit to prevent the blob
	      connecting in the given directions.  XX can be U, D, L, R
	      (horizontal  and	vertical);  UL,	 UR, DL, DR (diagonal);
	      UUL, UUR, DDL, DDR, LLU, LLD, RRU,  RRD  (knight);  F,  B
	      (3d)

VERSIONING
       Sometimes it is necessary to define a level slightly differently
       for different purposes.	For example you might need to  decrease
       numexplode   for	  the	two-player   version  lest  it	becomes
       unplayable.  The difficulty settings from cuyo's main menu  pro‐
       vide another example.

       This  is	 done  by  qualifiing a definition with the versions it
       should apply to.	 It is best explained by an example:

	 numexplode = 8
	 numexplode[2] = 6
	 numexplode[1,hard] = 10

       This specifies that normally numexplode should be  8.   In  two-
       player  mode  it should be 6.  In one-player hard mode it should
       be 10.  Here the specifiers 2 for two-player mode,  1  for  one-
       player  mode  and  hard for hard mode are used.	Along with easy
       for easy mode these are all predefined specifiers  intended  for
       levels.	 Additionally  (and  for  internal purposes), there are
       specifiers for the level tracks: main, all, game, extreme, nofx,
       weird, and contrib.

       Furthermore,  you  can  make up and use your own specifiers.  In
       order for them to take effect, though, you  have	 to  give  cuyo
       additional  information about the current version.  This is done
       on the command line using the --version option.	For example

	 cuyo --version=hard,geek

       Specifies both hard version (you can change that	 in  the  menu)
       and version "geek", which is not predefined.

       There are several constraints to be observed:

       —  All  versions	 of  a definition must be made before the first
	  use of the thing defined.  As sometimes  it  is  not	obvious
	  where	 the defined thing is used (for example startpic uses a
	  previous greypic by assigning successive numbers  to	kinds),
	  it is best to group all these versions into one block.

       —  A  given  version also applies to every more specialized ver‐
	  sion, for which no definition is given.  In the  above  exam‐
	  ple,	numexplode  is	set to 6 in two-player hard mode and in
	  two-player easy mode as well.

	  All resulting conflicts must be resolved.   For  example,  if
	  you  make  a	definition for [2] and one for [hard], you must
	  also make a definition for [2,hard]  (or,  equivalently,  for
	  [hard,2]),  because  otherwise it would be ambiguous which of
	  the two former should apply in two-player hard mode.

       —  Cuyo knows that easy and hard	 exclude  each	other.	 Conse‐
	  quently, it is unnecessary (and indeed prohibited) to give an
	  [easy,hard] definition, even if both [easy]  and  [hard]  are
	  given.  The same holds for 1 and 2, and for level tracks.

       —  Furthermore, cuyo knows that 1 and 2 are exhaustive: There is
	  no mode which is neither single-player nor two-player.   (The
	  human-versus-AI  mode	 counts as two-player as far as cual is
	  concerned.)  Therefore, if there are definitions for both, it
	  is  unnecessary, (and again illegal) also to define a version
	  without any of both.	For example, if [1,de] and  [2,de]  are
	  given,  [de]	must  be  omitted.  Alternatively, you could of
	  course give [1,de] and [de] or [de] and  [de,2].   The  level
	  track specifiers are exhaustive as well.

BUSIENESS
       (No, not Business ;-)

       Busieness  is  a	 concept  to make it easier to implement simple
       animated sequences which are triggered by certain events.   Each
       code fragment has an internal state which tells if it is busy.

       —  Normal statements like assignments are never busy.

       —  A  chain  of commands separated by "," is busy as long as not
	  all of the commands have been executed.

       —  code1 ; code2 is busy as long as at least one	 of  code1  and
	  code2 are busy.

       Here's an example of how to use busieness for an animation which
       appears at random intervals:

	 switch {
	   1:100 => {B*, C*, D*, E*};
	   -> A*;
	 };

       This code fragment normally draws the icon at  position	A  (0).
       But  in	each  step,  with  a probability of 1/100, an animation
       sequence consisting of icons B, C, D and E is started.	With  a
       normal arrow ("->") after the "1:100", after the step in which B
       has been drawn, the probability would be 99/100 that A is  drawn
       again.	But  with  the double arrow, the switch statement won't
       switch back to A until the animation has terminated.

       (Btw: It doesn't matter if there's a "->" or a "=>"  before  the
       "A*"; A* isn't busy anyway.)

THE GLOBAL BLOB
       Apart from the normal blobs which you can see on screen, there's
       one global blob (for the whole game, not one for	 each  player),
       which, well, isn't really a blob, but behaves a bit like it.  It
       has its own set of variables, and it can have a program which is
       run  once  every	 step.	 To  define  such a global program, use
       global=code.  However, the global variables do exist even if you
       don't  define  global code.  See section VARIABLES AND CONSTANTS
       on how to access them.  Note that the global blob is always exe‐
       cuted before any of the normal blobs.

       There  are also semiglobal blobs.  There is one for each player.
       These are programmed with semiglobal=code.

EVENT HANDLERS
       The following events exist:

       init   Is called only once, when the blob gets into  life,  just
	      before the first time its main drawing routine is called.

       turn   Is called for falling blobs each time they are rotated.

       land   Is  called  when	the  steered  blob lands (just after it
	      landed).

       changeside
	      Is called when a blob moves from one player to the other,
	      just after the blob has arrived at the new player.

       connect
	      Is called when the connection of blobs is recalculated.

       row_up Is  called  when	a player got a row from the other side,
	      after everything is finished and just after the loc_y  of
	      all  blobs  has  been decreased by 1.  Is only called for
	      the semiglobal blob, though.

       row_down
	      Is called when a player gives a row to  the  other  side,
	      before anything visible happens, but just after the loc_y
	      of all blobs has been increased by 1.  Is only called for
	      the semiglobal blob, though.

       keyleft, keyright, keyturn, keyfall
	      Are  called when the player presses the left, right, turn
	      or fall key.  Are only called  for  the  steered	falling
	      blobs  and  the  semiglobal blob, though.	 (Note that, in
	      contrast to turn, keyturn is called even if  the	steered
	      blob cannot be rotated due to some obstacles, and also if
	      there is no steered blob.)

THE LIFE OF A BLOB
       Normal blobs come into life at the beginning  of	 the  game,  or
       they  fall  into	 life:	either as colored blobs, steered by the
       user, or as grey	 blobs.	  More	precisely,  the	 steered  blobs
       already	come into life when they appear as the preview.	 When a
       blob moves (by gravitiy or when	rows  go  from	one  player  to
       another), it takes its variables with it.  When a blob explodes,
       it does not stop existing.  Rather, it transforms into an  empty
       blob.   That's important for the variables: The empty blob still
       has all the variables set to the values they  had  before;  only
       its kind is different.  Empty blobs are everywhere where there's
       no other blob.  (However, the falling blobs steered by the  user
       are in some sense "above" everything else; there are empty blobs
       beneath them.)

       The life of empty blobs is different  from  the	one  of	 normal
       blobs.	Empty blobs are not affected by gravity, and they often
       start or stop existing.	For example, when a single grey blob is
       falling	down,  the  empty blob below it stops existing when the
       grey blob arrives and a new empty blob starts existing when  the
       grey  blob moves on.  There is only one situation in which empty
       blobs move: When a row moves from one player to the  other,  and
       everything moves up resp. down, the empty blobs move, too.

STARTDIST
       The format of the startdist field is rather complicated.	 On the
       plus side, this means that many things can be done  with	 little
       effort.	 We  first describe the single-character format, which,
       at the time of this writing, has sufficed for all needs.	  After
       that, we describe the general format as an extension.

       Every  line  of	the startdist describes one row of blobs in the
       level's initial state.  The lines are aligned to the bottom  and
       the  topmost lines come first (normal reading order).  Each line
       must contain exactly 10 or exactly  20  characters,  except  the
       last  which  is	special.   In  a line of length 20 the first 10
       characters describe the left player, the	 second	 10  characters
       describe	 the  right player.  A line of length 10 describes both
       players.	 Hence, each character describes one blob.  The	 seman‐
       tics are:

       .      An empty blop.

       +, -, *
	      A	 blop chosen at random according to colourprob, respec‐
	      tively greyprob, respectively  goalprob.	 The  value  of
	      nogreyprob has no influence.

       0..9, A..Z, a..z
	      These  characters denote a specific kind.	 If the charac‐
	      ter matches the distkey of some kinds, the first of these
	      is  chosen.  More generally, these characters are ordered
	      such that "9" comes before "A" and "Z" comes before  "a".
	      In  this	order, the maximal distkey, which does not come
	      after the character, specifies the blob's kind.  The dif‐
	      ference between the character and the distkey then speci‐
	      fies the blob's version.

	      Example 1: In  the  special  case,  where	 the  character
	      exactly matches a distkey, version is set to 0.

	      Example  2:  Suppose  kind  apple has distkey = "A", kind
	      orange has distkey = "O" and no further  distkeys	 exist.
	      Then  the	 character "C" denotes an apple with version=2,
	      the character "N" denotes an apple with  version=13,  the
	      character "O" denotes an orange with version=0, the char‐
	      acter "S" denotes an orange with version=4, the character
	      "a"  denotes an orange with version=12, and the character
	      "8" does not denote anything (and hence is illegal).

       %      An info blop with the version set according to the level-
	      wide neighbours.

       &      An info blop with the version set according to the level-
	      wide chaingrass.

       The last line may have length 4, 8, 10, or 20.  If it has length
       10  or  20,  it	is  just  a normal line as above.  Otherwise it
       describes the informational blops next to the field.  In case of
       length  4,  the first entry describes the blop which depicts the
       number of greys.	 The second  entry  describes  the  blop  which
       depicts	the  number  of grass blops.  The third entry describes
       the blop which depicts connection information.  The fourth entry
       describes  the  blop  whoch  depicts chaingrass information.  In
       case of length 8, the above holds  for  the  left  player.   The
       remaining 4 entries then describe the same for the right player,
       but in reversed order.  The default is  "-*%&&%*-"  (or	equiva‐
       lently "-*%&").

       As  seen above, startdist can reference 62 kind/version combina‐
       tions directly (and more at random).  Because this might at some
       time not be enough, the multichar extension has been introduced.
       In this case, each blob is described by more than one character.
       However,	 the number of characters per blob must be the same for
       all keys.  Hence, the lengths of startdist lines	 then  must  be
       this  number  multiplied	 by  10 or by 20.  Every multicharacter
       combination starting with ".", "+", "-", or "*"	is  treated  as
       the  corresponding  character  in  single-character format.  All
       other character combinations are treated as numbers in  base  62
       representation.	 Here, "A" to "Z" are digits with decimal value
       10 to 35, and "a" to "z" are digits with decimal value 36 to 61.
       Leading	spaces are allowed instead of zeroes (however, the all-
       space string is forbidden).  The maximal	 distkey  which	 (as  a
       number) is not larger than the number given in startdist, speci‐
       fies the blob's kind.  The difference between the startdist num‐
       ber  and	 the distkey then specifies the blob's version.	 In the
       case of multichar distkeys, the default for  distkeys  of  kinds
       declared by startpic= is 10 in decimal.

       For blops whose kinds are chosen at random (i.e. characters "+",
       "-", "*" in single-character startdists),  cuyo	tries  to  make
       these  as  different  as	 possible.   That  means,  by a certain
       heuristic, cuyo minimizes the number of	neighbouring  blobs  of
       the  same kind.	"Neighbouring", of course, refers to the neigh‐
       bours entry.  inhibit and the calculate_size  bit  of  behaviour
       have  no effect (these are mutable during the lifetime of blobs,
       while at the time of startdist processing,  no  blob's  lifetime
       has started yet).  So the only way to influence the unneighbour‐
       ing (if you really wish to do  so),  is	by  setting  neighbours
       appropriately.	(Of  course, this possibility is even more lim‐
       ited, when you intend to set the calculate_size bit  during  the
       blob's lifetime.)

WHERE DO I PUT THE CUAL CODE?
       Cual  procedures	 and variables can be defined in different sec‐
       tions of the .ld files:

       —  Outside of everything; that code  is	accessible  from  every
	  level coming after that definition.

       —  In the section of a level.

       —  In the section of a kind.

       This basically does what you expect.  However, there's one thing
       you might want to know: Even if you define a variable  inside  a
       kind,  every  blob  in  that level will have that variable.  The
       only effect of defining the variable in the section of a kind is
       that this kind is the only one which can access it.

AMPERSAND-CALL
       To  explain a bit what calling a procecure with an & means, here
       two examples:

       Example 1:
       <<
       myblob = {
	 ...
	 switch {
	   myvar -> { 0A*; 1; A,B,C,D; *; 2A*};
		 -> { 0B*; 1; A,B,C,D; *; 2B*};
	 };
       };
       >>

       Example 2:
       <<
       anim = {1; A,B,C,D; *};

       myblob = {
	 ...
	 switch {
	   myvar -> { 0A*; &anim; 2A*};
		 -> { 0B*; &anim; 2B*};
	 };
       };
       >>

       The difference between these examples is what happens when myvar
       changes.	  In example 1, the animation "A, B, C, D" will restart
       at the beginning	 (because  the	two  animations	 are  different
       ones); in example 2, the "same" animation is used in both cases,
       so the animation will simply continue.  (Removing the ampersands
       from example 2 will turn the behaviour to the one of example 1.)

THE AI UTILITY FUNCTION
       When  deciding  how  to	place the steered falling blobs, the AI
       player tries to maximize a certain utility function.  Its  value
       is  the	sum  of	 the values for both steered falling blobs plus
       aiu_monochromic_vertical in case both blobs have the same  color
       and  they get placed vertically.	 The value for a single blob is
       the sum of the following:

       —  For each new neighbour of blob, the neighbour utility.

       —  aiu_two_above, if the blob is two above a blob of same kind.

       —  aiu_height*20/(the blob's y coordinate).

       The neighbour utility for a single new blob and a single one  of
       its new neighbours is the sum of the following:

       —  aiu_color, if the neighbour has the same kind as the blob.

       —  aiu_grass, if the neighbour fulfills behaviour.goalblob.

       —  aiu_grey,	if     the     neighbour     fulfills	 behav‐
	  iour.explodes_on_explosion.

SEE ALSO
       cuyo(6)

BUGS
       Probably a lot.	The following are just a few known ones:

       There are several problems with busieness and that stuff.  There
       are several situations in which Cual doesn't behave in the way I
       would like, and in other situations I don't know how Cual should
       behave.

				  2014-10-25			       CUAL(6)
[top]

List of man pages available for DragonFly

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net