Jeu de la vie en mode vga 11h [djgpp]

Description

Le jeu de la vie de John Conway en mode VGA 11h (640x480 pixels, noir et blanc).
Le jeu de la vie est un automate cellulaire aux règles extrêmement simple : le 'monde' du jeu de la vie est un plateau infini en 2D, et lorsque qu'une case a exactement trois voisins (les voisins en diagonale comptent), une nouvelle cellule nait dans cette case. Une cellule ne survit à la génération suivante que si elle a deux ou trois voisins, sinon elle meurt par désertification ou étouffement.
Il existe de nombreuses combinaisons de cellules qui donnent des résultats remarquables : des 'glisseurs', 'oscillateurs', des combinaisons qui reste stable (par exemple un carré de 2 cellules de côté), des 'navires', et avec des combinaisons plus complexes on peut même créer des 'lance-glisseurs', des colonies de cellules dont la population grandit à l'infini,... Il a également été démontré qu'il était possible de créer au moyen de 'glisseurs' et autres combinaisons des instructions logiques ET, OU, NON comme en électronique, et donc d'utiliser le 'monde' du jeu de la vie comme un ordinateur. Il existe même des combinaisons de cellules qui permettent de calculer les nombres premiers. Mais sinon le jeu de la vie n'a pas vraiment d'intérêt, si ce n'est ludique, mais il prouve que même si un univers est très complexes, ces règles peuvent néanmoins être extrêmement simple.

Source / Exemple :


#include			<conio.h>
#include			<dos.h>
#include			<go32.h>
#include			<math.h>
#include			<stdio.h>
#include			<stdlib.h>
#include			<string.h>
#include			<sys/farptr.h>
#include			<time.h>

char				buffer[8192];
char				temp[8192];
union REGS			regs;

void				Display();
void				InitVGA();
void				Life();
void				StopVGA();

int				main(int argc,char** argv)
{
	int			i;
	int			cells=0;
	int			max=0;
	int			min=65535;
	int			min2;
	int			rem=0;
	int			mode=0;
	int			generations=1;
	char			key=0;
	FILE*			file;

	/* --- ouvre une 'sauvegarde' si demande --- */
	if (argc==2)
	{
		for (i=0 ; i<8192 ; i++) buffer[i]=0;
		file=fopen(argv[1],"rb");
		fread(buffer,1,8192,file);
		/*
			pour un fichier de sauvegarde plus gros mais facile a editer
		for (i=0 ; i<256*256 ; i++)
		{
			if ((!(i&255))&&(i)) fseek(file,2L,SEEK_CUR);
			if (fgetc(file)!='.') buffer[i>>3]|=(1<<(7-(i&7)));
		}

  • /
fclose(file); } /* --- sinon dispose aleatoirement les cellules --- */ else { srand(time(NULL)); for (i=0 ; i<8192 ; i++) buffer[i]=rand(); } /* --- affichage des informations --- */ printf("JEU DE LA VIE\r\n" "-------------\r\n" "\r\n" "commandes :\r\n" "\r\n" "ESCAPE quitter\r\n" "ENTER evolution automatique/manuelle\r\n" "ESPACE evoluer (en mode manuel)\r\n" "+ et - changer le nombre de generations par evolution (defaut 1)\r\n" "TAB sauvegarder (sous le nom \"cellules.dat\"\r\n" "\r\n" "Appuyez sur ENTER pour commencer"); while (getch()!=13); /* --- jeu de la vie --- */ InitVGA(); while (key!=27) { cells=0; /* --- compte les cellules --- */ for (i=0 ; i<8192 ; i++) { if (buffer[i]&1) cells++; if (buffer[i]&2) cells++; if (buffer[i]&4) cells++; if (buffer[i]&8) cells++; if (buffer[i]&16) cells++; if (buffer[i]&32) cells++; if (buffer[i]&64) cells++; if (buffer[i]&128) cells++; } if (cells<min) { min=cells; max=min; } if ((cells-min)>rem) { rem=cells-min; min2=min; } if (cells>max) max=cells; gotoxy(2,25); printf("nombre de cellules : %-5d",cells); gotoxy(2,26); printf("plus petit nombre atteind : %-5d",min); gotoxy(2,27); printf("plus grande remontee : +%-5d en partant de %-5d",rem,min2); gotoxy(2,28); printf("plus grand nombre atteind depuis le dernier plus petit nombre atteind : %-5d",max); Display(); if ((mode)||(key==' ')) { for (i=0 ; i<generations ; i++) Life(&cells); if (kbhit()) key=getch(); else key=0; } else key=getch(); if (key==13) { gotoxy(2,2); if (mode) { mode=0; printf("evolution manuelle "); } else { mode=1; printf("evolution automatique "); } } else if (key==9) { file=fopen("cellules.dat","wb"); fwrite(buffer,1,8192,file); /* pour un fichier de sauvegarde plus gros mais facile a editer for (i=0 ; i<256*256 ; i++) { if ((!(i&255))&&(i)) fprintf(file,"\r\n"); if (buffer[i>>3]&(1<<(7-(i&7)))) fputc('#',file); else fputc('.',file); } fprintf(file,"\r\n");
  • /
fclose(file); gotoxy(2,2); printf("cellules enregistrees dans \"cellules.dat\" "); } else if (key=='+') { if (generations<20) generations++; gotoxy(2,2); printf("generations : %2d ",generations); } else if (key=='-') { if (generations>1) generations--; gotoxy(2,2); printf("generations : %2d ",generations); } } StopVGA(); return 0; } void Display() { int x; int y; int i=0; /* --- synchronise avec l'ecran --- */ while (!(inportw(0x03DA)&8)); while (inportw(0x03DA)&8); /* --- affichage --- */ for (y=0 ; y<256 ; y++) { for (x=0 ; x<32 ; x++) _farnspokeb(0xA0000+(y*80)+111*80+x+23,buffer[i++]); } } void InitVGA() { int i; /* --- activation mode 11h (640x480 B/W) --- */ regs.x.ax=0x0011; int86(0x10,&regs,&regs); _farsetsel(_dos_ds); /* --- dessine le cadre --- */ for (i=0 ; i<272 ; i++) _farnspokeb(0xA0000+(i+103)*80+22,0x02); for (i=0 ; i<272 ; i++) _farnspokeb(0xA0000+(i+103)*80+55,0x40); for (i=0 ; i<34 ; i++) _farnspokeb(0xA0000+109*80+22+i,0xFF); for (i=0 ; i<34 ; i++) _farnspokeb(0xA0000+368*80+22+i,0xFF); } void Life() { int i; int n; unsigned char p; /* --- fait un 'double' des cellules --- */ memcpy(temp,buffer,8192); /* --- premiere ligne --- */ for (i=0 ; i<32 ; i++) { /* --- premiere cellule --- */ n=0; if (temp[i-1]&1) n++; if (temp[i]&64) n++; if (temp[i+8160]&128) n++; if (temp[i+32]&128) n++; if (temp[i+8159]&1) n++; if (temp[i+8160]&64) n++; if (temp[i+31]&1) n++; if (temp[i+32]&64) n++; if (n==3) buffer[i]|=128; else if (n!=2) buffer[i]&=127; /* --- le reste --- */ for (p=64 ; p!=1 ; p>>=1) { n=0; if (temp[i]&(p<<1)) n++; if (temp[i]&(p>>1)) n++; if (temp[i+8160]&p) n++; if (temp[i+32]&p) n++; if (temp[i+8160]&(p<<1)) n++; if (temp[i+8160]&(p>>1)) n++; if (temp[i+32]&(p<<1)) n++; if (temp[i+32]&(p>>1)) n++; if (n==3) buffer[i]|=p; else if (n!=2) buffer[i]&=~p; } /* --- derniere cellule --- */ n=0; if (temp[i]&2) n++; if (temp[i+1]&128) n++; if (temp[i+8160]&1) n++; if (temp[i+32]&1) n++; if (temp[i+8160]&2) n++; if (temp[i+8161]&128) n++; if (temp[i+32]&2) n++; if (temp[i+33]&128) n++; if (n==3) buffer[i]|=1; else if (n!=2) buffer[i]&=254; } /* --- derniere ligne --- */ for (i=8192-32 ; i<8192 ; i++) { /* --- premiere cellule --- */ n=0; if (temp[i-1]&1) n++; if (temp[i]&64) n++; if (temp[i-32]&128) n++; if (temp[i-8160]&128) n++; if (temp[i-33]&1) n++; if (temp[i-32]&64) n++; if (temp[i-8161]&1) n++; if (temp[i-8160]&64) n++; if (n==3) buffer[i]|=128; else if (n!=2) buffer[i]&=127; for (p=64 ; p!=1 ; p>>=1) { n=0; if (temp[i]&(p<<1)) n++; if (temp[i]&(p>>1)) n++; if (temp[i-32]&p) n++; if (temp[i-8160]&p) n++; if (temp[i-32]&(p<<1)) n++; if (temp[i-32]&(p>>1)) n++; if (temp[i-8160]&(p<<1)) n++; if (temp[i-8160]&(p>>1)) n++; if (n==3) buffer[i]|=p; else if (n!=2) buffer[i]&=~p; } /* --- derniere cellule --- */ n=0; if (temp[i]&2) n++; if (temp[i+1]&128) n++; if (temp[i-32]&1) n++; if (temp[i-8160]&1) n++; if (temp[i-32]&2) n++; if (temp[i-31]&128) n++; if (temp[i-8160]&2) n++; if (temp[i-8159]&128) n++; if (n==3) buffer[i]|=1; else if (n!=2) buffer[i]&=254; } /* --- le reste --- */ for (i=32 ; i<8192-32 ; i++) { /* --- premiere cellule --- */ if (i&31) { n=0; if (temp[i-1]&1) n++; if (temp[i]&64) n++; if (temp[i-32]&128) n++; if (temp[i+32]&128) n++; if (temp[i-33]&1) n++; if (temp[i-32]&64) n++; if (temp[i+31]&1) n++; if (temp[i+32]&64) n++; } /* --- si extremite gauche --- */ else { n=0; if (temp[i+31]&1) n++; if (temp[i]&64) n++; if (temp[i-32]&128) n++; if (temp[i+32]&128) n++; if (temp[i-1]&1) n++; if (temp[i-32]&64) n++; if (temp[i+63]&1) n++; if (temp[i+32]&64) n++; } if (n==3) buffer[i]|=128; else if (n!=2) buffer[i]&=127; /* --- le reste --- */ for (p=64 ; p!=1 ; p>>=1) { n=0; if (temp[i]&(p<<1)) n++; if (temp[i]&(p>>1)) n++; if (temp[i-32]&p) n++; if (temp[i+32]&p) n++; if (temp[i-32]&(p<<1)) n++; if (temp[i-32]&(p>>1)) n++; if (temp[i+32]&(p<<1)) n++; if (temp[i+32]&(p>>1)) n++; if (n==3) buffer[i]|=p; else if (n!=2) buffer[i]&=~p; } /* --- derniere cellule --- */ if ((i+1)&31) { n=0; if (temp[i]&2) n++; if (temp[i+1]&128) n++; if (temp[i-32]&1) n++; if (temp[i+32]&1) n++; if (temp[i-32]&2) n++; if (temp[i-31]&128) n++; if (temp[i+32]&2) n++; if (temp[i+33]&128) n++; } /* --- si extremite droite --- */ else { n=0; if (temp[i]&2) n++; if (temp[i-31]&128) n++; if (temp[i-32]&1) n++; if (temp[i+32]&1) n++; if (temp[i-32]&2) n++; if (temp[i-63]&128) n++; if (temp[i+32]&2) n++; if (temp[i+1]&128) n++; } if (n==3) buffer[i]|=1; else if (n!=2) buffer[i]&=254; } /* --- cellule coin haut gauche --- */ n=0; if (temp[31]&1) n++; if (temp[0]&64) n++; if (temp[8160]&128) n++; if (temp[32]&128) n++; if (temp[8191]&1) n++; if (temp[8160]&64) n++; if (temp[63]&1) n++; if (temp[32]&64) n++; if (n==3) buffer[0]|=128; else if (n!=2) buffer[0]&=127; /* --- cellule coin haut droit --- */ n=0; if (temp[31]&2) n++; if (temp[0]&128) n++; if (temp[8191]&1) n++; if (temp[63]&1) n++; if (temp[8191]&2) n++; if (temp[8160]&128) n++; if (temp[63]&2) n++; if (temp[32]&128) n++; if (n==3) buffer[31]|=1; else if (n!=2) buffer[31]&=254; /* --- cellule coin bas gauche --- */ n=0; if (temp[8191]&1) n++; if (temp[8160]&64) n++; if (temp[8128]&128) n++; if (temp[0]&128) n++; if (temp[8159]&1) n++; if (temp[8128]&64) n++; if (temp[31]&1) n++; if (temp[0]&64) n++; if (n==3) buffer[8160]|=128; else if (n!=2) buffer[8160]&=127; /* --- cellule coin bas droit --- */ n=0; if (temp[8191]&2) n++; if (temp[8160]&128) n++; if (temp[8159]&1) n++; if (temp[31]&1) n++; if (temp[8159]&2) n++; if (temp[8128]&128) n++; if (temp[31]&2) n++; if (temp[0]&128) n++; if (n==3) buffer[8191]|=1; else if (n!=2) buffer[8191]&=254; } void StopVGA() { regs.x.ax=0x0003; int86(0x10,&regs,&regs); }

Conclusion :


Il y a possibilité de sauvegarde, et j'ai mis dans le zip quelques configurations de depart remarquables, pour essayer une sauvegarde, déplacer seulement son icône sur l'icone du programme. Normalement le plateau du jeu de la vie est infini, mais dans le programme c'est un tore de 256x256 cases : le bord droit correspond au gauche, le bord haut au bas,... Le programme se compile normalement avec DJGPP, et normalement il devrait marcher un peu mieux que mes autres sources graphiques vu que c'est un mode VGA et pas VESA, et qu'il n'y a pas de 'mappage' de mémoire et autres merdes qui faisaient foirer mes précédents programmes sur certaines machines.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.