/*
------------------------------------------------------------------------
  Programme: FOURMIES.C

  Module   : Programme principal
			      Borland Turbo C++ Version 1.0

  Auteur   : Jean Philippe BOCQUENET

  Date     : 13/IV/1995

  Objet    : La promenade des fourmies
	     Visualisation d'une s‚quence ou l'ordre peut surgir
	     du Chaos.
	     Inspir‚ de Science et Vie Nø 931 - Avril 1995

-----------------------------------------------------------------------
*/


#include <dos.h>
#include <time.h>
#include <alloc.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>

#define F1            	0x3B00
#define F2  	      	0x3C00
#define F3  	      	0x3D00
#define F4  	      	0x3E00
#define F5  	      	0x3F00
#define F6  	      	0x4000
#define F7  	      	0x4100
#define F8  	      	0x4200
#define F9  	      	0x4300
#define F10 	      	0x4400
#define SHIFT_F10     	0x5D00

#define ENTER    	0x1C0D
#define ESC		0x011B
#define p               0x1970
#define P               0x1950
#define PL 		0x4E2B
#define PLS 		0x0D2B
#define PM 		0x4A2D
#define PMS 		0x0C2D

int xf[21], xf2[21];
int yf[21], yf2[21];
int dxf[21], dxf2[21];
int dyf[21], dyf2[21];
int c, c2, cpo, cpf, pto, ptf, nbf1=10, nbf2=10;
int coul_fourmi1=15;
int coul_fourmi2=1;
int coul_obstacl=8;

/* ------------------------------------------------------------------ */
void init_grafic(void)
{
int gdriver=DETECT, gmode, errorcode;

/*  errorcode=registerbgifont(TRIPLEX_FONT);
  if (errorcode<0)
  {
   printf("Erreure graphique : %s\n",grapherrormsg(errorcode));
   printf("Frappez une touche pour quitter :");
   getch();
   exit(1);
  }
*/
  initgraph(&gdriver, &gmode, "");
  errorcode=graphresult();
  if(errorcode != grOk)
  {
   printf("Erreur graphique : %s\n",grapherrormsg(errorcode));
   printf("Frappez une touche pour quitter :");
   getch();
   exit(1);
  }
}

/* ------------------------------------------------------------------ */
void save_screen(void far *buf[4])
{
unsigned size;
int ystart=0, yend, yincr, block;

  yincr=(getmaxy()+1)/4;
  yend=yincr;
  size=imagesize(0,ystart, getmaxx(), yend);

  for (block=0;block<=3;block++)
  {
   if ((buf[block] = farmalloc(size)) == NULL)
   {
    closegraph();
    printf("Erreure: pas assez d'espace dans -save_screen()-.\n");
    exit(1);
   }
  getimage(0, ystart, getmaxx(), yend, buf[block]);
  ystart=yend+1;
  yend+=yincr+1;
  }
}

/* ------------------------------------------------------------------ */
void restore_screen(void far *buf[4])
{
int ystart=0, yend, yincr, block;

  yincr=(getmaxy()+1)/4;
  yend=yincr;

  for (block=0;block<=3;block++)
   {
    putimage(0,ystart,buf[block], COPY_PUT);
    farfree(buf[block]);
    ystart=yend+1;
    yend+=yincr+1;
   }
}

/* ------------------------------------------------------------------ */
void cadre_ecran(void)
{
 int xe,ye;

 xe=getmaxx();
 ye=getmaxy();
 setcolor(coul_obstacl);
 line(0,0,xe,0); line(0,1,xe,1);
 line(0,ye-1,xe,ye-1);line(0,ye,xe,ye);
 line(0,0,0,ye); line(1,0,1,ye);
 line(xe-1,0,xe-1,ye); line(xe,0,xe,ye);
}

/* ------------------------------------------------------------------ */
void cercles_vides(void)
{
 int midx,midy;

 midx=getmaxx()/2;
 midy=getmaxy()/2;
 setcolor(coul_fourmi1);
 circle(midx,midy,100);
 circle(midx,midy,200);
 circle(midx,midy,300);
}

/* ------------------------------------------------------------------ */
void cercles_pleins(int nbr,int couleur)
{
 int compt;

   delay(800); randomize();
   setcolor(couleur);
   setfillstyle(1,couleur);
   for (compt=1;compt<=nbr;compt++)
   { fillellipse((rand() % getmaxx()), (rand() % getmaxy()),\
       (rand() % 20),(rand() % 20)); }
}

/* ------------------------------------------------------------------ */
void points(int nbr,int couleur)
{
 int compt;

   delay(800); randomize();
   for (compt=1;compt<=nbr;compt++)
    { putpixel((rand() % getmaxx()), (rand() % getmaxy()), couleur); }
}

/* ------------------------------------------------------------------ */
void sens11(compt)
{
c = 0;
if (dxf[compt] == 1 && dyf[compt] == 0) { dxf[compt] = 0; dyf[compt] = 1;return;}
if (dxf[compt] == 0 && dyf[compt] == 1) {dxf[compt] = -1; dyf[compt] = 0;return;}
if (dxf[compt] == -1 && dyf[compt] == 0) {dxf[compt] = 0; dyf[compt] = -1;return;}
if (dxf[compt] == 0 && dyf[compt] == -1) {dxf[compt] = 1; dyf[compt] = 0;return;}
}

/* ------------------------------------------------------------------ */
void sens12(int compt)
{
c = coul_fourmi1;
if (dxf[compt] == 1 && dyf[compt] == 0) {dxf[compt] = 0; dyf[compt] = -1;return;}
if (dxf[compt] == 0 && dyf[compt] == -1) {dxf[compt] = -1; dyf[compt] = 0;return;}
if (dxf[compt] == -1 && dyf[compt] == 0) {dxf[compt] = 0; dyf[compt] = 1;return;}
if (dxf[compt] == 0 && dyf[compt] == 1) {dxf[compt] = 1; dyf[compt] = 0;return;}
}

/* ------------------------------------------------------------------ */
void sens13(int compt)
{
c = coul_obstacl;
if (dxf[compt] == 0 && dyf[compt] == 1) {dxf[compt] = 1; dyf[compt] = 0;return;}
if (dxf[compt] == 1 && dyf[compt] == 0) {dxf[compt] = 0; dyf[compt] = -1;return;}
if (dxf[compt] == 0 && dyf[compt] == -1) {dxf[compt] = -1; dyf[compt] = 0;return;}
if (dxf[compt] == -1 && dyf[compt] == 0) {dxf[compt] = 0; dyf[compt] = 1;return;}
}

/* ------------------------------------------------------------------ */
void sens21(compt)
{
c2 = 0;
if (dxf2[compt] == 1 && dyf2[compt] == 0) { dxf2[compt] = 0; dyf2[compt] = 1;return;}
if (dxf2[compt] == 0 && dyf2[compt] == 1) {dxf2[compt] = -1; dyf2[compt] = 0;return;}
if (dxf2[compt] == -1 && dyf2[compt] == 0) {dxf2[compt] = 0; dyf2[compt] = -1;return;}
if (dxf2[compt] == 0 && dyf2[compt] == -1) {dxf2[compt] = 1; dyf2[compt] = 0;return;}
}

/* ------------------------------------------------------------------ */
void sens22(int compt)
{
c2 = coul_fourmi2;
if (dxf2[compt] == 1 && dyf2[compt] == 0) {dxf2[compt] = 0; dyf2[compt] = -1;return;}
if (dxf2[compt] == 0 && dyf2[compt] == -1) {dxf2[compt] = -1; dyf2[compt] = 0;return;}
if (dxf2[compt] == -1 && dyf2[compt] == 0) {dxf2[compt] = 0; dyf2[compt] = 1;return;}
if (dxf2[compt] == 0 && dyf2[compt] == 1) {dxf2[compt] = 1; dyf2[compt] = 0;return;}
}

/* ------------------------------------------------------------------ */
void sens23(int compt)
{
c2 = coul_obstacl;
if (dxf2[compt] == 0 && dyf2[compt] == 1) {dxf2[compt] = 1; dyf2[compt] = 0;return;}
if (dxf2[compt] == 1 && dyf2[compt] == 0) {dxf2[compt] = 0; dyf2[compt] = -1;return;}
if (dxf2[compt] == 0 && dyf2[compt] == -1) {dxf2[compt] = -1; dyf2[compt] = 0;return;}
if (dxf2[compt] == -1 && dyf2[compt] == 0) {dxf2[compt] = 0; dyf2[compt] = 1;return;}
}

/* ------------------------------------------------------------------ */
void deroulement(void)
{
int sortie=0, tempo=0, tce, compt, x;
unsigned long iteration=0;
char itera[20];
void far *ptr[4];

/* Initialisation du d‚part de chaque fourmi */

   randomize();
   for (compt=1;compt<=nbf1;compt++)
    {
      xf[compt] = (rand() % 540) + 50;
      yf[compt] = (rand() % 250) + 50;
      dxf[compt] = 1; dyf[compt] = 0;
    }
   xf[1]=getmaxx()/2; yf[1]=getmaxy()/2;
   delay(800); randomize();
   for (compt=1;compt<=nbf2;compt++)
    {
      xf2[compt] = (rand() % 540) + 50;
      yf2[compt] = (rand() % 250) + 50;
      dxf2[compt] = 1; dyf2[compt] = 0;
    }

/* Boucle du programme jusqu'a appuie sur une touche */

 for(;sortie==0;)
 { if (bioskey(1) != 0)
   { tce = bioskey(0);
     switch(tce)
    {
    case ESC:        sortie=1;;
		     break;
    case p:
    case P:
		     save_screen(ptr);
		     setcolor(0);
		     outtextxy(getmaxx()-200,getmaxy()-10,"ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ");
		     setcolor(13);
		     sprintf(itera,"It‚ration nø %lu",iteration);
		     outtextxy(getmaxx()-200,getmaxy()-10, itera);
		     getch();
		     restore_screen(ptr);
		     break;
    case PL:
    case PLS:        tempo-=10;
		     if (tempo<=0) {tempo=0;}
		     break;
    case PM:
    case PMS:        tempo+=10;
		     if (tempo>=500) {tempo=500;}
		     break;
    }
   }
   else
   {
    delay(tempo);

/* Boucle des fourmis */
	iteration++;
	for (compt=1;compt<=nbf1;compt++)
	 {
/* Fourmies 1 */
	  x = getpixel(xf[compt], yf[compt]);
	  if (x == coul_fourmi2) { sens11(compt); }
	  if (x == coul_fourmi1) { sens11(compt); }
	  if (x == 0) { sens12(compt); }
	  if (x == coul_obstacl) { sens13(compt); }
	  putpixel(xf[compt], yf[compt], c);
	  xf[compt] = xf[compt] + dxf[compt];
	  yf[compt] = yf[compt] + dyf[compt];
	 }
	for (compt=1;compt<=nbf2;compt++)
	 {
/* Fourmies 2*/
	  x = getpixel(xf2[compt], yf2[compt]);
	  if (x == coul_fourmi1) { sens21(compt); }
	  if (x == coul_fourmi2) { sens21(compt); }
	  if (x == 0) { sens22(compt); }
	  if (x == coul_obstacl) { sens23(compt); }
	  putpixel(xf2[compt], yf2[compt], c2);
	  xf2[compt] = xf2[compt] + dxf2[compt];
	  yf2[compt] = yf2[compt] + dyf2[compt];
	 }
   }
 }
}

/* ------------------------------------------------------------------ */
void ecran_pres(void)
{
char tampon[20];

  cleardevice();
  setcolor(7);
  settextstyle(TRIPLEX_FONT,HORIZ_DIR,5);
  outtextxy((getmaxx()/2)-260,50,"CHAOS CHEZ LES FOURMIES");
  settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
  outtextxy(220,120,"Programme : J. Ph. Bocquenet");
  outtextxy(100,200,"Cercles vides concentriques :    F1  -   NON");
  outtextxy(100,220,"Ellipses pleines opaques :       F2  -");
  sprintf(tampon,"%d",cpo); outtextxy(430,220, tampon);
  outtextxy(100,240,"Ellipses pleines transparentes : F3  -");
  sprintf(tampon,"%d",cpf); outtextxy(430,240, tampon);
  outtextxy(100,260,"Points opaques :                 F4  -");
  sprintf(tampon,"%d",pto); outtextxy(430,260, tampon);
  outtextxy(100,280,"Points transparents :            F5  -");
  sprintf(tampon,"%d",ptf); outtextxy(430,280, tampon);
  outtextxy(100,300,"Nombre de fourmies 1 (0-20) :    F6  -");
  sprintf(tampon,"%d",nbf1); outtextxy(430,300, tampon);
  outtextxy(100,320,"Nombre de fourmies 2 (0-20) :    F7  -");
  sprintf(tampon,"%d",nbf2); outtextxy(430,320, tampon);
  outtextxy(100,340,"Lancer l'exp‚rience :           [F10]");
  outtextxy(100,360,"Sortie du programme :           [SHIFT][F10]");
  outtextxy(50,400,"S‚lectionne les options avec les touches de fonction");
  outtextxy(50,420,"puis change les options avec les touches + et -");
}

/* ------------------------------------------------------------------ */
void main(void)
{
unsigned int touche, tch;
int sortie=0, compt, opt[10];
char tampon[20];

  init_grafic();
  cpo=0; cpf=0; pto=0; ptf=0;
  ecran_pres();
  for(compt=1;compt<=5;compt++) { opt[compt]=0; }

 for(;;)
 {
  touche = bioskey(0);
  switch(touche)
 {
  case F1:
	     setcolor(0);
	     outtextxy(100,200,"ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ");
	     setcolor(13);
	     outtextxy(100,200,"Cercles vides concentriques :    F1");
	     delay(500);
	     setcolor(7);
	     opt[1]+=1;
	     if (opt[1]>1) {opt[1]=0;}
	     if (opt[1]==1)
	     { outtextxy(100,200,"Cercles vides concentriques :    F1  -   OUI"); }
	     if (opt[1]==0)
	     { outtextxy(100,200,"Cercles vides concentriques :    F1  -   NON"); }
	     break;

  case F2:
	     setcolor(13);
	     outtextxy(100,220,"Ellipses pleines opaques :       F2");

	     for(;sortie==0;)
	       {tch=bioskey(0);
		switch(tch)
		{
		 case PL:
		 case PLS:   cpo++;
			     if (cpo>=50) {cpo=50;}
			     setcolor(0); outtextxy(430,220,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",cpo);
			     outtextxy(430,220, tampon);
			     break;
		 case PM:
		 case PMS:   cpo--;
			     if (cpo<=0) {cpo=0;}
			     setcolor(0); outtextxy(430,220,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",cpo);
			     outtextxy(430,220, tampon);
			     break;
		 case ENTER: sortie=1;
			     break;
		}
	       }
	     opt[2]=1;
	     setcolor(7);
	     outtextxy(100,220,"Ellipses pleines opaques :       F2");
	     outtextxy(430,220, tampon);
	     sortie=0;
	     break;

  case F3:
	     setcolor(13);
	     outtextxy(100,240,"Ellipses pleines transparentes : F3");

	     for(;sortie==0;)
	       {tch=bioskey(0);
		switch(tch)
		{
		 case PL:
		 case PLS:   cpf++;
			     if (cpf>=50) {cpf=50;}
			     setcolor(0); outtextxy(430,240,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",cpf);
			     outtextxy(430,240, tampon);
			     break;
		 case PM:
		 case PMS:   cpf--;
			     if (cpf<=0) {cpf=0;}
			     setcolor(0); outtextxy(430,240,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",cpf);
			     outtextxy(430,240, tampon);
			     break;
		 case ENTER: sortie=1;
			     break;
		}
	       }
	     opt[3]=1;
	     setcolor(7);
	     outtextxy(100,240,"Ellipses pleines transparentes : F3");
	     outtextxy(430,240, tampon);
	     sortie=0;
	     break;

  case F4:
	     setcolor(13);
	     outtextxy(100,260,"Points opaques :                 F4");

	     for(;sortie==0;)
	       {tch=bioskey(0);
		switch(tch)
		{
		 case PL:
		 case PLS:   pto++;
			     if (pto>=500) {pto=500;}
			     setcolor(0); outtextxy(430,260,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",pto);
			     outtextxy(430,260, tampon);
			     break;
		 case PM:
		 case PMS:   pto--;
			     if (pto<=0) {pto=0;}
			     setcolor(0); outtextxy(430,260,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",pto);
			     outtextxy(430,260, tampon);
			     break;
		 case ENTER: sortie=1;
			     break;
		}
	       }
	     opt[4]=1;
	     setcolor(7);
	     outtextxy(100,260,"Points opaques :                 F4");
	     outtextxy(430,260, tampon);
	     sortie=0;
	     break;

  case F5:
	     setcolor(13);
	     outtextxy(100,280,"Points transparents :            F5");

	     for(;sortie==0;)
	       {tch=bioskey(0);
		switch(tch)
		{
		 case PL:
		 case PLS:   ptf++;
			     if (ptf>=500) {ptf=500;}
			     setcolor(0); outtextxy(430,280,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",ptf);
			     outtextxy(430,280, tampon);
			     break;
		 case PM:
		 case PMS:   ptf--;
			     if (ptf<=0) {ptf=0;}
			     setcolor(0); outtextxy(430,280,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",ptf);
			     outtextxy(430,280, tampon);
			     break;
		 case ENTER: sortie=1;
			     break;
		}
	       }
	     opt[5]=1;
	     setcolor(7);
	     outtextxy(100,280,"Points transparents :            F5");
	     outtextxy(430,280, tampon);
	     sortie=0;
	     break;

  case F6:
	     setcolor(13);
	     outtextxy(100,300,"Nombre de fourmies 1 (0-20) :    F6");

	     for(;sortie==0;)
	       {tch=bioskey(0);
		switch(tch)
		{
		 case PL:
		 case PLS:   nbf1++;
			     if (nbf1>=20) {nbf1=20;}
			     setcolor(0); outtextxy(430,300,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",nbf1);
			     outtextxy(430,300, tampon);
			     break;
		 case PM:
		 case PMS:   nbf1--;
			     if (nbf1<=0) {nbf1=0;}
			     setcolor(0); outtextxy(430,300,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",nbf1);
			     outtextxy(430,300, tampon);
			     break;
		 case ENTER: sortie=1;
			     break;
		}
	       }
	     opt[6]=1;
	     setcolor(7);
	     outtextxy(100,300,"Nombre de fourmies 1 (0-20) :    F6");
	     outtextxy(430,300, tampon);
	     sortie=0;
	     break;

  case F7:
	     setcolor(13);
	     outtextxy(100,320,"Nombre de fourmies 2 (0-20) :    F7");

	     for(;sortie==0;)
	       {tch=bioskey(0);
		switch(tch)
		{
		 case PL:
		 case PLS:   nbf2++;
			     if (nbf2>=20) {nbf2=20;}
			     setcolor(0); outtextxy(430,320,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",nbf2);
			     outtextxy(430,320, tampon);
			     break;
		 case PM:
		 case PMS:   nbf2--;
			     if (nbf2<=0) {nbf2=0;}
			     setcolor(0); outtextxy(430,320,"ÛÛÛÛ");
			     setcolor(13);
			     sprintf(tampon,"%d",nbf2);
			     outtextxy(430,320, tampon);
			     break;
		 case ENTER: sortie=1;
			     break;
		}
	       }
	     opt[7]=1;
	     setcolor(7);
	     outtextxy(100,320,"Nombre de fourmies 2 (0-20) :    F7");
	     outtextxy(430,320, tampon);
	     sortie=0;
	     break;

  case F10 :
	     cleardevice();
	     if(opt[1]==1) { cercles_vides();}
	     if(opt[2]==1) { cercles_pleins(cpo,coul_obstacl);}
	     if(opt[3]==1) { cercles_pleins(cpf,coul_fourmi1);;}
	     if(opt[4]==1) { points(pto,coul_obstacl);;}
	     if(opt[5]==1) { points(ptf,coul_fourmi1);;}

	     cadre_ecran();
	     deroulement();
	     ecran_pres();
	     break;

  case SHIFT_F10:
	closegraph();
	clrscr();
	exit(0);
  }
 }
}
