Partage

[FAIT][Défis] #2 : Le jeu de la vie !

SDL

12 septembre 2011 à 14:50:58

Il me semble qu'il faut utiliser 2 tableaux.
C'est ce que j'ai fait en tout cas. :-°
Zeste de Savoir, le site qui en a dans le citron !
12 septembre 2011 à 14:51:08

Logiquement, aucun ordre n'est donné, donc c'est par génération.
12 septembre 2011 à 14:55:50

Hahaha excellent le U, en fait c'est la combinaison de base à mettre par défaut pour vendre le projet ^^

J'vais peut être m'y mettre j'pense.

Et j'avoue m'être posé la même question que Pampattitude.
Moi je vois ça dans deux tableaux pareil.
12 septembre 2011 à 17:48:07

salut,
honnêtement, je suis assez impressionné par la vitesse des réponses, c'est un concept marrant, sur lequel je vais me pencher, mais je risque d'en avoir pour au moins une semaine ^^...
juste une question, la cellule en diagonale est considérées comme voisine ?
Nouveaux Modules pour la CEV_lib : éditeur de map (tiles) + météo. Testez le rendu ici. w pour alterner météo.
12 septembre 2011 à 18:08:57

Oui je crois.
Staff désormais retraité.
12 septembre 2011 à 18:25:02

Citation : Mr21

Ahh j'ai testé c'est cool!

[...] Et pouvoir dessiner pendant que ça joue serait sympa aussi jpense


Tu peux dessiner si tu mets en pause.
12 septembre 2011 à 21:13:33

salut,
bon, finalement, j'ai fait un truc qui semble marcher, par contre, j'ai un petit souci, tous mes "organismes" meurent ou s'arrêtent d'évoluer.
Du coup pour la vie, c'est pas terrible...

main :

#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
#include "constantes.h"
#include "fonctions.h"

int main ( int argc, char** argv )
{
    (void)argc;
    (void)argv;

    /* initialisation SDL video */
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {/*gestion de l'echec*/
        printf( "Err / main init SDL: %s\n", SDL_GetError() );
        exit(EXIT_FAILURE);
    }
    else /*init SDL OK*/
        atexit(SDL_Quit);

    /* creation de la fenêtre*/
    SDL_Surface* ecran = SDL_SetVideoMode(LARG_TAB*TAILLE_BLOCK, HAUT_TAB*TAILLE_BLOCK, 16,
                                           SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !ecran )
    {
        printf("Err création de la fenêtre 640x480 video: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    ETAT tab[2][LARG_TAB][HAUT_TAB];

    init_table(tab);


    BOOL fin=FALSE,
        pause=TRUE,
        index=FALSE;
    while (!fin)
    {

        SDL_Event event;

        while (SDL_PollEvent(&event))
        {

            switch (event.type)
            {

                case SDL_QUIT:/*croix quitter*/
                    fin = TRUE;
                    break;


                case SDL_KEYDOWN:/*touches*/
                    {
                        if (event.key.keysym.sym == SDLK_SPACE)
                            pause=TRUE;
                        break;
                    }
                } /* fin de switch*/
        } /*fin d'acquisition*/

        if (pause)
        {/*pause et edition*/
            SDL_Flip(ecran);
            if (!fill_surface(ecran,tab,index))
                fin=TRUE;

            pause=FALSE;
        }

        index=maj_tableau(ecran, tab, index);

        SDL_Delay(100);

        SDL_Flip(ecran);

    } /* fin de boucle principale*/

    return (EXIT_SUCCESS);
}


constantes.h :
#ifndef CONSTANTES_H_INCLUDED
#define CONSTANTES_H_INCLUDED

#define LARG_TAB 100
#define HAUT_TAB 100
#define TAILLE_BLOCK 5 /* 5x5 pixels*/

typedef enum{FALSE=0,TRUE=1}BOOL;
typedef enum{MORT=0,VIE=1}ETAT;

#endif /* CONSTANTES_H_INCLUDED */


fonctions.h :
#ifndef FONCTIONS_H_INCLUDED
#define FONCTIONS_H_INCLUDED

void init_table(ETAT tab[2][LARG_TAB][HAUT_TAB]);

BOOL test_vie(ETAT tab[2][LARG_TAB][HAUT_TAB],int x,int y,BOOL index);

BOOL blit_vie(SDL_Surface *ecran,SDL_Rect *position);

BOOL test_mort(ETAT tab[2][LARG_TAB][HAUT_TAB],int x,int y,BOOL index);

BOOL blit_mort(SDL_Surface *ecran,SDL_Rect *position);

BOOL maj_tableau(SDL_Surface* ecran, ETAT tab[2][LARG_TAB][HAUT_TAB], BOOL index);

BOOL fill_surface(SDL_Surface *ecran,ETAT tab[2][LARG_TAB][HAUT_TAB],BOOL index);

#endif /* FONCTIONS_H_INCLUDED */


fonctions.c :
#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
#include "constantes.h"
#include "fonctions.h"

void init_table(ETAT tab[2][LARG_TAB][HAUT_TAB])
{/*vide le tableau*/
    unsigned int i,j,k;

    for (k=0;k<2;k++)
        for (j=0;j<HAUT_TAB;j++)
            for (i=0;i<LARG_TAB;i++)
                tab[k][j][i]=MORT;
}


BOOL test_vie(ETAT tab[2][LARG_TAB][HAUT_TAB],int x,int y,BOOL index)
{/*laisse la vie..ou pas*/

    BOOL retour=FALSE;

    int compte=0,/*nombre de cellules en vie*/
        i,j;

    for (i=(y-1);i<=(y+1);i++)
    {
        for (j=(x-1);j<=(x+1);j++)
        {
            if ((j>=0) && (i>=0) && !(i==y && j==x) && (j<LARG_TAB) && (i<HAUT_TAB))
            {
                if (tab[index][j][i]==VIE)
                    compte++;
            }
        }
    }

    if ((compte==2) || (compte==3))
        retour=TRUE;
/*
    printf("test_vie : compte=%d  retour=%d x=%d  y=%d\n",compte,retour,y,y);*/

    return(retour);
}


BOOL blit_vie(SDL_Surface *ecran,SDL_Rect *position)
{/*blit un pixel vivant*/

    BOOL retour=TRUE;

    if ((SDL_FillRect(ecran,position,SDL_MapRGB(ecran->format,255,255,255)))<0)
    {/*gestion de l'erreur*/
        printf("Err / blit_vie : erreur de colorisation en %d x %d :%s",position->x,position->y,SDL_GetError());
        retour=FALSE;
    }

    return(retour);
}


BOOL test_mort(ETAT tab[2][LARG_TAB][HAUT_TAB],int x,int y,BOOL index)
{/*redonne la vie...ou pas*/

    BOOL retour=FALSE;

    int compte=0,/*nombre de cellules en vie*/
        i,j;

    for (i=(y-1);i<=(y+1);i++)
    {
        for (j=(x-1);j<=(x+1);j++)
        {
            if ((j>=0) && (i>=0) && !(j==x && i==y) && (j<LARG_TAB) && (i<HAUT_TAB))
            {
                if (tab[index][j][i]==VIE)
                    compte++;
            }
        }
    }

    if (compte==3)
        retour=TRUE;
/*
    printf("test_mort : compte=%d  retour=%d x=%d y=%d\n",compte,retour,x,y);*/

    return(retour);
}


BOOL blit_mort(SDL_Surface *ecran,SDL_Rect *position)
{/*blit un pixel mort*/

    BOOL retour=TRUE;

    if ((SDL_FillRect(ecran,position,SDL_MapRGB(ecran->format,0,0,0)))<0)
    {/*gestion de l'erreur*/
        printf("Err / blit_mort : erreur de colorisation en %d x %d :%s",position->x,position->y,SDL_GetError());
        retour=FALSE;
    }

    return(retour);
}


BOOL maj_tableau(SDL_Surface* ecran, ETAT tab[2][LARG_TAB][HAUT_TAB], BOOL index)
{/*mise à jour de la table suivante et affichage de l'actuelle*/

    int i=0,j=0;

    BOOL nextTabIndex=(index^1),
    etatActuel=FALSE;

    SDL_Rect blitPos;
    blitPos.h=TAILLE_BLOCK;
    blitPos.w=TAILLE_BLOCK;

    for (i=0;i<HAUT_TAB;i++)
    {
        for(j=0;j<LARG_TAB;j++)
        {
            blitPos.x=j*TAILLE_BLOCK;
            blitPos.y=i*TAILLE_BLOCK;

            etatActuel=tab[index][j][i];

            if (etatActuel==VIE)
            {
                tab[nextTabIndex][j][i]=test_vie(tab,j,i,index);

                if (!blit_vie(ecran,&blitPos))
                    printf("Err / maj_tableau \n");
            }
            else
            {
                tab[nextTabIndex][j][i]=test_mort(tab,j,i,index);

                if (!blit_mort(ecran,&blitPos))
                printf("Err / maj_tableau \n");
            }
        }
    }
    return(nextTabIndex);
}


BOOL fill_surface(SDL_Surface *ecran,ETAT tab[2][LARG_TAB][HAUT_TAB],BOOL index)
{/*rempli l'écran manuellement*/

    BOOL fin=FALSE,
        retour=TRUE,
        leftBtDown=FALSE,
        rightBtDown=FALSE;
    SDL_Event event;
    SDL_Rect blitPos;
    int x,y;
    blitPos.x=blitPos.y=0;
    blitPos.h=blitPos.w=TAILLE_BLOCK;

    while(!fin)
    {
        SDL_WaitEvent(&event);

        switch (event.type)
        {
            case SDL_MOUSEBUTTONDOWN :

                x=event.button.x/TAILLE_BLOCK;
                y=event.button.y/TAILLE_BLOCK;
                blitPos.x=x*TAILLE_BLOCK;
                blitPos.y=y*TAILLE_BLOCK;

                switch (event.button.button)
                {

                    case SDL_BUTTON_LEFT :
                        leftBtDown=TRUE;
                        tab[index][x][y]=TRUE;
                        blit_vie(ecran,&blitPos);
                    break;

                    case SDL_BUTTON_RIGHT :
                        rightBtDown=TRUE;
                        tab[index][x][y]=FALSE;
                        blit_mort(ecran,&blitPos);
                    break;

                    default :
                    break;
                }
            break;

            case SDL_MOUSEBUTTONUP :

                switch (event.button.button)
                {
                    case SDL_BUTTON_LEFT :
                        leftBtDown=FALSE;
                    break;

                    case SDL_BUTTON_RIGHT :
                        rightBtDown=FALSE;
                    break;

                    default :
                    break;
                }
            break;

            case SDL_MOUSEMOTION :

                x=event.motion.x/TAILLE_BLOCK;
                y=event.motion.y/TAILLE_BLOCK;
                blitPos.x=x*TAILLE_BLOCK;
                blitPos.y=y*TAILLE_BLOCK;

                if (leftBtDown)
                {
                    tab[index][x][y]=TRUE;
                    blit_vie(ecran,&blitPos);
                }
                else if (rightBtDown)
                {
                    tab[index][x][y]=FALSE;
                    blit_mort(ecran,&blitPos);
                }

            break;

            case SDL_KEYDOWN :
                switch (event.key.keysym.sym)
                {
                    case SDLK_SPACE :
                        fin=TRUE;
                    break;

                    case SDLK_DELETE :
                        init_table(tab);

                        for (y=0;y<HAUT_TAB;y++)
                            for (x=0;x<LARG_TAB;x++)
                            {
                                blitPos.x=x*TAILLE_BLOCK;
                                blitPos.y=y*TAILLE_BLOCK;

                                blit_mort(ecran,&blitPos);
                            }
                        SDL_Flip(ecran);
                    break;

                    default :
                    break;
                }
            break;

            case SDL_QUIT :
                fin=TRUE;
                retour=FALSE;

            default :
            break;
        }

        SDL_Flip(ecran);
    }

    return(retour);
}


un vrai massacre, personne ne survie...

PS, soyez indulgeants, il y a ptet un truc en 4 lignes mais bon...

Edit : code corrigé @Mon ouïe : effectivement la case elle-même était prise en compte ^^ , merci ..

: une barre de 10 se maintien en mouvement...

Re-édit, c'est terrible ce truc... : trouvé par pur hasard : 2 fleurs animées il faut de la place autour (suis en 100*100):

Image utilisateur
et celui là envoi des "marcheurs" dans tous les sens :
Image utilisateur

Nouveaux Modules pour la CEV_lib : éditeur de map (tiles) + météo. Testez le rendu ici. w pour alterner météo.
12 septembre 2011 à 23:32:45

C’est parce qu’il y a une erreur dans ta fonction test_vie :
for (i=y-1;i<=y+1;i++)
        for (j=x-1;j<=x+1;j++)
        {
            if (j>=0 && i>=0 && j<LARG_TAB && i<LARG_TAB)
            {
                if (tab[j][i])
                    compte++;
            }
        }


Tu comptes la cellule (x, y) comme l’un de ses voisins vivants ; il faut seulement considérer les 8 cellules voisines, pas la cellule elle-même.
13 septembre 2011 à 18:35:12

Citation : GurneyH

Il me semble qu'il faut utiliser 2 tableaux.
C'est ce que j'ai fait en tout cas. :-°


Ah oui, effectivement, je n'y avais pas pensé, ça change tout en fait :p

Voici ma version corrigée (version 2 toujours, donc) :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>

#define COLS 640
#define ROWS 480
#define MODE SDL_HWSURFACE | SDL_DOUBLEBUF

#define FPS 25

int main(int argc, char ** argv) {
    SDL_Surface * screen;

    Uint32 black;
    Uint32 white;

    int grid[1 + COLS + 1][1 + ROWS + 1];

    int onclick = 0;
    int onpause = 0;
    int onclear = 0;
    int running = 1; 

/* init ------------------------------------------------------------- */
    if (SDL_Init(SDL_INIT_VIDEO) == -1) {
        fprintf(stderr, "fatal: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }
    
    if ((screen = SDL_SetVideoMode(COLS, ROWS, 32, MODE)) == NULL) {
        fprintf(stderr, "fatal: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    black = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF);
    white = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);

    SDL_WM_SetCaption("Game of Life", NULL);

    memset(grid, 0, sizeof grid);

    for (;;) {
        int x, y;
        SDL_Event event;

/* handle events ---------------------------------------------------- */
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_MOUSEBUTTONDOWN:
                    onclick = 1;
                    break;

                case SDL_MOUSEBUTTONUP:
                    onclick = 0;
                    break;

                case SDL_MOUSEMOTION:
                    x = 1 + event.motion.x;
                    y = 1 + event.motion.y;
                    break;

                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym) {
                        case SDLK_p:
                            onpause = 1;
                            break;

                        case SDLK_r:
                            onclear = 1;
                            break;

                        default:
                            ;
                    }
                    break;

                case SDL_QUIT:
                    goto quit;

                default:
                    ;
            }

/* process events --------------------------------------------------- */
            if (onclick) {
                grid[x][y] = 1;
            }

            if (onpause) {
                running ^= 1;

                if (running) {
                    SDL_WM_SetCaption("Game of Life", NULL);
                }
                else {
                    SDL_WM_SetCaption("Game of Life (paused)", NULL);
                }

                onpause = 0;
            }

            if (onclear) {
                memset(grid, 0, sizeof grid);

                onclear = 0;
            }
        }

/* update ----------------------------------------------------------- */
        if (running) {
            int temp[1 + COLS + 1][1 + ROWS + 1];

            memcpy(temp, grid, sizeof grid);

            for (x = 1; x < 1 + COLS; x++) {
                for (y = 1; y < 1 + ROWS; y++) {
                    int n = 0;

                    n += temp[x][y - 1];
                    n += temp[x][y + 1];
                    n += temp[x - 1][y];
                    n += temp[x + 1][y];
                    n += temp[x - 1][y - 1];
                    n += temp[x - 1][y + 1];
                    n += temp[x + 1][y - 1];
                    n += temp[x + 1][y + 1];

                    if (temp[x][y]) {
                        grid[x][y] = n == 2 || n == 3;
                    }
                    else {
                        grid[x][y] = n == 3;
                    }
                }
            }
        }

/* render ----------------------------------------------------------- */
        for (y = 1; y < 1 + ROWS; y++) {
            for (x = 1; x < 1 + COLS; x++) {
                Uint32 * pixel = (Uint32 *) screen->pixels;

                pixel += (y - 1) * screen->pitch / 4 + (x - 1);

                if (grid[x][y]) {
                    *pixel = black;
                }
                else {
                    *pixel = white;
                }
            }
        }

        SDL_Flip(screen);
        SDL_Delay(1000 / FPS);
    }

/* quit ------------------------------------------------------------- */
quit:
    SDL_Quit();
        
    (void) argc;
    (void) argv;

    return 0;
}

Toujours les mêmes touches, on peut répandre des cellules en cliquant avec la souris à tout moment, P pour mettre en pause, R pour effacer l'écran.

EDIT: petite optimisation...
13 septembre 2011 à 18:48:43

Ahhh c'est pas mal ça!
Par contre il y a le bug habituel qui fait que si je clique et que je me déplace assez vite bah ça ne me met qu'un point tout deux kilomètres...

Une cellule/un pixel jtrouve ça parfait!
Mais on devrait pouvoir zoomer pour voir vraiment ce qu'on fait.
Typiquement, là, j'aurais pas pu essayer de faire un U comme m'a dit yoch...
Mais bon jtrouve ça déjà excellent et ça me fait mal de dire d'un projet sans fonction :S

Par contre P pour faire Pause ça craint un peu, faut le chercher le P alors que la barre espace est beaucoup mieux pour ça j'pense, mais bon c'est un détail.

OMG comment c'est classe de faire une ligne droite!!!
13 septembre 2011 à 20:12:53

Citation : Mr21

Par contre il y a le bug habituel qui fait que si je clique et que je me déplace assez vite bah ça ne me met qu'un point tout deux kilomètres...


C'est dû au fait que l'event "déplacement souris" n'est pas forcément envoyé à chaque pixel de déplacement, lors d'un déplacement rapide. S'il faut gérer ça, suffit de tracer des traits à chaque fois (je serais d'ailleurs curieux de voir si la SDL peut rater un tracé de courbe ultra rapide dans ces conditions).
13 septembre 2011 à 20:17:40

Oui voilà exactement, il faut le drawline (premier exercice graphique qu'on fait à mon école ^^)

Dans notre cas, il faut garder en mémoire la position du dernier point et tracer la droite entre les deux.
Mais il est vrai que c'est un peu plus dur, mais ça rendra clairement mieux!

Et la SDL ne peux pas rater un trait car tu auras toujours les coordonnées du point d'avant (il faut un cas particulier pour le premier clique).
23 septembre 2011 à 15:57:08

Salut,

Je viens de finir le programme, je sais que je viens en retarde, mais c'est du au manque de temps, j'ai un/des projets en cours en plus du lycée.

Le code :

#include <stdio.h>
#include <time.h>
#include <SDL.h>

#define TAILLE 10
#define NOMBRE_BLOCS 50
#define FILE_NAME_S "save.gl"
#define FILE_NAME_L "load.gl"

int init();
SDL_Surface* creeFenetre(int largeur, int hauteur, int nbrCouleur, Uint32 arguments, char nomF[]);
SDL_Surface* creeBloc();
void afficheMap(char map[][NOMBRE_BLOCS], SDL_Surface* ecran, SDL_Surface* bloc);
void copieMap(char map[][NOMBRE_BLOCS], char map1[][NOMBRE_BLOCS]);
void generateMap(char map[][NOMBRE_BLOCS], int choix);
void teste(char map[][NOMBRE_BLOCS], char map1[][NOMBRE_BLOCS]);
void Save(char map[][NOMBRE_BLOCS]);
void Load(char map[][NOMBRE_BLOCS]);

int main ( int argc, char** argv )
{
    SDL_Surface *ecran = NULL, *bloc = NULL;
    SDL_Event event;
    char map[NOMBRE_BLOCS][NOMBRE_BLOCS];
    char map1[NOMBRE_BLOCS][NOMBRE_BLOCS];
    int continuer = 1, delay = 100, delay1 = 0, etat = 0;

    srand(time(NULL));
    init();
    ecran = creeFenetre(TAILLE * NOMBRE_BLOCS, TAILLE * NOMBRE_BLOCS, 32, SDL_HWSURFACE, "Jeu De La Vie");
    bloc = creeBloc();

    generateMap(map, -1);
    copieMap(map, map1);
    SDL_EnableKeyRepeat(0, 0);
    while(continuer)
    {
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT :
                continuer = 0;
                break;
                case SDL_MOUSEBUTTONUP :
                if(!etat && event.button.button == SDL_BUTTON_LEFT)
                {
                    map[event.button.x / TAILLE][event.button.y / TAILLE] ^= 1;
                    map1[event.button.x / TAILLE][event.button.y / TAILLE] ^= 1;
                }
                else if(etat && (event.button.button == SDL_BUTTON_WHEELUP || event.button.button == SDL_BUTTON_WHEELDOWN))
                {
                    delay += event.button.button == SDL_BUTTON_WHEELUP ? (delay > 0 ? -1 : 0) : +1;
                }
                break;
                case SDL_KEYDOWN :
                switch(event.key.keysym.sym)
                {
                    case SDLK_p :
                    etat ^= 1;
                    break;
                    case SDLK_SPACE :
                    SDL_SaveBMP(ecran, "screen.bmp");
                    break;
                    case SDLK_KP1 :
                    if(!etat)
                    {
                        generateMap(map, 1);
                        copieMap(map, map1);
                    }
                    break;
                    case SDLK_KP0 :
                    if(!etat)
                    {
                        generateMap(map, 0);
                        copieMap(map, map1);
                    }
                    break;
                    case SDLK_KP2 :
                    if(!etat)
                    {
                        generateMap(map, -1);
                        copieMap(map, map1);
                    }
                    break;
                    case SDLK_s :
                    Save(map);
                    break;
                    case SDLK_l :
                    if(!etat)
                    {
                        Load(map);
                        copieMap(map, map1);
                    }
                    break;
                    default :
                    ;
                    break;
                }
                break;
                default :
                ;
                break;
            }
        }
    if(etat)
    teste(map, map1);
    afficheMap(map, ecran, bloc);
    SDL_Delay(etat ? delay : delay1);
    }

    SDL_FreeSurface(bloc);
    return EXIT_SUCCESS;
}

int init()
{

    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "Erreur d'initialisation de la SDL: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }
    atexit(SDL_Quit);

    return 0;
}

SDL_Surface* creeFenetre(int largeur, int hauteur, int nbrCouleur, Uint32 arguments, char nomF[])
{
    SDL_Surface* ecran = NULL;

    ecran = SDL_SetVideoMode(largeur, hauteur, nbrCouleur, arguments);
    SDL_WM_SetCaption(nomF, NULL);

    if(!ecran)
    {
        fprintf(stderr, "Erreur de creation de la fenetre : %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    return ecran;
}

SDL_Surface* creeBloc()
{
    SDL_Surface* bloc = NULL;
    SDL_Rect parti;
    int i;

    parti.h = parti.w = TAILLE;
    parti.y = 0;

    bloc = SDL_CreateRGBSurface(SDL_HWSURFACE, TAILLE * 2, TAILLE, 32, 0, 0, 0,0);
    if(!bloc)
    {
        fprintf(stderr, "Erreur de creation de l'allocation d'une surface : %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }
    for(i = 0; i < 2; i++)
    {
        parti.x = i * TAILLE;
        SDL_FillRect(bloc, &parti, ~(0xffffff * i));
    }

    return bloc;
}

void afficheMap(char map[][NOMBRE_BLOCS], SDL_Surface* ecran, SDL_Surface* bloc)
{
    SDL_Rect parti, pos;
    int i, j;

    parti.y = 0;
    parti.w = parti.h = TAILLE;

    for(i = 0; i < NOMBRE_BLOCS; i++)
    {
        for(j = 0; j < NOMBRE_BLOCS; j++)
        {
            parti.x = map[i][j] * TAILLE;
            pos.x = i * TAILLE;
            pos.y = j * TAILLE;
            SDL_BlitSurface(bloc, &parti, ecran, &pos);
        }
    }
    SDL_Flip(ecran);
}

void copieMap(char map[][NOMBRE_BLOCS], char map1[][NOMBRE_BLOCS])
{
    int i, j;

    for(i = 0; i < NOMBRE_BLOCS; i++)
        for(j = 0; j < NOMBRE_BLOCS; j++)
            map1[i][j] = map[i][j];

}

void generateMap(char map[][NOMBRE_BLOCS], int choix)
{
    int i, j;

    for(i = 0; i < NOMBRE_BLOCS; i++)
        for(j = 0; j < NOMBRE_BLOCS; j++)
            map[i][j] = choix >= 0 ? choix : rand() % 2;
}

void teste(char map[][NOMBRE_BLOCS], char map1[][NOMBRE_BLOCS])
{
    int i, j, k, l, nbr_voisine_vivante;

    for(i = 0; i < NOMBRE_BLOCS; i++)
    {
        for(j = 0; j < NOMBRE_BLOCS; j++)
        {
            nbr_voisine_vivante = 0;
            for(k = -1; k < 2; k++)
                for(l = -1; l < 2; l++)
                    if((k != 0 || l != 0) && (i != 0 || k != (-1)) && (i != NOMBRE_BLOCS-1 || k != 1) && (j != 0 || l != (-1)) && (j != NOMBRE_BLOCS-1 || l!= 1))
                        nbr_voisine_vivante += map1[i+k][j+l];

            map[i][j] = (map1[i][j] && (nbr_voisine_vivante == 2 || nbr_voisine_vivante == 3)) || !map1[i][j] && nbr_voisine_vivante == 3 ? 1 : 0;
        }
    }
    copieMap(map, map1);
}

void Save(char map[][NOMBRE_BLOCS])
{
    FILE * save;
    int i, j;

    save = fopen(FILE_NAME_S, "w");
    if(save)
    {
        for(i = 0; i < NOMBRE_BLOCS; i++)
        {
            for(j = 0; j < NOMBRE_BLOCS; j++)
            fputc(map[i][j], save);
            if(i < NOMBRE_BLOCS-1)
            fputc('\n', save);
        }

        fclose(save);
    }
}

void Load(char map[][NOMBRE_BLOCS])
{
    FILE * load;
    int i, j;

    load = fopen(FILE_NAME_L, "r");
    if(load)
    {
        for(i = 0; i < NOMBRE_BLOCS; i++)
        {
            for(j = 0; j < NOMBRE_BLOCS; j++)
            map[i][j] = fgetc(load);
            fgetc(load);
        }

        fclose(load);
    }
}



Utilisation :
P : mettre en Pause/Relancer
ESPACE : Prendre un screen
0 : Effacer l’écran (Uniquement en mode Pause)
1 : Remplir Tout l’écran avec des cellules vivantes (Uniquement en mode Pause)
2 : Remplir l'écran aléatoirement (Uniquement en mode Pause)
La mollette de la souris : accélérée/ralentir (Uniquement en Mode Play)
s : Sauvegarder dans un fichier .gl (par default save.gl)
l : Lire un fichier .gl (par default load.gl)

Pour la fonction Load : je dois la modifier pour qu'elle soit utilisable pour une grille de n'importe quelle taille.
La grille est rempli aléatoirement au lancement du programme.
6 novembre 2016 à 18:30:21

Désolé pour le déterrage, j'ai commencé le C il y a 6 jours.

voici mon code, il démarre en pause, merci pour vos conseils.

p = pause/reprise

esc = quitter

mouse+clic-gauche = ajouter cellules

#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <time.h> 



typedef struct cellule cellule;
typedef struct petri petri;


SDL_Surface* screen;
SDL_Event event;
char pause;
int numcell;
int nait;
int meurt;

struct cellule
	{
	int x;
	int y;
	char status;
	char compteur;
	cellule* next;
	};
	

struct petri
	{
	int width;
	int height;
	cellule* listCell;
	cellule** table;
	};


SDL_Surface* setMode(int w, int h)
	{
	if(SDL_Init(SDL_INIT_VIDEO)==-1){exit(EXIT_FAILURE);}
	return SDL_SetVideoMode(w, h , 32, SDL_HWSURFACE);
	}


void putpixel(SDL_Surface* screen, int x, int y)
	{
	Uint8 *p = (Uint8 *)screen->pixels + y * screen->pitch + x * 4;
	*(Uint32 *)p = SDL_MapRGB(screen->format, 200, 200, 200);
	}
	
petri* setPetri(int width, int height)
	{
	screen	       = setMode(width,height);
	width = screen->w;
	height = screen->h;
	petri* culture     = malloc(sizeof(petri));
	culture->listCell  = NULL;
	culture->table     = malloc((long unsigned)width*sizeof(cellule*));
	int xx, yy;
	for(xx=0;xx<width;xx++)
		{
		culture->table[xx] = malloc((long unsigned)height*sizeof(cellule));
		for(yy=0;yy<height;yy++)
			{
			culture->table[xx][yy].x	= xx;
			culture->table[xx][yy].y	= yy;
			culture->table[xx][yy].status	= 0;
			culture->table[xx][yy].compteur	= 0;
			culture->table[xx][yy].next	= NULL;
			}
		}
	culture->width  = width;
	culture->height = height;
	return culture;
	}

void setCellule(petri *culture, int x, int y)
	{
	culture->table[x][y].compteur = 0;
	if(culture->table[x][y].status==0)
		{
		culture->table[x][y].status = 1;
		culture->table[x][y].next = culture->listCell;
		culture->listCell = &culture->table[x][y];
		}
	}

void updateCell(petri *culture, int x, int y)
	{
	if(x>=0 && x<culture->width && y>=0 && y<culture->height)
		{
		if(!culture->table[x][y].status && !culture->table[x][y].compteur)
			{
			culture->table[x][y].next = culture->listCell;
			culture->listCell = &culture->table[x][y];
			}
		culture->table[x][y].compteur++;
		}
	}


void update(petri *culture)
	{
	cellule* alive = culture->listCell;
	cellule* tmp   = culture->listCell;
	numcell = 0;
	nait = 0;
	meurt = 0;
	while(tmp!=NULL)
		{
		updateCell(culture,tmp->x,tmp->y+1);
		updateCell(culture,tmp->x,tmp->y-1);
		updateCell(culture,tmp->x+1,tmp->y);
		updateCell(culture,tmp->x-1,tmp->y);
		updateCell(culture,tmp->x+1,tmp->y+1);
		updateCell(culture,tmp->x+1,tmp->y-1);
		updateCell(culture,tmp->x-1,tmp->y+1);
		updateCell(culture,tmp->x-1,tmp->y-1);
		tmp = tmp->next;
		}
	tmp = culture->listCell;
	cellule** tmp0 = &culture->listCell;
	while(tmp!=alive)
		{
		if(tmp->compteur==3)
			{
			tmp->status = 1;
			tmp->compteur = 0;
			*tmp0 = tmp;
			tmp0 = &tmp->next;
			numcell++;
			putpixel(screen,tmp->x, tmp->y);
			}
		else
			{
			culture->table[tmp->x][tmp->y].status   = 0;
			culture->table[tmp->x][tmp->y].compteur = 0;
			}
		nait = numcell;
		tmp = tmp->next;
		}
	while(tmp!=NULL)
		{
		if(tmp->compteur==2||tmp->compteur==3)
			{
			tmp->compteur = 0;
			*tmp0 = tmp;
			tmp0 = &tmp->next;
			numcell++;
			putpixel(screen,tmp->x, tmp->y);
			}
		else
			{
			culture->table[tmp->x][tmp->y].status   = 0;
			culture->table[tmp->x][tmp->y].compteur = 0;
			meurt++;
			}
		tmp = tmp->next;
		}
	*tmp0 = NULL;
	SDL_Flip(screen);
	SDL_FillRect(screen, NULL, 0);
	}
 
void generation(petri *culture)
	{
	pause = 1;
	int gen = 0;
	while(1)
		{
		while(SDL_PollEvent(&event))
			{
			if(event.type==SDL_KEYDOWN)
				{
				switch(event.key.keysym.sym)
					{
					case SDLK_p:
						pause ^= 1;
						break;
					case SDLK_ESCAPE:
						return;
						break;
					default:
						break;
					}
				}
			else if(event.type==SDL_MOUSEMOTION && event.motion.state==SDL_BUTTON_LEFT)
				{
				setCellule(culture,event.motion.x,event.motion.y);
				putpixel(screen,event.motion.x, event.motion.y);
				SDL_UpdateRect(screen,event.motion.x, event.motion.y,1,1);
				}
			else if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT)
				{
				setCellule(culture,event.button.x,event.button.y);
				putpixel(screen,event.button.x, event.button.y);
				SDL_UpdateRect(screen,event.button.x, event.button.y,1,1);
				}
			}
		if(pause==0)
			{
			printf("gen %d : total %d : naiss %d : deces %d\n",gen,numcell,nait,meurt);
			update(culture);
			gen++;
			}
		}
	}
	
void terminus(petri *culture)
	{
	int i;
	for(i=0;i<culture->width;i++)
		{
		free(culture->table[i]);
		}
	free(culture->table);
	free(culture);
	SDL_Quit();
	}


int main()
	{
	srand ((unsigned int)time (NULL));
	printf("%p",&terminus);
	petri* culture = setPetri(600,400);
	//~ int w=culture->width, h=culture->height;
	//~ int i;
	//~ for(i=0;i<w*h;i++)
		//~ {
		//~ int x = rand()%w;
		//~ int y = +rand()%h;
		//~ setCellule(culture,x,y);
		//~ }
	generation(culture);
	terminus(culture);
	return 0;
	}



-
Edité par josmiley 23 novembre 2016 à 8:07:17

[FAIT][Défis] #2 : Le jeu de la vie !

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
  • Editeur
  • Markdown