(********************************************************************)
(*                                                                  *)
(*  dna_base.s7i  Bacterial dna fight programming game interface    *)
(*  Copyright (C) 1985, 1986, 2005  Thomas Mertes                   *)
(*  Copyright (C) 1985, 1986,       Markus Stumptner                *)
(*  Copyright (C) 1985, 1986, 1991  Johannes Gritsch                *)
(*                                                                  *)
(*  This program is free software; you can redistribute it and/or   *)
(*  modify it under the terms of the GNU General Public License as  *)
(*  published by the Free Software Foundation; either version 2 of  *)
(*  the License, or (at your option) any later version.             *)
(*                                                                  *)
(*  This program is distributed in the hope that it will be useful, *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of  *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *)
(*  GNU General Public License for more details.                    *)
(*                                                                  *)
(*  You should have received a copy of the GNU General Public       *)
(*  License along with this program; if not, write to the           *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


const type: bactColor is new enum
    EDGE, CLEAR, WHITE, VIOLET, INDIGO, BLUE, CYAN,
    GREEN, YELLOW, AMBER, ORANGE, RED, SCARLET, TAN,
    LILIAC, PINK
  end enum;

const func string: str (in bactColor: aColor) is
  return [] (
    "Edge", "Clear", "White", "Violet", "Indigo", "Blue", "Cyan",
    "Green", "Yellow", "Amber", "Orange", "Red", "Scarlet", "Tan",
    "Lilac", "Pink"
  )[succ(ord(aColor))];

enable_output(bactColor);

const bactColor: FIRSTCOL is WHITE;
const bactColor: LASTCOL  is PINK;

const type: direction is new enum
    HERE, NORTH, SOUTH, WEST, EAST, NW, NE, SW, SE
  end enum;

const func string: str (in direction: aDirection) is
  return [] (
    "HERE", "NORTH", "SOUTH", "WEST", "EAST", "NW", "NE", "SW", "SE"
  )[succ(ord(aDirection))];

enable_output(direction);

const type: colorSet is set of bactColor;
const type: directSet is set of direction;
const type: directArr is array [direction] direction;
const type: power is integer; (* 0 .. ALL *)
const type: lifeSpan is subtype integer; (* 0 .. MAXLIFESPAN *)
const type: percent is subtype integer; (* 0 .. 100 *)

const power: ALL is 1000000;
const lifeSpan: MAXLIFESPAN is 3;

const array [direction] direction: right is [direction] (
    HERE, NE, SW, NW, SE, NORTH, EAST, WEST, SOUTH);
const array [direction] direction: left is [direction] (
    HERE, NW, SE, SW, NE, WEST, NORTH, SOUTH, EAST);

const colorSet: ALL_COLORS is {WHITE, VIOLET, INDIGO, BLUE, CYAN,
    GREEN, YELLOW, AMBER, ORANGE, RED, SCARLET, TAN, LILIAC, PINK};
const directSet: MAIN_DIRECTIONS is {NORTH, SOUTH, WEST, EAST};
const directSet: DIAGONAL_DIRECTIONS is {NW, NE, SW, SE};

const integer: defaultVal is 10; # Default value for initSize, foodReserve and shrinkage.

var power: initSize is defaultVal;    # Initial size of the bacterials.
var power: foodReserve is defaultVal; # Initial amount of food at all fields.
var percent: shrinkage is defaultVal; # Percentage by which bacterials shrink in every move.


(**
 *  Returns the content (color of a bacterium, CLEAR or EDGE) of a cell.
 *)
const func bactColor: view (in direction: direct) is forward;


(**
 *  Returns the strength/size of a bacterium or 0 for CLEAR and EDGE fields.
 *)
const func power: strength (in direction: direct) is forward;


(**
 *  Returns the amount of food at a field or 0 for EDGE fields.
 *)
const func power: food (in direction: direct) is forward;


(**
 *  Moves a bacterium and it eats the given quantity of food.
 *  If the direction is not HERE the destination field must be CLEAR.
 *)
const proc: eat (in direction: direct, in power: quantity) is forward;


(**
 *  Moves a bacterium and it kills/eats another bacterium at the new position.
 *  The other bacterium must be of the same size or smaller.
 *)
const proc: kill (in direction: direct) is forward;


(**
 *  Splits a bacterium in two (one moves in the given direction).
 *  The two bacteria eat the given amounts of food.
 *  The direction must not be HERE and the destination field must be CLEAR.
 *)
const proc: split (in direction: direct, in power: quantity1, in power: quantity2) is forward;


(**
 *  Computes the size by which a bacterium with the given
 *  size would shrink (when the bacterium does nothing).
 *)
const func power: shrinkSize (in power: size) is forward;


(**
 *  Computes how many moves a bacterium survives a hunger situation.
 *)
const func lifeSpan: hunger is forward;


(**
 *  Computes the new size of a bacterium. As input it has
 *  the current size, the food it plans to ingest and the current hunger.
 *)
const func power: nextSize (in power: ownsize, in power: foodmass, in lifeSpan: ownHunger) is forward;


(**
 *  Returns a random direction from the given dirset.
 *  When the dirset is empty it returns HERE.
 *)
const func direction: ranDir (in directSet: dirset) is forward;