Réalisation en C d'un Démineur

Signaler
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008
-
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008
-
voilà dans le cadre de mes études, je dois réaliser un demineur version rlogic en C... le principe de base est le meme sauf que dans ce rlogic, il faut parcourir le terrain en partant du coin en haut à gauche jusqu'au coin en bas à droite.
j'utiliserais donc 2 tableaux l'un servant à conserver l'état du terrain et l'autre contenant les informations d'affichage.

Donc voilà je souhaite avoir de l'aide pour ce qui est de l'algorithme...
je dois générer un terrain miner, puis me lancer dans les situations pour lesquelles je suis pres d'une mine etc... les 1,2,3,4 que je place autour des mines je les gerent comment étant donné la pose aléatoire du terrain miné...

merci d'avances pour vos réponses...

19 réponses

Messages postés
25
Date d'inscription
vendredi 1 décembre 2006
Statut
Membre
Dernière intervention
27 novembre 2018

c'est simple un fois le terain miné generer,  pour chaque case non miné tu compte combien de case sont miné autour .
Ex : Sur un tableau Tab[X][Y] (on considère que une case  miné est a -1)

pour i de 0 a X-1
   pour j de 0 a Y-1
      Si (Tab[i][j] != -1)  //case non miné
          iNbMine = 0      

         Si (Tab[i-1][j] = = -1)
            iNbMine++

         Si (Tab[i][j-1] == -1)
            iNbMine++

         Si (Tab[i+1][j] == -1)
            iNbMine++

          Si (Tab[i][j+1] == -1)
            iNbMine++ 

          Tab[i][j] = iNbMine;
      FinSi
   FinPour
FinPour

Voila apres je ne sais plus si tu doit aussi verfier les cases en diagonales ds le demineur
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Salut,

Pour le demineur, les cases en diagonales doivent etre prise en compte. ( sinon c'est impossible pour jouer)
La vrai seule difficultee pour le demineur, c'est de devoiler les cases "0", mais si tu maitrises la recursivitee ou les piles, il n'y a plus aucun probleme.

A+

Mon site internet : http://pistol.petesampras.free.fr
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

merci pour vos réponses... mais comment réaliser le terrain en positionant les mines aléatoirement... j'ai entendu parler de la fonction:

srand((unsigned)time(NULL));

avec laquelle j'utilise:

int mine=rand()%nbMine;

mais je ne vois pas comment cela genere le "nbMine" prédéfini dans tout le tableau[nbColonne][nbLigne].
il faut pas faire une boucle for imbriquée dans une autre pour parcourir chaque case et mettre la fonction aléatoire à l'interieur?
si vous pouvez m'éclairer la dessus merci...
Messages postés
25
Date d'inscription
vendredi 1 décembre 2006
Statut
Membre
Dernière intervention
27 novembre 2018

Une solution serait (pour expliquer on suppose que tu doit generer 10 bombes et que tu a un tableau  tab de 10*10 "Tab[10][10] "

pour i de 0 a 9 //on passe 10 fois donc 10 bombes
   X = Generer un nb aleatoire entre 0 et 9 //Puisque tu a 10 case en longeur
   Y = Generer un nb aleatoire entre 0 et 9 //Puisque tu a 10 case en largeur

   si (Tab[X][Y] != -1)//Si la case n'est pas deja marquer (ca peut arriver)
        Tab[X][Y] = -1 // marque la case
   sinon
         i = i -1 //Sinon il te manquera une bombe
   FinSi
FinPour


Voila de cette façon tu n'a qu'une boucle


Pour generer un nb aléatoire tu doit initializer le compteur avec srand((unsigned)time(NULL));
Puis a chaque apel de "rand() % (10)"
tu aura un nb different compris entre 0 et 9

pour plus de detail sur rand va sur
http://c.developpez.com/faq/?page=nombres#NOMBRES_random_bornes
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

j'ai pas encore essayé ta facon...

voilà le code d'essai pour l'utilisation de la fonction aléatoire:

#include <stdio.h>
#include<stdlib.h>

int main (void){
  int i,j;
  char tab[9][9];
  int mine=0;
for(i=0;i<9;i++)
{
  for(j=0;j<9;j++)
    {
      tab[i][j]=rand()%2;
      if ((tab[i][j]>0.5) &amp;&amp; (mine<10))
    {
      tab[i][j]='*';
      mine++;
    }
      else tab[i][j]=0;
 printf("%c ",tab[i][j]);
    }
  printf("\n");
 
  
} 
 
return 0;
}


Le probleme est que la répartition aléatoire n'est valable qu'une seule fois, car lorsque je refais une nouvelle l'execution du programme, j'obtiens le meme resultat: les mines sont représentées avec '*'

c'est possible de cette maniere ou il faut que je fasse de la tienne?
Messages postés
25
Date d'inscription
vendredi 1 décembre 2006
Statut
Membre
Dernière intervention
27 novembre 2018

il faut initialiser le compteur avec l'heure courante pour que tes nb soit aleatoire a chaque demarage
avec la fct srand((unsigned)time(NULL)) a mettre en debut de programme

oui ta methode devrait marcher mais je comprend pas trop ton > 0.5  (tu risque d'avoir beaucoup de  mine au debut du tab et pas du tout a la fin, essaye en tous cas)

de plus 2 boucle for sa veut dire que le temps d'execution et le carré du temps si il n'y en a qu'une.
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

ok merci je continue dans mon prog... je risque d'avoir encore quelque question...
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

j'ai une autre question: il faut que j'utilise les touches h,d,b,g du
clavier pour me deplacer des cases en haut à gauche aux cases en bas à
droite de mon demineur... on nous a parlé succintement de sequence
d'échappement... pour faire correspondre une action à une touche au
clavier... mais il faut faire quoi pour que le simple deplacement du
curseur face apparaitre ce qui se cache sous la case? je vais utiliser un deuxieme tableau pour "jouer" cad modifier mon premier tableau qui est le terrain de base ou il y a eu le tirage aléatoire...
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Salut
Axjaw, tu devrais suivre la methode de kts__system pour la generation aleatoire du terrain car ta facon de faire n'est pas du tout aleatoire.
Tu testes toutes les cases, et tu dis qu'il y a une 1 chance sur 2 pour qu'il y ai une mine la. Tu n'as aucun control sur le nombre de mine present sur ton tableau a la fin de ta generation.
Ben oui imagine que rand()%2 te donne a chaque fois 0 !! (peut probable mais ya une chance), tu n'aurai alors aucune mines sur ton tableau alors que tu pensais en avoir 10!

Et en l'occurence, comme tu as un gros tableau, et peu de mines, toutes tes mines seront sur les premieres colonnes.

En conclusion, tu as aucun controle sur le nombre de mines et leurs emplacements n'est pas aleatoire=> oublie cette methode 

A+
Mon site internet : http://pistol.petesampras.free.fr
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

ok merci, mais j'ai resolu cette affaire en suivant la méthode de kts_system...
sinon vous ne peux pas m'en dire plus sur les séquences d'échappements et sur le fait que l'on  a un curseur que l'on peut faire bouger à droite a gauche en bas en haut avec "h" "d" "b" "g" entrée std du clavier...
Messages postés
25
Date d'inscription
vendredi 1 décembre 2006
Statut
Membre
Dernière intervention
27 novembre 2018

pour l'interception des touches du clavier je sai plus comment on fait en c
mais c'est simple et tu devrait trouver sa ds la faq c de devellopez ou meme peut etre ds une src ici

par contre pour que le simple deplacement du curseur face apparaitre ce qui se cache sous la case, si tu veut faire ca en C t'a pas fini sa va etre la mrd
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

d'ou peut etre la création d'un deuxieme tableau sur lequel je vais "jouer"...c'est possible ça non?
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

il faut que je crée un deuxieme tableau pour afficher le jeux "modifié"... le premier tableau contient le terrain de base avec les mines et les '-' comme ceci:
les premieres case autour du joueur sont decouverte...

J 1 - - - - - -
2 * - - - - -
- - - - - - - -
- - - - - - - -
- - - - - - - V

j'ai donc besoin d'un second tableau pour faire apparaitre à chaque appui sur les touches h d b g qui correspondent aux deplacements haut droit bas gauche

if (getchar(d))
se déplacer à droite pr exemple...

et ça je ne vois pas comment le faire....
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

Deuxieme question: dans ton algo kts_system, des mines peut alatoirement se place au debut et de ce fait bloquer la progression du joueur du genre

J *- - - - -
**- - - * -
- - - * - -

etc... de meme à la fin

- - - - - * *
- - - - -* Victoire

il faudrait donc empecher que cela se produise j'avais pensé à cette methode:

TON CODE
if((tab[X][Y]!= '*') &&(tab[X][Y]!=tab[0][0])&&(tab[X][Y]!=tab[0][1])&&(tab[X][Y]!=tab[1][0]))
tab[X][Y] ='*';
else i--;

et en italique le rajout pour eviter juste les mines qui bloque le debut il faudrait faire la meme à la fin...
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Salut
On ne doit pas avoir la meme definition du demineur. Ce que tu essaies de faire ne ressemble en rien au demineur de Microsoft.
La c'est beaucoup plus compliqué pour la generation du terrain: il faut qu'a chaque fois que tu poses une bombe, tu t'assures que l'on peux toujours atteindre par un chemin la case d'arrivé!!!
Cela implique la creation de l'algo A* (A star) ou autre...

Je te conseil de faire le meme demineur que celui de Windows pour commencer.

A+

Mon site internet : http://pistol.petesampras.free.fr
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Re


Je me suis un peu plus penché sur ton probleme, et je pense que pour generer ton terrain aléatoirement, le plus facile est de creer un chemin pseudo aléatoire de ton point A vers ton point B sur ton terrain vierge, puis ensuite seulement tu ajoutes les mines aléatoirements en t'interdissant de poser des mines sur le chemin selectionné.

Mon site internet : http://pistol.petesampras.free.fr
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

ok! oui je crois que c'est plutot ça, crer un chemin solution en fait et ensuite généré les mines aléatoirement... mais le probleme c'est qu'a chaque fois que tu vas rejouer tu auras toujours la meme solution non?
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Salut
Il faudrait que tu arrives a generer un chemin solution qui lui aussi sera pseudo aleatoire... Mais je suis d'accord sur le fait qui se ressemblera beaucoup d'une partie sur l'autre.

Je pense que ce que je ferai, c'est qu'a chaque fois que je pose une mine, je verifirai si un chemin existe toujours pour aller jusqu'à la fin. Donc regarde bien l'algo A* . Il reglerait tous tes problemes. Ya pas mal d'exemple sur ce site d'on voici un lien:
http://www.cppfrance.com/codes/DEPLACEMENT-UNITEES-MAX-200-AVEC-ALGO-STAR_34949.aspx

A+
Mon site internet : http://pistol.petesampras.free.fr
Messages postés
11
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
30 janvier 2008

ok merci à toi autre question:
Voilà j'ai un petit soucis dans mon programme j'ai besoin d'utiliser la
fonction aleatoire "rand" qui permet de tirer au hazard un nombre par
exemple ici entre 0 et 19, ce nombre sera mis dans la variable m ici:
m=rand()%20;

Le soucis, c'est que je veux tirer un nombre de maniere aléatoirement,
mais une fois le nombre tirer, je ne veux plus retomber sur ce
nombre... en gros, je veux que l'on fasse un tirage sans remettre le
nombre dans la "pioche" ! (sur les 20 nombres à piocher j'en veux que
10 par exemple... mais differents !!)

merci d'avance!