Accueil > > > KAKURO
KAKURO
Information sur la source
Description
Voila, je bosse sur un projet pour mes cours de programmation. Le premier projet consistait en une grille statique realisée correctement. Pour le second projet, mon prof veut un tableau dynamique. Je crois que j'en suis pas loin mais ca plante pour l'affichage et paf l'erreur habituelle "Erreur de segmentation". Vous pouvez tester le code en mettant en commentaire de la ligne 82 et la ligne 100 et la miracle ca marche. Mais ca ne m'arrange pas du tout puisque mes cases sont vides :(. Je sais que j'ai defini ici ma taille du tableau par nx,ny mais je dois en fait recuperer la taille en lisant la grille du kakuro, et la aussi je seche, j'utilise un "sscanf" pour lire dans le fichier, il me recupère bien la valeur mais ne l'attribue pas. Dans un premier temps, je cherche uniquement a resoudre mon problème d'affichage car après vérification, la memoire est belle est bien allouée. Bon, ne jugez pas mon code lol, je suis novice en programmation et je trouve que le prof a fait un peu fort de demander un kakuro pour des premières années, mais je debrouille meme si parfois je pourrais faire un meilleur codage. Je vous remercie a tous d'avance. Je joinds le zip comme ca vous avez une grille, donc quand vous jouer, vous tapez 1 puis 1 et encore 1 car c'est la grille11.txt
Source
- #include<stdio.h>
- #include<stdlib.h>
- #include"couleurs.h"
-
- typedef struct element
- {
- char type;
- int val[2];
- int attrib;
- }grille;
-
- /* Explication de la fonction INIT */
- /* Fonction servant a initialiser le tableau pour eviter des problemes d'allocation */
- /* de valeur dans les cases, pouvant causer des erreurs */
-
- void init(int nx,int ny,grille **tab)
- {
- int x,y;
- for(x=0;x<nx;x++)
- {
- for(y=0;y<ny;y++)
- {
- tab[x][y].type='Z';
- tab[x][y].val[0]=0;
- tab[x][y].val[1]=0;
- tab[x][y].attrib=-1;
- }
- }
- }
-
- /* Explication de la fonction AFFICHAGE */
- /* En fonction du type attribue a chaque case, un affichage se distinque par le switch */
- /* Le "default" equivalant aux cases blanches non-codees */
-
- void affichage(int nx,int ny,grille **tab)
- {
- int x,y,x2;
- printf("\033[H\033[2J");
- for(x=0;x<nx+1;x++)
- {
- couleur("31");
- printf("+-----");
- if(x==nx)
- {
- printf("+\n");
- }
- }
- for(x=0;x<nx;x++)
- {
- if(x==0)
- {
- printf("| ");
- }
- printf("| %2d ",x);
- if(x==nx-1)
- {
- printf("|\n");
- }
- }
- for(x=0;x<nx;x++)
- {
- for(x2=0;x2<nx+1;x2++)
- {
- couleur("31");
- printf("+-----");
- if(x2==nx)
- {
- printf("+\n");
- }
- }
- for(y=0;y<ny;y++)
- {
- if(y==0)
- {
- couleur("31");
- printf("| %2d ",x);
- couleur("0");
- }
- couleur("31");
- printf("|");
- couleur("0");
- switch (tab[x][y].type)
- {
- case 'D' : couleur("36");
- printf("%2d\\%2d",tab[x][y].val[1],tab[x][y].val[0]);
- couleur("0");
- break;
- case 'N' : couleur("32");
- printf("*****");
- couleur("0");
- break;
- case 'P' : couleur("33");
- printf(" %2d ",tab[x][y].val[0]);
- couleur("0");
- break;
- case 'B' : printf(" %2d ",tab[x][y].val[0]);
- break;
- default : printf(" ");
- break;
- }
- }
- couleur("31");
- printf("|\n");
- couleur("0");
- }
- for(x=0;x<nx+1;x++)
- {
- couleur("31");
- printf("+-----");
- if(x==nx)
- {
- printf("+\n");
- }
- couleur("0");
- }
- }
-
- /* Explication de la fonction LOAD */
- /* Fonction de lecture du fichier */
- /* Lecture du fichier a partir de la commande FGETS */
- /* Lecture ligne par ligne */
- /* En fonction du premier caractere, je peux definir le masque pour la commande SSCANF et */
- /* Ainsi recupere les differentes valeurs correspondant au type de la case, on rempli la structure */
- /* et on termine en fermant le fichier */
-
- void chargement(long int nx,long int ny,grille **tab,char fichier[20])
- {
- char type,temp[14];
- int ligne,colonne,valeur1,valeur2,i,j;
- int compteur=0,drap=0;
- FILE *jeu;
- jeu=fopen(fichier,"r");
- if(jeu==NULL)
- {
- printf(" \n Fichier non charge \n");
- }
- else
- {
- printf(" Fichier %s charge \n",fichier);
-
- /* Fonction de lecture du fichier. */
- /* Attrib est specifique de ce que je peux faire, */
- /* 0 affecte aux cases definitions, impossible de faire une action dessus. */
- /* 1 affecte aux cases noires, impossible de faire une action dessus. */
- /* -1 affecte aux cases blanches(Z), possibilite d'agir dessus */
- /* 3 affecte aux cases predifinies, case remplie par le joueur, impossible d'agir dessus sauf en supprimant la valeur, */
- /* et reaffectant la case en case blanche(Z) voir plus bas dans supprimvaleur */
-
- while(!feof(jeu))
- {
- fgets(temp,14,jeu);
- if(drap==0)
- {
- tab=(grille **)malloc(nx * sizeof(grille *));
- if(tab==NULL)
- {
- printf("\n Echec lors de l'allocation memoire!!!");
- }
- printf("La memoire allouee est de %d ",sizeof(grille*));
- for(i=0;i<nx;i++)
- {
- tab[i] = (grille *)malloc(ny * sizeof(grille));
- printf("La memoire allouee est de %d\n",sizeof(grille));
- if (tab[i] == NULL)
- {
- for (j=0;j<ny;j++)
- {
- printf("%d",j);
- free(tab[j]);
- printf("\n Echec lors de l'allocation memoire!!!");
- }
- }
- }
- drap=1;
- }
- if(temp[0]=='D')
- {
- sscanf(temp,"%c %d %d %d %d",&type,&ligne,&colonne,&valeur1,&valeur2);
- tab [ligne][colonne].attrib=0;
- tab [ligne][colonne].type=type;
- tab [ligne][colonne].val[0]=valeur1;
- tab [ligne][colonne].val[1]=valeur2;
- }
- if(temp[0]=='N')
- {
- sscanf(temp,"%c %d %d",&type,&ligne,&colonne);
- tab [ligne][colonne].type=type;
- tab [ligne][colonne].attrib=1;
- }
- if(temp[0]=='B')
- {
- tab[ligne][colonne].attrib=-1;
- }
- if(temp[0]=='P')
- {
- sscanf(temp,"%c %d %d %d",&type,&ligne,&colonne,&valeur1);
- tab [ligne][colonne].type=type;
- tab [ligne][colonne].val[0]=valeur1;
- tab [ligne][colonne].attrib=3;
- }
- compteur++;
- }
- fclose(jeu);
- }
-
- }
-
- /* Explication de la fonction SAUVEGARDE */
- /* Fonction de sauvegarde du jeu */
- /* On ouvre un fichier en ecriture, et ecrase l'ancien s'il y en a deja un nomme comme cela */
- /* et on enregistre les donnees dedans */
- /* Enregistrement case par case dans un fichier texte au meme format que les grilles de depart */
-
- void sauvegarde(int nx,int ny,grille **tab,char fichier[20])
- {
- int x,y;
- FILE *savegame;
- char nom_fic[20];
- printf("Veuillez entrer le nom du fichier : ");
- fgets(nom_fic,20,savegame);
- savegame=fopen(nom_fic,"w");
- if(savegame==NULL)
- {
- printf("Fichier non sauvegarde");
- }
- else
- {
- for(x=0;x<nx;x++)
- {
- for(y=0;y<ny;y++)
- {
- if(tab[x][y].type=='D')
- {
- fprintf(savegame,"%c %d %d %d %d\n",tab[x][y].type,x,y,tab[x][y].val[0],tab[x][y].val[1]);
- }
- if(tab[x][y].type=='B'||tab[x][y].type=='N')
- {
- fprintf(savegame,"%c %d %d\n",tab[x][y].type,x,y);
- }
- if(tab[x][y].type=='P')
- {
- fprintf(savegame,"%c %d %d %d\n",tab[x][y].type,x,y,tab[x][y].val[0]);
- }
- }
- }
- }
- }
-
- /* Explication de la fonction VERIFREGLE*/
- /* Fonction de verification pour les lignes horizontales */
- /* Premierement, on cherche la valeur de la case definition correspondant a la ligne */
- /* Dont la valeur fait partie, de la on sait d'ou notre verification doit partir (valeur DEPART) */
- /* Ensuite, on demarre du DEPART, on teste si la valeur se trouve deja sur la ligne */
- /* Si elle se trouve sur la ligne, on retourne directement 0 */
- /* Si la valeur ne se trouve pas sur la ligne, on verifie que la case est soit Blanche, soit Predefinie */
- /* Si elle l'est, alors on fait la somme de la valeur actuelle avec les valeurs precedentes. */
- /* Si a un moment donne, la colonne est differente de DEPART et que les cases sont differentes de B ou P */
- /* On a une case vide en plus de celle que l'on veut attribuer et donc cela ne sert a rien de tester la somme */
- /* En fin de fonction, on verifie les deux cas possibles et on retourne 1 si c'est possible ou 0 si ca ne l'est pas */
-
- int verifregle(int nx,int ny,grille **tab,int ligne,int colonne,int valeur)
- {
- int test=0,co,somme=valeur;
- int depart,def,echec=1;
- co=colonne;
- while(test==0)
- {
- if(tab[ligne][co-1].type=='D')
- {
- def=tab[ligne][co-1].val[0];
- depart=co;
- test=1;
- }
- co--;
- }
- for(depart=depart;depart<nx&&tab[ligne][depart].type!='N'&&tab[ligne][depart].type!='D';depart++)
- {
- if(valeur!=tab[ligne][depart].val[0])
- {
- if(tab[ligne][depart].type=='P'||tab[ligne][depart].type=='B')
- {
- somme=somme+tab[ligne][depart].val[0];
- }
- else if(colonne!=depart)
- echec=0;
- }
- else
- {
- return 0;
- }
- }
- if( (echec==1&&somme==def)||(echec==0&&somme<def))
- return 1;
- else
- return 0;
- }
-
- /* Explication de la fonctoion VERIFREGLE2 */
- /* Fonction de verification pour les lignes verticales */
- /* Premierement, on cherche la valeur de la case definition correspondant a la colonne */
- /* Dont la valeur fait paretie, de la sait d'ou notre verification doit partir (valeur DEPART) */
- /* Ensuite, on demarre du DEPART, on teste si la valeur se trouve deja sur la colonne */
- /* Si elle se trouve sur la ligben on retourne directement 0 */
- /* Si la valeur ne se trouve pas sur la colonne, on verifie que la case est soit Blanche, soit Predefinie */
- /* Si elle l'est, alors on fait la somme de la valeur actuelle avec les valeurs precedentes. */
- /* Si a un moment donne, la ligne est differente de DEPART et que les cases sont differentes de B ou de P */
- /* On a une case videen plus de celle que l'on veut attribuer et donc cela ne sert a rien de tester la somme */
- /* En fin de fonction, on verifie les deux cas possibles et on retourne 1 si c'est possible ou 0 si ca ne l'est pas */
-
- int verifregle2(int nx,int ny,grille **tab,int ligne,int colonne,int valeur)
- {
- int test=0;
- int somme=valeur;
- int def,echec=1,depart,li;
- li=ligne;
- while(test==0)
- {
- if(tab[li-1][colonne].type=='D')
- {
- def=tab[li-1][colonne].val[1];
- depart=li;
- test=1;
- }
- li--;
- }
- for(depart=depart;depart<ny&&tab[depart][colonne].type!='N'&&tab[depart][colonne].type!='D';depart++)
- {
- if(valeur!=tab[depart][colonne].val[0])
- {
- if(tab[depart][colonne].type=='P'||tab[depart][colonne].type=='B')
- somme=somme+tab[depart][colonne].val[0];
- else if(ligne!=depart)
- echec=0;
- }
- else
- {
- return 0;
- }
- }
- if((echec==1&&somme==def)||(echec==0&&somme<def))
- return 1;
- else
- return 0;
- }
-
- /* Explication de BACKTRACKING */
- /* Ne fonctionne pas correctement, plante sur la grille 32,34,35 */
-
- int backtracking(int nx,int ny,grille **tab, int lig, int colo)
- {
- int i=1;
- if(colo==ny)
- {
- lig=lig+1;
- colo=0;
- }
- while(tab[lig][colo].type=='D'||tab[lig][colo].type=='N'||tab[lig][colo].type=='P') /* Test pour voir le type de ligne */
- {
- colo++; /* Tant que c'est un des types test, on avance dans la colonne */
- if(colo==ny) /* Si on arrive en fin de colonne, on avance d'une ligne et on reviens a la case 0 de la colonne */
- {
- lig=lig+1;
- colo=0;
- }
- }
- if((colo==0&&lig==nx)||(colo==ny&&lig==nx)) /*Sert a verifier que je suis a la fin du tableau*/
- return 1;
- else
- {
- while(i<10) /* Test tant que i est plus que 10 */
- /* Si les 2 regles sont verifiees, on change le type de */
- /* en case Blanche, on affecte la valeur de i a la case */
- /* Ensuite on teste ce que la fonction et la colonne */
- /* renvoie */
- /* Sinon on reaffecte un type vide a la case ainsi que la */
- /* valeur 0 */
- /* On incremente le compteur et on recommence */
- {
- if(verifregle(nx,ny,tab,lig, colo,i)==1 && verifregle2(nx,ny,tab,lig, colo,i)==1)
- {
- tab[lig][colo].type='B';
- tab[lig][colo].val[0]=i;
- if(backtracking(nx,ny,tab, lig,colo+1)==1)
- return 1;
- }
- else
- {
- tab[lig][colo].type='Z';
- tab[lig][colo].val[0]=0;
- }
- i++;
- tab[lig][colo].type='Z';
- tab[lig][colo].val[0]=0;
- }
- return 0;
- }
- }
- void resolutionautomatique(int nx,int ny,grille **tab)
- {
- int colo=0,lig=0;
- /*fonction qui me permet de trouver le depart */
- if( backtracking(ny,nx,tab, colo, lig)==1 )
- printf("Solution possible\n");
- else
- printf("solution impossible\n");
- }
-
- /* Explication de la fonction JEU */
- /* Introduction des coordonnees de la case par le joueur */
- /* Fonction de test de valeur introduite par le joueur */
- /* Test de la case pour savoir si celle ci est libre ( type Z ) ou si elle correspond a un autre type */
- /* Si la case est libre, introduction de la valeur par le joueur puis test de la valeur entree avec les */
- /* fonction VERIFREGLE et VERIFREGLE2 */
- /* Si test ok, la valeur est encodee, sinon on refais la boucle */
-
- void jeu(int nx,int ny,grille **tab)
- {
- int ligne,colonne,valeur,test;
- do
- {
- printf("Veuillez entrer le numero de la ligne : \n");
- scanf("%d",&ligne);
- printf("Veuillez entrer le numero de la colonne : \n");
- scanf("%d",&colonne);
- if(tab[ligne][colonne].attrib==0)
- {
- test=0;
- affichage(nx,ny,tab);
- couleur("1;31");
- printf("Ceci est une case definition \n");
- couleur("0");
- }
- if(tab[ligne][colonne].attrib==1)
- {
- test=0;
- affichage(nx,ny,tab);
- couleur("1;31");
- printf("Ceci est une case noire \n");
- couleur("0");
- }
- if(tab[ligne][colonne].attrib==3)
- {
- test=0;
- affichage(nx,ny,tab);
- couleur("1;31");
- printf("Cette case a deja ete remplie par le joueur \n");
- couleur("0");
-
- }
- if(tab[ligne][colonne].attrib==-1)
- {
- printf("Veuillez introduire votre valeur comprise entre 1 et 9 inclus : \n");
- scanf("%d",&valeur);
- if(valeur>0&&valeur<10)
- {
- if(verifregle(nx,ny,tab,ligne,colonne,valeur)==0||verifregle2(nx,ny,tab,ligne,colonne,valeur)==0)
- {
- affichage(nx,ny,tab);
- couleur("1;31");
- printf("Cette valeur se trouve deja sur la ligne et/ou la colonne, ou la somme n'est pas correcte \n");
- couleur("0");
- test=0;
- }
- else
- {
- tab[ligne][colonne].type='P';
- tab[ligne][colonne].val[0]=valeur;
- tab[ligne][colonne].attrib=3;
- test=1;
- }
- }
- else
- {
- couleur("1;31");
- printf("La valeur introduire n'est pas comprise dans la fourchette\n");
- printf("Veuillez recommencer\n");
- couleur("0");
- }
- }
- }
- while(test==0);
- }
-
- /* Explication de la fonction SUPPRIMVALEUR */
- /* Fonction pour supprimer la valeur d'une case */
- /* Meme test que pour la fonction JEU, pour ne pas effacer n'importe quoi */
- /* Si case ok, la valeur est supprimee et on repasse la case en type Z pour pouvoir reecrire dedans par la suite */
- /* J'etais d'abord passe par une fonction pour modifier la valeur plutot que de la supprimer, mais cela pose */
- /* des problemes au niveau des regles de verification */
-
- void supprimvaleur(int nx,int ny,grille **tab)
- {
- int ligne,colonne,valeur,test;
- do
- {
- printf("Veuillez entrer le numero de la ligne : \n");
- scanf("%d",&ligne);
- printf("Veuillez entrer le numero de la colonne : \n");
- scanf("%d",&colonne);
- if(tab[ligne][colonne].attrib==-1)
- {
- affichage(nx,ny,tab);
- printf("Il n'y a rien a supprimer ici ici \n" );
- test=0;
- }
- if(tab[ligne][colonne].attrib==0)
- {
- affichage(nx,ny,tab);
- printf("Ceci est une case definition \n");
- test=0;
- }
- if(tab[ligne][colonne].attrib==1)
- {
- affichage(nx,ny,tab);
- printf("Ceci est une case noire \n");
- test=0;
- }
- if(tab[ligne][colonne].attrib==3)
- {
- tab[ligne][colonne].type='Z';
- tab[ligne][colonne].val[0]=valeur;
- tab[ligne][colonne].attrib=-1;
- printf("La valeur a ete supprimee \n");
- test=1;
- }
- }
- while(test==0);
-
- }
-
-
-
- /* Explication de la fonction AIDE */
- /* Fonction pour l'aide sur les valeurs possibles que peut prendre une case */
- /* Introduction par le joueur des coordonnees de la case */
- /* Test des valeurs de 1 a 9 par les fonctions VERIFREGLE et VERIFREGLE2 */
- /* Les valeurs retournees sont celles qui sont possibles d'introduire */
-
- void aide(int nx,int ny,grille **tab, int ligne, int colonne)
- {
- int i;
- printf("Solution possible : ");
- for(i=1;i<10;i++)
- {
- if(verifregle(nx,ny,tab,ligne,colonne,i)==1&&verifregle2(nx,ny,tab,ligne,colonne,i)==1)
- {
- printf("%d est une valeur possible pour cette case \n", i);
- }
- }
- printf("\n");
- }
-
- /* Explication de la fonction MENU2 */
- /* Menu de JEU avec la grille */
- /* 1. Entrer une valeur, permet d'entrer une valeur en appelant la fonction JEU */
- /* 2. Supprimer une valeur, supprimer la valeur d'une case en appelant la fonction SUPPRIMVALEUR */
- /* 3. Demander de l'aide, introduction des coordonnees par le joueur puis appel de la fonction AIDE */
- /* 4. Resolution automatique, appel de la fonction resolutionautomatique ( BACKTRACKING ) */
- /* 5. Sauvegarde de la partie, enregistre la partie dans un fichier txt en appelant la fonction SAUVEGARDE */
- /* 6. Retour, retour au menu principal */
-
- void menu2(int nx,int ny,grille **tab)
- {
- int ligne,colonne;
- char choix2;
- char fichier[20]="";
- do
- {
- affichage(nx,ny,tab);
- couleur("1;34");
- printf("***** MENU DU JEU *****\n");
- couleur("0");
- couleur("31");
- printf("-----------------------\n");
- couleur("0");
- printf("Que voulez-vous faire ?\n"
- "1.Entrer une valeur\n"
- "2.Supprimer une valeur\n"
- "3.Demander de l'aide\n"
- "4.Resolution automatique\n"
- "5.Sauvegarde de la partie\n"
- "6.Retour\n");
- do
- choix2=getchar();
- while((int)choix2<49||(int)choix2>55);
- switch ((int)choix2)
- {
- case 49 : jeu(nx,ny,tab);
- break;
- case 50 : supprimvaleur(nx,ny,tab);
- break;
- case 51 : printf("Entrez le numero de la ligne : \n");
- scanf("%d",&ligne);
- printf("Entrez le numero de la colonne : \n");
- scanf("%d",&colonne);
- aide(nx,ny,tab,ligne,colonne);
- break;
- case 52 : resolutionautomatique(nx,ny,tab);
- break;
- case 53 : sauvegarde(nx,ny,tab,fichier);
- break;
- }
- }
- while((int)choix2!=54);
- }
-
- /* Explication de la fonction MENU3 */
- /* Menu de selection de difficulte de la grille */
- /* 3 difficultes sont proposees */
- /* Utilisation de la commande SPRINTF pour concatener les valeurs introduites par le joueur */
-
- void menu3(int nx,int ny,grille **tab)
- {
- int choix3,choix4;
- char fichier[20]="";
- do
- {
- couleur("1;34");
- printf("Selectionnez le niveau de difficulte\n");
- couleur("0");
- printf("-------------1.Facile---------------\n"
- "-------------2.Moyen----------------\n"
- "-------------3.Expert---------------\n"
- "-------------4.Retour---------------\n");
- scanf("%d",&choix3);
- }
- while(choix3<1 || choix3>4);
- if((int)choix3!=4)
- {
- do
- {
- printf("Selectionnez votre grille de 1 a 5 : \n");
- scanf("%d",&choix4);
- }
- while(choix4<1 || choix4>5);
- sprintf(fichier,"grille%d%d.txt",choix3,choix4);
- chargement(nx,ny,tab,fichier);
- menu2(nx,ny,tab);
- }
- }
-
- /* Explication de la fonction MAIN */
- /* Menu de depart */
-
- int main()
- {
- long int nx=9;
- long int ny=9;
- grille **tab;
- char choix,fichier [20];
- printf("\033[H\033[2J");
- couleur("1;34");
- printf( "*****************************************************************************************************************\n"
- "*****************************************************************************************************************\n"
- "** **\n"
- "* *\n"
- "* *\n"
- "* *\n"
- "* *\n"
- "* *\n"
- "* BIENVENUE DANS LE JEU KAKURO *\n"
- "* *\n"
- "* *\n"
- "* *\n"
- "** **\n"
- "****************************************************************************************************************\n"
- "****************************************************************************************************************\n");
- printf("\n");
- printf(" Tapez 1 pour Jouer\n "
- " Tapez 2 pour charger une partie sauvegardee\n "
- " Tapez 3 pour quitter le jeu\n");
- do
- {
- choix=getchar();
- while((int)choix<49 || (int)choix>52);
- switch((int)choix)
- {
- case 49 : menu3(nx,ny,tab);
- break;
- case 50 : printf("Entrer le nom du fichier en specifiant son extension (.TXT) : \n");
- scanf("%s",fichier);
- chargement(nx,ny,tab,fichier);
- menu2(nx,ny,tab);
- break;
- }
- }
- while((int)choix!=51);
- return 0;
- }
#include<stdio.h>
#include<stdlib.h>
#include"couleurs.h"
typedef struct element
{
char type;
int val[2];
int attrib;
}grille;
/* Explication de la fonction INIT */
/* Fonction servant a initialiser le tableau pour eviter des problemes d'allocation */
/* de valeur dans les cases, pouvant causer des erreurs */
void init(int nx,int ny,grille **tab)
{
int x,y;
for(x=0;x<nx;x++)
{
for(y=0;y<ny;y++)
{
tab[x][y].type='Z';
tab[x][y].val[0]=0;
tab[x][y].val[1]=0;
tab[x][y].attrib=-1;
}
}
}
/* Explication de la fonction AFFICHAGE */
/* En fonction du type attribue a chaque case, un affichage se distinque par le switch */
/* Le "default" equivalant aux cases blanches non-codees */
void affichage(int nx,int ny,grille **tab)
{
int x,y,x2;
printf("\033[H\033[2J");
for(x=0;x<nx+1;x++)
{
couleur("31");
printf("+-----");
if(x==nx)
{
printf("+\n");
}
}
for(x=0;x<nx;x++)
{
if(x==0)
{
printf("| ");
}
printf("| %2d ",x);
if(x==nx-1)
{
printf("|\n");
}
}
for(x=0;x<nx;x++)
{
for(x2=0;x2<nx+1;x2++)
{
couleur("31");
printf("+-----");
if(x2==nx)
{
printf("+\n");
}
}
for(y=0;y<ny;y++)
{
if(y==0)
{
couleur("31");
printf("| %2d ",x);
couleur("0");
}
couleur("31");
printf("|");
couleur("0");
switch (tab[x][y].type)
{
case 'D' : couleur("36");
printf("%2d\\%2d",tab[x][y].val[1],tab[x][y].val[0]);
couleur("0");
break;
case 'N' : couleur("32");
printf("*****");
couleur("0");
break;
case 'P' : couleur("33");
printf(" %2d ",tab[x][y].val[0]);
couleur("0");
break;
case 'B' : printf(" %2d ",tab[x][y].val[0]);
break;
default : printf(" ");
break;
}
}
couleur("31");
printf("|\n");
couleur("0");
}
for(x=0;x<nx+1;x++)
{
couleur("31");
printf("+-----");
if(x==nx)
{
printf("+\n");
}
couleur("0");
}
}
/* Explication de la fonction LOAD */
/* Fonction de lecture du fichier */
/* Lecture du fichier a partir de la commande FGETS */
/* Lecture ligne par ligne */
/* En fonction du premier caractere, je peux definir le masque pour la commande SSCANF et */
/* Ainsi recupere les differentes valeurs correspondant au type de la case, on rempli la structure */
/* et on termine en fermant le fichier */
void chargement(long int nx,long int ny,grille **tab,char fichier[20])
{
char type,temp[14];
int ligne,colonne,valeur1,valeur2,i,j;
int compteur=0,drap=0;
FILE *jeu;
jeu=fopen(fichier,"r");
if(jeu==NULL)
{
printf(" \n Fichier non charge \n");
}
else
{
printf(" Fichier %s charge \n",fichier);
/* Fonction de lecture du fichier. */
/* Attrib est specifique de ce que je peux faire, */
/* 0 affecte aux cases definitions, impossible de faire une action dessus. */
/* 1 affecte aux cases noires, impossible de faire une action dessus. */
/* -1 affecte aux cases blanches(Z), possibilite d'agir dessus */
/* 3 affecte aux cases predifinies, case remplie par le joueur, impossible d'agir dessus sauf en supprimant la valeur, */
/* et reaffectant la case en case blanche(Z) voir plus bas dans supprimvaleur */
while(!feof(jeu))
{
fgets(temp,14,jeu);
if(drap==0)
{
tab=(grille **)malloc(nx * sizeof(grille *));
if(tab==NULL)
{
printf("\n Echec lors de l'allocation memoire!!!");
}
printf("La memoire allouee est de %d ",sizeof(grille*));
for(i=0;i<nx;i++)
{
tab[i] = (grille *)malloc(ny * sizeof(grille));
printf("La memoire allouee est de %d\n",sizeof(grille));
if (tab[i] == NULL)
{
for (j=0;j<ny;j++)
{
printf("%d",j);
free(tab[j]);
printf("\n Echec lors de l'allocation memoire!!!");
}
}
}
drap=1;
}
if(temp[0]=='D')
{
sscanf(temp,"%c %d %d %d %d",&type,&ligne,&colonne,&valeur1,&valeur2);
tab [ligne][colonne].attrib=0;
tab [ligne][colonne].type=type;
tab [ligne][colonne].val[0]=valeur1;
tab [ligne][colonne].val[1]=valeur2;
}
if(temp[0]=='N')
{
sscanf(temp,"%c %d %d",&type,&ligne,&colonne);
tab [ligne][colonne].type=type;
tab [ligne][colonne].attrib=1;
}
if(temp[0]=='B')
{
tab[ligne][colonne].attrib=-1;
}
if(temp[0]=='P')
{
sscanf(temp,"%c %d %d %d",&type,&ligne,&colonne,&valeur1);
tab [ligne][colonne].type=type;
tab [ligne][colonne].val[0]=valeur1;
tab [ligne][colonne].attrib=3;
}
compteur++;
}
fclose(jeu);
}
}
/* Explication de la fonction SAUVEGARDE */
/* Fonction de sauvegarde du jeu */
/* On ouvre un fichier en ecriture, et ecrase l'ancien s'il y en a deja un nomme comme cela */
/* et on enregistre les donnees dedans */
/* Enregistrement case par case dans un fichier texte au meme format que les grilles de depart */
void sauvegarde(int nx,int ny,grille **tab,char fichier[20])
{
int x,y;
FILE *savegame;
char nom_fic[20];
printf("Veuillez entrer le nom du fichier : ");
fgets(nom_fic,20,savegame);
savegame=fopen(nom_fic,"w");
if(savegame==NULL)
{
printf("Fichier non sauvegarde");
}
else
{
for(x=0;x<nx;x++)
{
for(y=0;y<ny;y++)
{
if(tab[x][y].type=='D')
{
fprintf(savegame,"%c %d %d %d %d\n",tab[x][y].type,x,y,tab[x][y].val[0],tab[x][y].val[1]);
}
if(tab[x][y].type=='B'||tab[x][y].type=='N')
{
fprintf(savegame,"%c %d %d\n",tab[x][y].type,x,y);
}
if(tab[x][y].type=='P')
{
fprintf(savegame,"%c %d %d %d\n",tab[x][y].type,x,y,tab[x][y].val[0]);
}
}
}
}
}
/* Explication de la fonction VERIFREGLE*/
/* Fonction de verification pour les lignes horizontales */
/* Premierement, on cherche la valeur de la case definition correspondant a la ligne */
/* Dont la valeur fait partie, de la on sait d'ou notre verification doit partir (valeur DEPART) */
/* Ensuite, on demarre du DEPART, on teste si la valeur se trouve deja sur la ligne */
/* Si elle se trouve sur la ligne, on retourne directement 0 */
/* Si la valeur ne se trouve pas sur la ligne, on verifie que la case est soit Blanche, soit Predefinie */
/* Si elle l'est, alors on fait la somme de la valeur actuelle avec les valeurs precedentes. */
/* Si a un moment donne, la colonne est differente de DEPART et que les cases sont differentes de B ou P */
/* On a une case vide en plus de celle que l'on veut attribuer et donc cela ne sert a rien de tester la somme */
/* En fin de fonction, on verifie les deux cas possibles et on retourne 1 si c'est possible ou 0 si ca ne l'est pas */
int verifregle(int nx,int ny,grille **tab,int ligne,int colonne,int valeur)
{
int test=0,co,somme=valeur;
int depart,def,echec=1;
co=colonne;
while(test==0)
{
if(tab[ligne][co-1].type=='D')
{
def=tab[ligne][co-1].val[0];
depart=co;
test=1;
}
co--;
}
for(depart=depart;depart<nx&&tab[ligne][depart].type!='N'&&tab[ligne][depart].type!='D';depart++)
{
if(valeur!=tab[ligne][depart].val[0])
{
if(tab[ligne][depart].type=='P'||tab[ligne][depart].type=='B')
{
somme=somme+tab[ligne][depart].val[0];
}
else if(colonne!=depart)
echec=0;
}
else
{
return 0;
}
}
if( (echec==1&&somme==def)||(echec==0&&somme<def))
return 1;
else
return 0;
}
/* Explication de la fonctoion VERIFREGLE2 */
/* Fonction de verification pour les lignes verticales */
/* Premierement, on cherche la valeur de la case definition correspondant a la colonne */
/* Dont la valeur fait paretie, de la sait d'ou notre verification doit partir (valeur DEPART) */
/* Ensuite, on demarre du DEPART, on teste si la valeur se trouve deja sur la colonne */
/* Si elle se trouve sur la ligben on retourne directement 0 */
/* Si la valeur ne se trouve pas sur la colonne, on verifie que la case est soit Blanche, soit Predefinie */
/* Si elle l'est, alors on fait la somme de la valeur actuelle avec les valeurs precedentes. */
/* Si a un moment donne, la ligne est differente de DEPART et que les cases sont differentes de B ou de P */
/* On a une case videen plus de celle que l'on veut attribuer et donc cela ne sert a rien de tester la somme */
/* En fin de fonction, on verifie les deux cas possibles et on retourne 1 si c'est possible ou 0 si ca ne l'est pas */
int verifregle2(int nx,int ny,grille **tab,int ligne,int colonne,int valeur)
{
int test=0;
int somme=valeur;
int def,echec=1,depart,li;
li=ligne;
while(test==0)
{
if(tab[li-1][colonne].type=='D')
{
def=tab[li-1][colonne].val[1];
depart=li;
test=1;
}
li--;
}
for(depart=depart;depart<ny&&tab[depart][colonne].type!='N'&&tab[depart][colonne].type!='D';depart++)
{
if(valeur!=tab[depart][colonne].val[0])
{
if(tab[depart][colonne].type=='P'||tab[depart][colonne].type=='B')
somme=somme+tab[depart][colonne].val[0];
else if(ligne!=depart)
echec=0;
}
else
{
return 0;
}
}
if((echec==1&&somme==def)||(echec==0&&somme<def))
return 1;
else
return 0;
}
/* Explication de BACKTRACKING */
/* Ne fonctionne pas correctement, plante sur la grille 32,34,35 */
int backtracking(int nx,int ny,grille **tab, int lig, int colo)
{
int i=1;
if(colo==ny)
{
lig=lig+1;
colo=0;
}
while(tab[lig][colo].type=='D'||tab[lig][colo].type=='N'||tab[lig][colo].type=='P') /* Test pour voir le type de ligne */
{
colo++; /* Tant que c'est un des types test, on avance dans la colonne */
if(colo==ny) /* Si on arrive en fin de colonne, on avance d'une ligne et on reviens a la case 0 de la colonne */
{
lig=lig+1;
colo=0;
}
}
if((colo==0&&lig==nx)||(colo==ny&&lig==nx)) /*Sert a verifier que je suis a la fin du tableau*/
return 1;
else
{
while(i<10) /* Test tant que i est plus que 10 */
/* Si les 2 regles sont verifiees, on change le type de */
/* en case Blanche, on affecte la valeur de i a la case */
/* Ensuite on teste ce que la fonction et la colonne */
/* renvoie */
/* Sinon on reaffecte un type vide a la case ainsi que la */
/* valeur 0 */
/* On incremente le compteur et on recommence */
{
if(verifregle(nx,ny,tab,lig, colo,i)==1 && verifregle2(nx,ny,tab,lig, colo,i)==1)
{
tab[lig][colo].type='B';
tab[lig][colo].val[0]=i;
if(backtracking(nx,ny,tab, lig,colo+1)==1)
return 1;
}
else
{
tab[lig][colo].type='Z';
tab[lig][colo].val[0]=0;
}
i++;
tab[lig][colo].type='Z';
tab[lig][colo].val[0]=0;
}
return 0;
}
}
void resolutionautomatique(int nx,int ny,grille **tab)
{
int colo=0,lig=0;
/*fonction qui me permet de trouver le depart */
if( backtracking(ny,nx,tab, colo, lig)==1 )
printf("Solution possible\n");
else
printf("solution impossible\n");
}
/* Explication de la fonction JEU */
/* Introduction des coordonnees de la case par le joueur */
/* Fonction de test de valeur introduite par le joueur */
/* Test de la case pour savoir si celle ci est libre ( type Z ) ou si elle correspond a un autre type */
/* Si la case est libre, introduction de la valeur par le joueur puis test de la valeur entree avec les */
/* fonction VERIFREGLE et VERIFREGLE2 */
/* Si test ok, la valeur est encodee, sinon on refais la boucle */
void jeu(int nx,int ny,grille **tab)
{
int ligne,colonne,valeur,test;
do
{
printf("Veuillez entrer le numero de la ligne : \n");
scanf("%d",&ligne);
printf("Veuillez entrer le numero de la colonne : \n");
scanf("%d",&colonne);
if(tab[ligne][colonne].attrib==0)
{
test=0;
affichage(nx,ny,tab);
couleur("1;31");
printf("Ceci est une case definition \n");
couleur("0");
}
if(tab[ligne][colonne].attrib==1)
{
test=0;
affichage(nx,ny,tab);
couleur("1;31");
printf("Ceci est une case noire \n");
couleur("0");
}
if(tab[ligne][colonne].attrib==3)
{
test=0;
affichage(nx,ny,tab);
couleur("1;31");
printf("Cette case a deja ete remplie par le joueur \n");
couleur("0");
}
if(tab[ligne][colonne].attrib==-1)
{
printf("Veuillez introduire votre valeur comprise entre 1 et 9 inclus : \n");
scanf("%d",&valeur);
if(valeur>0&&valeur<10)
{
if(verifregle(nx,ny,tab,ligne,colonne,valeur)==0||verifregle2(nx,ny,tab,ligne,colonne,valeur)==0)
{
affichage(nx,ny,tab);
couleur("1;31");
printf("Cette valeur se trouve deja sur la ligne et/ou la colonne, ou la somme n'est pas correcte \n");
couleur("0");
test=0;
}
else
{
tab[ligne][colonne].type='P';
tab[ligne][colonne].val[0]=valeur;
tab[ligne][colonne].attrib=3;
test=1;
}
}
else
{
couleur("1;31");
printf("La valeur introduire n'est pas comprise dans la fourchette\n");
printf("Veuillez recommencer\n");
couleur("0");
}
}
}
while(test==0);
}
/* Explication de la fonction SUPPRIMVALEUR */
/* Fonction pour supprimer la valeur d'une case */
/* Meme test que pour la fonction JEU, pour ne pas effacer n'importe quoi */
/* Si case ok, la valeur est supprimee et on repasse la case en type Z pour pouvoir reecrire dedans par la suite */
/* J'etais d'abord passe par une fonction pour modifier la valeur plutot que de la supprimer, mais cela pose */
/* des problemes au niveau des regles de verification */
void supprimvaleur(int nx,int ny,grille **tab)
{
int ligne,colonne,valeur,test;
do
{
printf("Veuillez entrer le numero de la ligne : \n");
scanf("%d",&ligne);
printf("Veuillez entrer le numero de la colonne : \n");
scanf("%d",&colonne);
if(tab[ligne][colonne].attrib==-1)
{
affichage(nx,ny,tab);
printf("Il n'y a rien a supprimer ici ici \n" );
test=0;
}
if(tab[ligne][colonne].attrib==0)
{
affichage(nx,ny,tab);
printf("Ceci est une case definition \n");
test=0;
}
if(tab[ligne][colonne].attrib==1)
{
affichage(nx,ny,tab);
printf("Ceci est une case noire \n");
test=0;
}
if(tab[ligne][colonne].attrib==3)
{
tab[ligne][colonne].type='Z';
tab[ligne][colonne].val[0]=valeur;
tab[ligne][colonne].attrib=-1;
printf("La valeur a ete supprimee \n");
test=1;
}
}
while(test==0);
}
/* Explication de la fonction AIDE */
/* Fonction pour l'aide sur les valeurs possibles que peut prendre une case */
/* Introduction par le joueur des coordonnees de la case */
/* Test des valeurs de 1 a 9 par les fonctions VERIFREGLE et VERIFREGLE2 */
/* Les valeurs retournees sont celles qui sont possibles d'introduire */
void aide(int nx,int ny,grille **tab, int ligne, int colonne)
{
int i;
printf("Solution possible : ");
for(i=1;i<10;i++)
{
if(verifregle(nx,ny,tab,ligne,colonne,i)==1&&verifregle2(nx,ny,tab,ligne,colonne,i)==1)
{
printf("%d est une valeur possible pour cette case \n", i);
}
}
printf("\n");
}
/* Explication de la fonction MENU2 */
/* Menu de JEU avec la grille */
/* 1. Entrer une valeur, permet d'entrer une valeur en appelant la fonction JEU */
/* 2. Supprimer une valeur, supprimer la valeur d'une case en appelant la fonction SUPPRIMVALEUR */
/* 3. Demander de l'aide, introduction des coordonnees par le joueur puis appel de la fonction AIDE */
/* 4. Resolution automatique, appel de la fonction resolutionautomatique ( BACKTRACKING ) */
/* 5. Sauvegarde de la partie, enregistre la partie dans un fichier txt en appelant la fonction SAUVEGARDE */
/* 6. Retour, retour au menu principal */
void menu2(int nx,int ny,grille **tab)
{
int ligne,colonne;
char choix2;
char fichier[20]="";
do
{
affichage(nx,ny,tab);
couleur("1;34");
printf("***** MENU DU JEU *****\n");
couleur("0");
couleur("31");
printf("-----------------------\n");
couleur("0");
printf("Que voulez-vous faire ?\n"
"1.Entrer une valeur\n"
"2.Supprimer une valeur\n"
"3.Demander de l'aide\n"
"4.Resolution automatique\n"
"5.Sauvegarde de la partie\n"
"6.Retour\n");
do
choix2=getchar();
while((int)choix2<49||(int)choix2>55);
switch ((int)choix2)
{
case 49 : jeu(nx,ny,tab);
break;
case 50 : supprimvaleur(nx,ny,tab);
break;
case 51 : printf("Entrez le numero de la ligne : \n");
scanf("%d",&ligne);
printf("Entrez le numero de la colonne : \n");
scanf("%d",&colonne);
aide(nx,ny,tab,ligne,colonne);
break;
case 52 : resolutionautomatique(nx,ny,tab);
break;
case 53 : sauvegarde(nx,ny,tab,fichier);
break;
}
}
while((int)choix2!=54);
}
/* Explication de la fonction MENU3 */
/* Menu de selection de difficulte de la grille */
/* 3 difficultes sont proposees */
/* Utilisation de la commande SPRINTF pour concatener les valeurs introduites par le joueur */
void menu3(int nx,int ny,grille **tab)
{
int choix3,choix4;
char fichier[20]="";
do
{
couleur("1;34");
printf("Selectionnez le niveau de difficulte\n");
couleur("0");
printf("-------------1.Facile---------------\n"
"-------------2.Moyen----------------\n"
"-------------3.Expert---------------\n"
"-------------4.Retour---------------\n");
scanf("%d",&choix3);
}
while(choix3<1 || choix3>4);
if((int)choix3!=4)
{
do
{
printf("Selectionnez votre grille de 1 a 5 : \n");
scanf("%d",&choix4);
}
while(choix4<1 || choix4>5);
sprintf(fichier,"grille%d%d.txt",choix3,choix4);
chargement(nx,ny,tab,fichier);
menu2(nx,ny,tab);
}
}
/* Explication de la fonction MAIN */
/* Menu de depart */
int main()
{
long int nx=9;
long int ny=9;
grille **tab;
char choix,fichier [20];
printf("\033[H\033[2J");
couleur("1;34");
printf( "*****************************************************************************************************************\n"
"*****************************************************************************************************************\n"
"** **\n"
"* *\n"
"* *\n"
"* *\n"
"* *\n"
"* *\n"
"* BIENVENUE DANS LE JEU KAKURO *\n"
"* *\n"
"* *\n"
"* *\n"
"** **\n"
"****************************************************************************************************************\n"
"****************************************************************************************************************\n");
printf("\n");
printf(" Tapez 1 pour Jouer\n "
" Tapez 2 pour charger une partie sauvegardee\n "
" Tapez 3 pour quitter le jeu\n");
do
{
choix=getchar();
while((int)choix<49 || (int)choix>52);
switch((int)choix)
{
case 49 : menu3(nx,ny,tab);
break;
case 50 : printf("Entrer le nom du fichier en specifiant son extension (.TXT) : \n");
scanf("%s",fichier);
chargement(nx,ny,tab,fichier);
menu2(nx,ny,tab);
break;
}
}
while((int)choix!=51);
return 0;
}
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
jeu des chiffres exact [ par mounmoun45 ]
salut a tous, Je souhaitreais réaliser un jeu des chiffres "exact" en utilisant les piles ou les arbres de langage c ,et j'ai besoin de votre aide.l
jeu kakuro [ par langagec08 ]
bonjour ts le monde, j ai un projet du langage c consistant à realiser un jeu kakuro.......mais j arrive pas à construire la grille..............veui
jeu d'echecs [ par yara21 ]
bonjour, j'ai un petit soucis , je dois rendre mon projet en c++ mardi 6 avril mais je ne sais pas comment commencer : le sujet est de modeliser un
Programme SDL qui s'arrête subitement au clic... [ par Rflx ]
Bonjour, Je programme actuellement, pour mes études, un jeu labyrinthe en C++ avec interface graphique gérée avec SDL. Parfois, je peux jouer sans
IA en MIPS pour le Jeu de Morpion [ par erkan1404 ]
Bonjour, J'ai quelque petit soucis pour effectuer un IA en Mips (code assembleur), pour le jeu de Morpion. Si vous avez des idées par ou commencer j
Projet de jeu [ par Tobal42300 ]
Mon projet [b]Présentations[/b] Nothern Strike est un jeu en ligne massivement multijoueur avec un monde persistant se déroulant dans l'espace. Les
comment coder des entier de 30 chiffres [ par khaled2010 ]
je veut utiliser des entiers de 30 chiffres dans un programme en c++ .quelle est le type utilsé et comment par exemple le reste de la division??
Afficher du texte sur un jeu vidéo [ par Adeon ]
Salut à tous! J'ai du mal à trouver des infos à ce sujet : Comment afficher du texte(ou autre) sur une AUTRE application qui a un grand taux de rafra
Jeu QUARTO [ par bakano ]
Bonjour, Je cherche un code source du jeu "Quarto" complète ou en partie que je pourrais utiliser sur l'interface graphique d 'Eclipse et non en Open
|
Derniers Blogs
CSS CONTENT STATE SELECTORS (PERSONNAL DRAFT)CSS CONTENT STATE SELECTORS (PERSONNAL DRAFT) par FREMYCOMPANY
Bonjour à tous, Je viens de publier une proposition comprenant 5 pseudo-classes pour le CSS Working Group ayant trait à l'état de chargement d'un élément (ex: IMG,VIDEO,AUDIO,OBJECT pour l'HTML.). Si le c½ur vous en dit, vous pouvez retrouver cette p...
Cliquez pour lire la suite de l'article par FREMYCOMPANY MBA : POURQUOI FAIRE ET COMMENT LE CHOISIR ?MBA : POURQUOI FAIRE ET COMMENT LE CHOISIR ? par ROMELARD Fabrice
Formation initiale Durant la formation, le découpage classique est le suivant (je donnerai les équivalences Suisse lorsque je les connaîtrais) : Ecole primaire jusqu'au Collège : Formation générale permettant d'obtenir les méthodes...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice Y'A DES ERREURS QUI PEUVENT RENDRE LE DéVELOPPEUR VIOLENTY'A DES ERREURS QUI PEUVENT RENDRE LE DéVELOPPEUR VIOLENT par Aleks
Quand on a ce genre d'erreur sans log :
Et bas on a juste envie de choper le gas de Microsoft qu'a développé ça et lui foutre des baffes de Coboye ! ...
Cliquez pour lire la suite de l'article par Aleks [HYPER-V 3] PRéSENTATION DES COMMANDLETS POWERSHELL[HYPER-V 3] PRéSENTATION DES COMMANDLETS POWERSHELL par Pierrick CATRO-BROUILLET
Avec la sortie prochaine de la Beta Consumer Preview de Windows 8, j'avais envie de revenir sur une des fonctionnalités que j'attends le plus et que, en bon geek que je suis, j'utilise déjà : Hyper-V 3 ainsi son module PowerShell.
Il y a déjà pléthor...
Cliquez pour lire la suite de l'article par Pierrick CATRO-BROUILLET IIS7 - COMPRESSION GZIPIIS7 - COMPRESSION GZIP par cyril
La compression GZIP permet d'améliorer les performances de navigation en compressant ce qu'envoie le serveur à un client. Pour comprendre comment cela fonctionne, regardons ce qu'il se passe au niveau HTTP lorsqu'un client tente d'accéder à une ress...
Cliquez pour lire la suite de l'article par cyril
Forum
ARBRE BINAIREARBRE BINAIRE par pacotheking
Cliquez pour lire la suite par pacotheking
Logiciels
Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning Academy System (17.1.3.0)ACADEMY SYSTEM (17.1.3.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|