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

Soyez le premier à donner votre avis sur cette source.

Vue 4 939 fois - Téléchargée 266 fois

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

Ajouter un commentaire

Commentaires

dubstructor
Messages postés
15
Date d'inscription
vendredi 24 juillet 2009
Statut
Membre
Dernière intervention
24 février 2010
-
Oups j'avais pas vu la date ^^
dubstructor
Messages postés
15
Date d'inscription
vendredi 24 juillet 2009
Statut
Membre
Dernière intervention
24 février 2010
-
'Lut

J'avais programmé un petit jeu de la vie dans le temps pour tester ma librairie graphique. J'ai pas regardé ton code en détail mais il me semble que si tu gères les cases en mode damier infini (ie, les bords se "touchent") tu peux utiliser l'indiçage modulo 81xx (enfin ta taille de tableau) (et moyennant une petite conversion d'indices vu que tu gères tout ça en tableau 1D), du style temp[getIndex(i,j)] ou getIndex renvoie un truc du genre (i%tailleX)*tailleY+j%tailleY (je tape ça au pifo hein, c pas à prendre tel quel), comme ça ça t'évite de prendre en compte à chaque fois tous les cas particuliers !
cs_gorgonzola
Messages postés
37
Date d'inscription
samedi 16 mars 2002
Statut
Membre
Dernière intervention
21 février 2015
-
Bah je sais pas si c'est possible de faire une source portable vu que ça utilise des instructions de très bas niveau. Sous Turbo C par exemple je crois qu'on peut mettre de l'ASM inline à la place mais je suis pas sûr.
Sinon voila un exécutable : http://gcheese.free.fr/life.exe
essayer les fichier .dat que j'ai mis dans le zip, il y en a qui donnent des beaux effets.
coucou747
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
29 -
#include <dos.h>
ça m'interesse mais je ne peux pas y jouer... tu peux pas faire un jeu portable ?
TeLeTUbIz
Messages postés
215
Date d'inscription
mercredi 30 juillet 2003
Statut
Membre
Dernière intervention
25 septembre 2010
-
Bon ca m'intéresse moi aussi (et pour une fois je suis satisfait parce que tu explique le truc dans les notes dans la description de sources;en générals, certains oublient voir n'ont pas envie de le faire).

Bref, j'aimerais bien un executable, parce qu'il manque go32.h pour compilé (je ne sais quelle librairie).

Thx

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.