home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CTECHAPP.ZIP / SIMULATN.ZIP / GRAZER.CPP < prev    next >
C/C++ Source or Header  |  1990-02-15  |  6KB  |  270 lines

  1. //  Header:     Grazer
  2. //  Version:    2.00
  3. //
  4. //  Language:   C++ 2.0
  5. //  Environ:    MS-DOS, Zortech C++ v2.0x
  6. //
  7. //  Purpose:    SIMECO Grazer class definition
  8. //
  9. //  Written by: Scott Robert Ladd
  10.  
  11. // include class definition
  12. #include "Grazer.hpp"
  13.  
  14. // include C library headers
  15. extern "C"
  16.     {
  17.     #include "stdio.h"
  18.     #include "stdlib.h"
  19.     #include "graphvga.h"
  20.     }
  21.  
  22. // this macro returns a random number between 1 and n
  23. #define RandVal(n) ((rand() % n) + 1)
  24.  
  25. // initialize the static members of Grazer class
  26. int Grazer::Count       =    0;
  27. int Grazer::MaxEnergy   = 3000;
  28. int Grazer::MaxAge      =  300;
  29. int Grazer::MaxSense    =    3;
  30. int Grazer::ReproAge    =  100;
  31. int Grazer::RepEnergy   = 2000;
  32. int Grazer::FoodValue   =  150;
  33. int Grazer::NoMoveGenes =    8;
  34.  
  35. int Grazer::MoveTable[8][2] =
  36.     { {-3, -3}, { 0, -3}, { 3, -3},
  37.       {-3,  0},           { 3,  0},
  38.       {-3,  3}, { 0,  3}, { 3,  3} };
  39.  
  40. // globals defining area which grazers live in
  41. BitGrid * Grazer::FoodSupply = NULL;
  42.  
  43. int Grazer::MaxX = 0;
  44. int Grazer::MaxY = 0;
  45.  
  46. // basic constructor for a new creature
  47. Grazer::Grazer(int x, int y)
  48.     : Creature(15,1500,x,y)
  49.     {
  50.     for (int i = 0; i < NoMoveGenes; ++ i)
  51.         Movement[i] = 1;
  52.  
  53.     MoveCount = NoMoveGenes;
  54.  
  55.     Sense = 0;
  56.  
  57.     ++Count;
  58.  
  59.     Draw();
  60.     }
  61.  
  62. // copy constructor
  63. Grazer::Grazer(const Grazer & G)
  64.     : Creature(15,G.Energy,G.PosX,G.PosY)
  65.     {
  66.     for (int i = 0; i < NoMoveGenes; ++i)
  67.         Movement[i] = G.Movement[i];
  68.  
  69.     MoveCount = G.MoveCount;
  70.  
  71.     Sense = G.Sense;
  72.  
  73.     int choice = RandVal(10);
  74.  
  75.     switch (choice)
  76.         {
  77.         case 1: // modify movement genes
  78.         case 2:
  79.         case 3:
  80.             int move = RandVal(NoMoveGenes) - 1;
  81.  
  82.             if (1 == RandVal(2))
  83.                 {
  84.                 if (Movement[move] == 1)
  85.                     {
  86.                     ++Movement[move];
  87.                     ++MoveCount;
  88.                     }
  89.                 }
  90.             else
  91.                 {
  92.                 if (Movement[move] == 2)
  93.                     {
  94.                     --Movement[move];
  95.                     --MoveCount;
  96.                     }
  97.                 }
  98.             break;
  99.  
  100.         case 4: // modify sense value
  101.             if (1 == RandVal(2))
  102.                 {
  103.                 if (Sense < MaxSense)
  104.                     ++Sense;
  105.                 }
  106.             else
  107.                 {
  108.                 if (Sense > 0)
  109.                     --Sense;
  110.                 }
  111.         }
  112.  
  113.     ++Count;
  114.  
  115.     Draw();
  116.     }
  117.  
  118. // destructor
  119. Grazer::~Grazer()
  120.     {
  121.     if (CList.Delete(this))
  122.         {
  123.         printf("Error: Creature cannot be deleted from list\n");
  124.         exit(0);
  125.         }
  126.  
  127.     Erase();
  128.  
  129.     --Count;
  130.     }
  131.  
  132. // set food supply and area dimensions
  133. void Grazer::SetRegion(BitGrid * food, int xmax, int ymax)
  134.     {
  135.     FoodSupply = food;
  136.  
  137.     MaxX = xmax;
  138.     MaxY = ymax;
  139.     }
  140.  
  141. // ask grazer to do something
  142. int Grazer::Move()
  143.     {
  144.     ++Age;
  145.     ++AgeRep;
  146.  
  147.     if ((AgeRep >= ReproAge) && (Energy >= RepEnergy))
  148.         {
  149.         AgeRep = 0;
  150.  
  151.         Energy /= 2;
  152.  
  153.         Grazer * newG = new Grazer(*this);
  154.  
  155.         if (newG == NULL)
  156.             {
  157.             printf("Error! Grazer Repro\n");
  158.             exit(1);
  159.             }
  160.         }
  161.  
  162.     int i, x, y, newx, newy, m, weight, move;
  163.  
  164.     if (Sense > 0)
  165.         {
  166.         int move_value, j, ix, iy;
  167.  
  168.         int hi_value = -1;
  169.  
  170.         move = 0;
  171.  
  172.         for (i = 0; i < NoMoveGenes; ++i)
  173.             {
  174.             move_value = 0;
  175.  
  176.             x = PosX;
  177.             y = PosY;
  178.  
  179.             for (j = 0; j < Sense; ++j)
  180.                 {
  181.                 x += MoveTable[i][0];
  182.                 y += MoveTable[i][1];
  183.  
  184.                 if (x < 1) x = MaxX;
  185.                 if (x > MaxX) x = 1;
  186.                 if (y < 1) y = MaxY;
  187.                 if (y > MaxY) y = 1;
  188.  
  189.                 for (ix = x - 1; ix <= x + 1; ++ix)
  190.                     for (iy = y - 1; iy <= y + 1; ++iy)
  191.                         if (FoodSupply->IsSet(ix,iy))
  192.                             ++move_value;
  193.                 }
  194.  
  195.             if (move_value > hi_value)
  196.                 {
  197.                 hi_value = move_value;
  198.                 move = i;
  199.                 }
  200.             else
  201.                 if ((move_value == hi_value) && (Movement[i] >= Movement[move]))
  202.                     if ((Movement[i] > Movement[move]) || (RandVal(2) == 1))
  203.                         move = i;
  204.             }
  205.         }
  206.     else
  207.         {
  208.         weight = Movement[0];
  209.         m      = RandVal(MoveCount);
  210.  
  211.         move =  0;
  212.  
  213.         while (m > weight)
  214.             {
  215.             ++move;
  216.             weight += Movement[move];
  217.             }
  218.         }
  219.  
  220.     if ((move == 0) || (move == 2) || (move == 5) || (move == 7))
  221.         Energy -= 5;
  222.     else
  223.         Energy -= 3;
  224.  
  225.     // did it die?
  226.     if ((Age == MaxAge) || (Energy <= 0))
  227.         return 1;
  228.  
  229.     newx = PosX + MoveTable[move][0];
  230.     newy = PosY + MoveTable[move][1];
  231.  
  232.     Erase();
  233.  
  234.     PosX = newx;
  235.     PosY = newy;
  236.  
  237.     if (PosX < 1) PosX = MaxX;
  238.     if (PosX > MaxX) PosX = 1;
  239.     if (PosY < 1) PosY = MaxY;
  240.     if (PosY > MaxY) PosY = 1;
  241.  
  242.     for (x = PosX - 1; x <= PosX + 1; ++x)
  243.         for (y = PosY - 1; y <= PosY + 1; ++y)
  244.             if (FoodSupply->IsSet(x,y))
  245.                 {
  246.                 Energy += FoodValue;
  247.                 FoodSupply->Exclude(x,y);
  248.                 }
  249.  
  250.     Draw();
  251.  
  252.     return 0;
  253.     }
  254.  
  255. // tell grazer to draw itself
  256. void Grazer::Draw()
  257.     {
  258.     for (int x = PosX - 1; x <= PosX + 1; ++x)
  259.         for (int y = PosY - 1; y <= PosY + 1; ++y)
  260.             PlotPixel(x,y,Color);
  261.     }
  262.  
  263. // tell grazer to erase itself
  264. void Grazer::Erase()
  265.     {
  266.     for (int x = PosX - 1; x <= PosX + 1; ++x)
  267.         for (int y = PosY - 1; y <= PosY + 1; ++y)
  268.             PlotPixel(x,y,0);
  269.     }
  270.