Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's tools.

 

 

 

 

 

(C++) SimThomasBerngruber

 

Technical facts

 

 

 

 

 

 

./ToolSimThomasBerngruber/Project1.cpp

 

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
USEFORM("..\Unit2.cpp", Form2);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
  try
  {
     Application->Initialize();
     Application->Title = "Simple Cellular Automaton";
     Application->CreateForm(__classid(TForm1), &Form1);
     Application->CreateForm(__classid(TForm2), &Form2);
     Application->Run();
  }
  catch (Exception &exception)
  {
     Application->ShowException(&exception);
  }
  catch (...)
  {
     try
     {
       throw Exception("");
     }
     catch (Exception &exception)
     {
       Application->ShowException(&exception);
     }
  }
  return 0;
}
//---------------------------------------------------------------------------

 

 

 

 

 

./ToolSimThomasBerngruber/Unit1.h

 

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Graphics.hpp>
#include <Chart.hpp>
#include <ComCtrls.hpp>
#include <Series.hpp>
#include <TeEngine.hpp>
#include <TeeProcs.hpp>
#include <Dialogs.hpp>
#include <Grids.hpp>
#include <ValEdit.hpp>
//---------------------------------------------------------------------------
#include "UnitRandom.h"
//#include <richel001.h>
enum STATE {EMPTY, SUS, RES, KILL};    // Some global definitions
STATE area[400][400];
int NEmpty=0;
int NSus=0;
int NRes=0;
int NKill=0;
double deathrate=0.0;
double birthrate=0.0;
double cost_of_res=0.0;
double extra_death_kil=0.0;
double mut=0.0;
int duration=0;
int maxx=0;
int maxy=0;
double initsus=0.0;
double initres=0.0;
double initkill=0.0;
int diffusion=0;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
  TButton *Button1;
  TChart *Chart1;
  TLineSeries *Series1;
  TLineSeries *Series2;
  TLineSeries *Series3;
  TLineSeries *Series4;
  TValueListEditor *ValueListEditor1;
        TImage *ImageGrid;
  void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
  __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

//////////////////////
/// Mobius Function///
//////////////////////
template <class T>
void Mobius(T &number,T min, T max)
  {
  if (number>max) {number-=(max+min);}
  if (number<min) {number+=(max-min);}
  }//End of: void Mobius

////////////////////////////////////////////////////////////
// Choose from a 4 neighborhood at max distance diffusion///
////////////////////////////////////////////////////////////

void FindNeighbour(int x1, int y1, int &x2, int& y2, int diffusion)
  {
   x2=x1+(random(2*diffusion+1)-diffusion);
   y2=y1+(random(2*diffusion+1)-diffusion);
   while (x2==x1 && y2==y1)
     {
      x2=x1+(random(2*diffusion+1)-diffusion);
      y2=y1+(random(2*diffusion+1)-diffusion);
     }
  /*switch(random(4))
    {
    case 0 : y2=y1-diffusion; x2=x1; break;
    case 1 : x2=x1-diffusion; y2=y1; break;
    case 2 : y2=y1+diffusion; x2=x1; break;
    case 3 : x2=x1-diffusion; y2=y1; break;
    }//End of: switch (random(4))*/
  }

/////////////////////////////////////
/// Map states to colors ////////////
/////////////////////////////////////

TColor StateToColor(STATE number)
  {
  TColor solution=clWhite;
  if (number==EMPTY) solution=clBlack;
  if (number==SUS) solution=clYellow;
  if (number==RES) solution=clLime;
  if (number==KILL) solution=clRed;
  return (solution);
  }

void ExtractRGB(const int& colorvalue, int &R, int &G, int &B)
   {
   R=GetRValue(colorvalue);
   G=GetGValue(colorvalue);
   B=GetBValue(colorvalue);
   }//End of:

void ExtractRGB(const TColor& colorvalue, int &R, int &G, int &B)
   {
   R=GetRValue(colorvalue);
   G=GetGValue(colorvalue);
   B=GetBValue(colorvalue);
   }//End of:

////////////////////////////////////////////////////////////
// EMPTY THE CHART
////////////////////////////////////////////////////////////
void EmptyChart(TChart * Chart1)
  {
  Chart1->Series[0]->Clear();
  Chart1->Series[1]->Clear();
  Chart1->Series[2]->Clear();
  Chart1->Series[3]->Clear();
  }

////////////////////////////////////////////////////////////
// INITIALIZE THE GRID
////////////////////////////////////////////////////////////
void Init_grid(void)
  {
  for (int x=0; x<maxx; x++)
    {
    for (int y=0; y<maxy; y++)
      {
      //ShowMessage(initsus);
      double ran1=rnd::uniform();
      if (ran1 < initsus) {area[x][y]=SUS;  continue; }
      if (ran1 > initsus &&  ran1 < initsus+initres) {area[x][y]=RES; continue;}
      if (ran1 > initsus+initres  && ran1 < initsus+initres+initkill) {area[x][y]=KILL; continue;}
      area[x][y]=EMPTY;
      }// next y
    }// next x
  }//End of: Init_grid


////////////////////////////////////////////////////////////
// UPDATE THE GRID
////////////////////////////////////////////////////////////
void GridUpdate(void)
  {
  int x1,y1,x2,y2;
  for (y1=0; y1<maxy; y1++)
    {
    for (x1=0; x1<maxx; x1++)
      {
      FindNeighbour(x1,y1,x2,y2,diffusion);
      Mobius(x2,0,maxx-1);
      Mobius(y2,0,maxy-1);
      //Update rule
      STATE Here=area[x1][y1];
      STATE Neighbour=area[x2][y2];
      double ran1=rnd::uniform();
      double ran2=rnd::uniform();
      switch (Here)
        {
        case EMPTY : if ((ran1 < birthrate) && (Neighbour==SUS))
                       {
                        area[x1][y1]=SUS; //Birth: If res/sus are neighbor
                       }

                     else if ((ran2 < birthrate-cost_of_res) && (Neighbour==RES))
                       {
                        area[x1][y1]=RES;
                       }
                     break;

        case SUS   : if (ran2 < deathrate  || Neighbour==KILL)
                       {
                        area[x1][y1]=EMPTY; //Mortality of Sus
                       }
                     break;

        case RES   : if (ran2 < deathrate)
                       {
                       area[x1][y1]=EMPTY; // Mortality of Res
                       }
                     else if (ran1 < mut) //Mutation: Res becomes Kil
                       {
                       area[x1][y1]=KILL;
                       }
                     break;

        case KILL  : if (ran1 < deathrate + extra_death_kil)
                       {
                       area[x1][y1]=EMPTY; //Mortality of Kil
                       }
                     break;
        }//End of: switch(Here)
      }//Next x
    }//Next y
  }//End of: void Update(void)

////////////////////////////////////////////////////////////
// EXAMINE THE GRID
////////////////////////////////////////////////////////////
void CountValues(void)
  {
  //Reset values
  NEmpty=0; NSus=0; NRes=0; NKill=0;
  //Count total grid
  for (int y=0; y<maxy; y++)
    {
    for (int x=0; x<maxx; x++)
      {
      if (area[x][y]==EMPTY) NEmpty++;
      if (area[x][y]==SUS) NSus++;
      if (area[x][y]==RES) NRes++;
      if (area[x][y]==KILL) NKill++;
      }//Next x
    }//Next y
  }//End of: void CountValues(void)

////////////////////////////////////////////////////////////
// DISPLAY THE VALUES IN THE CHART
////////////////////////////////////////////////////////////
void DisplayValues(TChart * Chart1)
  {
  /// Graphical Output timeseries
  Chart1->Series[0]->Add(NEmpty);
  Chart1->Series[1]->Add(NSus);
  Chart1->Series[2]->Add(NRes);
  Chart1->Series[3]->Add(NKill);
  Chart1->Refresh();
  }

///////////////////////////////////////////////////////
//   SHOW AREA
///////////////////////////////////////////////////////
void ShowArea(TPaintBox * PaintBox1)
  {
  int x,y;
  for (y=0; y<maxy; y++)
    {
    for (x=0; x<maxx; x++)
      {
      PaintBox1->Canvas->Pixels[x][y]=StateToColor(area[x][y]);
      }//Next x
    }//Next y
  }//End of: void ShowArea(..)

///////////////////////////////////////////////////////
//   SHOW AREA
///////////////////////////////////////////////////////
void ShowArea(TImage * pImage)
{
  int red, green, blue;
  unsigned char * pLine;
  for (int y=0; y<pImage->Height; ++y)
  {
    pLine=(unsigned char *) pImage->Picture->Bitmap->ScanLine[y];
    for (int x=0; x<pImage->Width; ++x)
    {
      ExtractRGB(StateToColor(area[x][y]),red,green,blue);
      pLine[x*3]  = blue;
      pLine[x*3+1]= green;
      pLine[x*3+2]= red;
    }
  }

}

 

 

 

 

 

./ToolSimThomasBerngruber/Unit1.cpp

 

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <math.h>
#include <vector>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;



//---------------------------------------------------------------------------
// CONSTRUCTOR OF FORM
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------

///////////////////////////////////////////////////////
//   MAIN FUNCTION ////////////////////////////////////
///////////////////////////////////////////////////////
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Read in Parameters

birthrate = ValueListEditor1->Cells[1][1].ToDouble();
deathrate =ValueListEditor1->Cells[1][2].ToDouble();
cost_of_res =ValueListEditor1->Cells[1][3].ToDouble();
extra_death_kil =ValueListEditor1->Cells[1][4].ToDouble();
mut =ValueListEditor1->Cells[1][5].ToDouble();
initsus =ValueListEditor1->Cells[1][6].ToDouble();
initres =ValueListEditor1->Cells[1][7].ToDouble();
initkill =ValueListEditor1->Cells[1][8].ToDouble();
maxx=ValueListEditor1->Cells[1][9].ToInt();
maxy=ValueListEditor1->Cells[1][10].ToInt();
duration=ValueListEditor1->Cells[1][11].ToInt();
diffusion=ValueListEditor1->Cells[1][12].ToInt();

EmptyChart(Chart1);
Init_grid(); //Initialize grid
CountValues();
DisplayValues(Chart1);
ShowArea(ImageGrid);

for (int time=0; time<duration; time++)
  {
  GridUpdate();
  CountValues();
  DisplayValues(Chart1);
  ShowArea(ImageGrid);
  this->Canvas->Draw(0,0,ImageGrid->Picture->Graphic);
  }//Next time
}
//--------------------------------------------------------------------------

 

 

 

 

 

./ToolSimThomasBerngruber/UnitRandom.h

 

//---------------------------------------------------------------------------

#ifndef UnitRandomH
#define UnitRandomH
//---------------------------------------------------------------------------
#include <math.h>

class rnd
{
  private:
  static long int idum;
  static int MBIG;
  static int MSEED;
  static int MZ;
  static double FAC;


  public:
  //Returns a uniform random value from 0.0 to 1.0
  static double uniform()
  {
    static int inext,inextp;
    static long ma[56];
    static int iff=0;
    long mj,mk;
    int i,ii,k;
    if (idum < 0 || iff == 0)
      {
      iff=1;
      mj=MSEED-(idum < 0 ? -idum : idum);
      mj %= MBIG;
      ma[55]=mj;
      mk=1;
      for (i=1;i<=54;i++)
        {
        ii=(21*i) % 55;
        ma[ii]=mk;
        mk=mj-mk;
        if (mk < MZ) mk += MBIG;
        mj=ma[ii];
        }
      for (k=1;k<=4;k++)
        for (i=1;i<=55;i++)
          {
          ma[i] -= ma[1+(i+30) % 55];
          if (ma[i] < MZ) ma[i] += MBIG;
          }
      inext=0;
      inextp=31;
      idum=1;
      }
    if (++inext == 56) inext=1;
    if (++inextp == 56) inextp=1;
    mj=ma[inext]-ma[inextp];
    if (mj < MZ) mj += MBIG;
    ma[inext]=mj;
    return mj*FAC;
  }

  static double gasdev()
  {
    static int iset=0;
    static double gset;
    double fac,r,v1,v2;
    //double uniform();
    uniform();
    if  (iset == 0)
    {
      do
      {
        v1=2.0*uniform()-1.0;
        v2=2.0*uniform()-1.0;
        r=v1*v1+v2*v2;
      }
      while (r >= 1.0);
      fac=sqrt(-2.0*log(r)/r);
      gset=v1*fac;
      iset=1;
      return v2*fac;
    }
    else
    {
      iset=0;
      return gset;
    }
  }
  //Sets the seed for the random number sequence
  static void SetSeed(const int& seed)
  {
    int i;
    idum = long(-std::abs(seed));
    for (i=0; i<100; i++) uniform();
  }
  //Returns a random number from a gaussian distrubution
  static double normal(const double& mean,const double& stdev)
  {
    return gasdev()*stdev + mean;
  }
  //Returns a random integer from 0 to N
  static int RandomNumber(const int& N)
  {
    double x;
    int out;
    x=std::floor(uniform()*N);
    out=int (x);
    return out;
  }
};

#endif

 

 

 

 

 

./ToolSimThomasBerngruber/UnitRandom.cpp

 

//---------------------------------------------------------------------------

#pragma hdrstop

#include "UnitRandom.h"
//---------------------------------------------------------------------------
long int rnd::idum;
int rnd::MBIG  = 1000000000;
int rnd::MSEED = 161803398;
int rnd::MZ = 0;
double rnd::FAC = (1.0/MBIG);

#pragma package(smart_init)

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's tools.

 

Valid XHTML 1.0 Strict