C'est un algorithme de propagation, un peut comme les virus a la télé.
On peut dire qu'il simule du récursif multitache en utilisant une pile.
Le rendu est simpat, l'algo aussi...
Source / Exemple :
//##############################################################################
//# #
//# fichier : propa.c version : V1.0 #
//# projet : propa date : 26/11/2005 #
//# par : aerith #
//# #
//# algo de propagation #
//# #
//##############################################################################
#include <string.h>
#include <SDL\SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include "SDL text.h"
#ifdef WIN32
#include <windows.h>
#include <winbase.h>
#include <time.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/time.h>
#endif
#define WIDTH 800
#define HEIGHT 600
#define NBWALL (WIDTH * HEIGHT) / 3
#define NBBOOST 0//(WIDTH * HEIGHT) / 5
#define BLOCK 1
typedef struct _vecteur
{
int x;
int y;
} vecteur;
SDL_Surface *Screen;
char Matrice[WIDTH][HEIGHT];
int NbThread;
int MaxThread;
int MinThread;
int NoThread;
int NbBlock;
vecteur Stack[WIDTH * HEIGHT];
rect Zone;
color Top, Back;
char Text[1024];
void TempWait(int iDelai);
void Propa(vecteur *vPt);
void Point(int x, int y, int r, int g, int b);
void Block(int iX0, int iY0, int r, int g, int b);
void AddThread(vecteur *vPt);
int main(int argc, char **argv)
{
int i, nb;
vecteur pt;
Uint32 Color;
clock_t start;
SDL_Event event;
int done = 0;
srand(time(NULL));
SDL_Init(SDL_INIT_VIDEO);
atexit(SDL_Quit);
Screen = SDL_SetVideoMode(WIDTH * BLOCK, HEIGHT * BLOCK, 16, SDL_SWSURFACE|SDL_DOUBLEBUF);
Zone.x = 1;
Zone.y = 1;
Zone.l = Screen->w;
Zone.h = Screen->h;
Top.r = 255;
Top.g = 255;
Top.b = 255;
Back.r = 0;
Back.g = 0;
Back.b = 0;
for(pt.y = 0; pt.y < HEIGHT; pt.y++)
for(pt.x = 0; pt.x < WIDTH; pt.x++)
Matrice[pt.x][pt.y] = 0;
for(i = 0; i < NBWALL;)
{
pt.x = (int)(rand() * ((float)WIDTH / RAND_MAX));
pt.y = (int)(rand() * ((float)HEIGHT / RAND_MAX));
if(!Matrice[pt.x][pt.y])
{
Matrice[pt.x][pt.y] = 1;
i++;
if(BLOCK > 1)
Block(pt.x, pt.y, 255, 0, 0);
else
Point(pt.x, pt.y, 255, 0, 0);
}
}
for(i = 0; i < NBBOOST;)
{
pt.x = (int)(rand() * ((float)WIDTH / RAND_MAX));
pt.y = (int)(rand() * ((float)HEIGHT / RAND_MAX));
if(Matrice[pt.x][pt.y] != 1)
{
Matrice[pt.x][pt.y] = 2;
i++;
if(BLOCK > 1)
Block(pt.x, pt.y, 0, 255, 0);
else
Point(pt.x, pt.y, 0, 255, 0);
}
}
do
{
pt.x = (int)(rand() * ((float)WIDTH / RAND_MAX));
pt.y = (int)(rand() * ((float)HEIGHT / RAND_MAX));
}
while(Matrice[pt.x][pt.y] != 0);
NbThread = 0;
MaxThread = 0;
NoThread = 0;
MinThread = 1;
NbBlock = 0;
start = clock();
Propa(&pt);
do
{
nb = NbThread;
if(NbThread > MaxThread)
MaxThread = NbThread;
NbThread = 0;
if(SDL_MUSTLOCK(Screen))
if(SDL_LockSurface(Screen) < 0)
return 0;
for(i = 0; i < nb; i++)
Propa(&Stack[MinThread + i]);
MinThread += i;
sprintf(Text, "Thread:%i (%i) \nCases :%i\nTime :%i ms", NbThread, MaxThread, NbBlock, clock() - start);
SDLText(Screen, Text, Zone, 2, Top, Back);
TempWait(1);
if(SDL_MUSTLOCK(Screen))
SDL_UnlockSurface(Screen);
SDL_Flip(Screen);
}
while(nb);
while(!done)
{
TempWait(10);
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
done = 1;
}
}
return 0;
}
void Propa(vecteur *vPt)
{
vecteur pt;
if(Matrice[vPt->x][vPt->y] != 1)
{
Matrice[vPt->x][vPt->y] = 1;
if(BLOCK > 1)
Block(vPt->x, vPt->y, 0, 0, 255);
else
Point(vPt->x, vPt->y, 0, 0, 255);
NbBlock++;
}
pt.y = vPt->y - 1;
pt.x = vPt->x;
AddThread(&pt);
if(Matrice[pt.x][pt.y] == 2)
pt.y = vPt->y - 2;
AddThread(&pt);
pt.y = vPt->y + 1;
AddThread(&pt);
if(Matrice[pt.x][pt.y] == 2)
pt.y = vPt->y + 2;
AddThread(&pt);
pt.y = vPt->y;
pt.x = vPt->x + 1;
AddThread(&pt);
if(Matrice[pt.x][pt.y] == 2)
pt.x = vPt->x + 2;
AddThread(&pt);
pt.x = vPt->x - 1;
AddThread(&pt);
if(Matrice[pt.x][pt.y] == 2)
pt.x = vPt->x - 2;
AddThread(&pt);
}
void AddThread(vecteur *vPt)
{
int i;
if((vPt->x >= 0) && (vPt->x < WIDTH) && (vPt->y >= 0) && (vPt->y < HEIGHT))
{
if(Matrice[vPt->x][vPt->y] != 1)
{
for(i = MinThread; i <= NoThread; i++)
if((Stack[i].x == vPt->x) && (Stack[i].y == vPt->y))
return;
NoThread++;
NbThread++;
Stack[NoThread].x = vPt->x;
Stack[NoThread].y = vPt->y;
}
}
}
void Point(int x, int y, int r, int g, int b)
{
Uint16 *pPxl;
pPxl = (Uint16*)Screen->pixels + ((Screen->pitch / 2 * y) + x);
- pPxl = SDL_MapRGB(Screen->format, (Uint8)r, (Uint8)g, (Uint8)b);
}
void Block(int iX0, int iY0, int r, int g, int b)
{
int x, y, px, py;
px = iX0 * BLOCK;
py = iY0 * BLOCK;
for(y = 0; y < BLOCK; y++)
for(x = 0; x < BLOCK; x++)
Point(px + x, py + y, r, g, b);
}
void TempWait(int iDelai)
{
#ifdef WIN32
Sleep(iDelai);
#else
usleep(iDelai * 1000);
#endif
}
Conclusion :
On peut chager quelque paramètre dans les defines.
Il ne faut pas toucher a la fenètre pendant le calcul, sinon vous perder l'affichage.
Le screen est a chier car on ne peut pas fait de capture d'écran, donc photo...
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.