Inscription / Connexion Nouveau Sujet
Niveau première
Partager :

algorithme

Posté par
juudu62
10-12-13 à 17:51

Bonjour voila j'ai commencer un algorithme sur un jeu de demineur et j'ai besoins d'aide pour le terminer ( ou me corriger si besoins ), le voici :

Tableau 100 entrees (1,2,3,...,100)
Placer 20 mines sur 20 cases parmis les100 --> entalea(1;100)
Remplir le tableau de chiffre (1,8)   : normalement ce ne sont pas des parentheses

Cliquer sur une case (x)
If "mine"
Then afficher "perdu"
Else afficher chiffre case -->   partis ou j ai besoin d aider je doit la devellopper
If [1;8]
Afficher x (1;8) idem ce ne sont pas des parentheses normalement
If 0, decouvrir x-11,x-10,x-9,x-1,x+1,x+9,x+10,x+11 ( cases au alentours )
Jusqu'a decouvrir (1;5) idem pour les parentheses ce sont des acolades

Voila j ai besoins d aide pour la partit ou je le demande + si vous juger qu il manque quelque chose

Posté par
mathafou Moderateur
re : algorithme 10-12-13 à 19:11

Bonjour,

à mon avis il en manque beaucoup plus que ça des "choses"
ton écriture de ça :

Citation :
If [1;8]
Afficher x (1;8) idem ce ne sont pas des parentheses normalement
If 0, decouvrir x-11,x-10,x-9,x-1,x+1,x+9,x+10,x+11 ( cases au alentours )
Jusqu'a decouvrir (1;5) idem pour les parentheses ce sont des acolades
est de toute façon complètement incompréhensible.

déja pour "Remplir le tableau de chiffre (1,8)" ce n'est pas clair du tout.

en fait on comprend (on devine sauvagement) que tu as rangé ton tableau en une seule grande ligne qui regroupe toutes les lignes du tableau
une seule ligne de 100 cases
et que l'indice de la case (i; j) de ce tableau c'est 10*i + j
OK mais il faut le dire et cela impacte directement la façon d'accèder aux cases.

et tout ça, ça va dépendre de la façon de coder dans le tableau l'état d'une case

on peut se contenter de mettre juste "il y a une mine ou pas" et de tout recalculer à chaque fois
ou on peut mettre un état plus riche en possibilités (que l'on calcule donc au départ une fois pour toutes)
- la présence d'une mine
- le nombre de mines autour.
- et au besoin si la case est "découverte" ou pas

le remplissage de ce tableau au départ (initialisation) peut alors être :
on remplit tout ce tableau à 0 (absence totale de mines)
on choisit aléatoirement des emplacements de mine
on les marque "mine"
on ajoute 1 à toutes les cases autour (sauf celles où il y a des mines éventuellement, tout dépend comment on a codé l'état "mine ou pas"
à la fin de cette initialisation on a l'état une bonne fois pour toutes "tout calculé"

et dans la boucle de jeu on n'a donc rien à recalculer du tout !!
il n'y a qu'à tester la valeur de la case et c'est tout.

reste le processus pour rendre récursivement les cases visibles autour de toutes celles qui valent 0 que l'on découvre.

c'est là la difficulté et il me semble assez difficile de le faire sans récursion
ce qui est une notion informatique avancée et revient à écrire un sous programme capable de s'appeler lui même !!

programme découvrir :
si la case contient 0 appeler le programme découvrir sur les cases autour non découvertes
sinon découvrir cette case

le programme qui s'appelle lui même qui s'appelle lui même etc ... avec bien entendu une condition de retour

et on voit immédiatement qu'il va falloir pour éviter de recalculer tout un fatras à chaque fois, mémoriser dans le tableau si la case est découverte ou cachée.

en d'autre termes l'état d'une case est la réunion de 3 informations
- mine ou pas (oui/non)
- nombre de mines autour (un nombre entre 0 et 7, pourquoi 7 ? on peut ne pas se poser cette question et dire entre 0 et 8, bof)
- état découverte ou pas : (oui/non)

soit on crée trois tableaux séparés "en parallèle" pour chacune de ces propriétés
soit on code le tout dans un truc "composite" d'où on peut extraire et modifier séparément chaque composante

tout dépendra sur quoi tu codes et la richesse du langage utilisé

comme pour la récursion
si le langage ne permet ni la récursion ni les sous programes, ça va devenir "assez acrobatique".
(remplacer la récursion par la gestion d'une pile et une boucle tant que la pile n'est pas vide par exemple)

on t'avait prévenu : c'est un boulot assez monstrueux ce "truc"

à suivre (pas ce soir en tout cas, pas trop dispo)

Posté par
juudu62
re : algorithme 10-12-13 à 19:19

Woo normal que je n'est absolument rien compris
Pourtant ma prof nous a dit algorithme la ca devien de la programmation...
Je sent que je ne vais jamais y arrive

Posté par
juudu62
re : algorithme 11-12-13 à 14:22

Quelqu'un?

Posté par
mathafou Moderateur
re : algorithme 11-12-13 à 14:52

je veux bien te faire un post de 2 pages là dessus ...
(c'est cela l'algo)
et l'écriture de l'algo "purement algorithme" ne peut tout simplement pas rentrer dans les détails qui dépendent très fortement de la "réalisation"
donc la demande "détailler tel morceau" c'est rentrer dans ces détails de réalisation, décider comment on va coder tel et tel truc.

1ère étape l'algorithme de principe :

initialisation :
placer des mines dans le tableau
afficher le jeu
tant que la partie n'est pas finie
demander une case
si on est sur une mine
terminer la partie : "perdu"
sinon découvrir cette case (et d'autres éventuellement)
si toutes les cases sans mines sont découvertes
terminer la partie : "gagné"
fin
découvrir tout (montrer les mines)


et ensuite on met à part (séparément) pour ne pas rendre cette algorithme "principal" complètement illisible, chacun des morceaux.

- placer des mines dans le tableau
- découvrir une ou des cases
- afficher une ou des cases
- détails sur les conditions de test et sur l'examen des cases autour

et ces trucs à part et les détails sont des trucs qui dépendront réellement et très fortement de la "réalisation" :
comment on code le tableau et l'état des cases etc

les points à clarifier sont surtout :
- le codage et la représentation du tableau
- la façon d'accéder aux cases "autour" et en particulier
- le test si ces cases existent vraiment (la case voisine pourait être tout simplement en dehors du tableau, et donc carrément plantage du programme en tentant d'accèder à une telle case)

et tous les "détails demandés" vont dépendre effectivement du choix technique fait pour répondre à ces questions.

à suivre. (sinon le post est trop long)

Posté par
juudu62
re : algorithme 11-12-13 à 18:35

Avec tout ces posts je n'y voit plus clair, je sais que ce que je vais te demander va te deplaire mais pourrai tu me reecrire cette algorithme en entier parce que vraiment moi la je vais droit dans le mur.....

Posté par
mathafou Moderateur
re : algorithme 11-12-13 à 18:49

tu veux que je te le fasse en fait quoi ?

reprenons donc

le problème du codage des cases et du tableau tout d'abord
si on ne veut pas entrer dans la réalisation véritable et rester à un pur niveau "algorithme", le tableau est réellement un tableau à deux dimensions i et j
un élément de ce tableau sera noté case[i, j]
point final
i et j de 1 à 10

donc on oublie tes trucs avec des x et des x+11 et un tableau de 100 éléments alignés (avec un seul indice)
ça c'est de la réalisation pure, pas de l'algorithme.

maintenant qu'y a-t-il dans ces cases ?
on a déja mentionné que chaque case a 3 caractèristique (même 4 si on considère sa simple existence)
- il y a une mine dessus ou pas
- elle est visible ou pas
- sa "valeur" (le nombre de mines autour)

sans vouloir entrer dans les détails de réalisation trop pointus, on va utiliser ici la notation pointée héritée des langages objets

la caractéristique de la case[i, j] a-t-elle une mine ou pas sera notée tout simplement
case[i, j].mine sera vrai ou faux selon que cette case a une mine ou pas
de même, case[i, j].visible dira si la case est découverte ou cachée
et enfin case[i, j].valeur donnera le nombre de mines autour.
(et pour le fun : case[i, j].existe indiquera si la case existe purement et simplement, on en vera l'utilité plus tard)

on peut déja détailler l'initialisation du tableau

N dimensions du tableau NxN
M nombre de mines à placer
(N = 10 et M = 20)

pour i de 1 à N
pour j de 1 à N
case[i, j].mine = faux
case[i, j].visible = faux
case[i, j].valeur = 0
case[i, j].existe = vrai (eh eh oui, on peut se psoer la question )
fin
fin


puis le placement des mines :
pour n de 1 à M
i = alea entre 1 et N
j = alea entre 1 et N
tant que case[i, j].mine // on ne met pas une mine sur une mine
i = alea entre 1 et N
j = alea entre 1 et N
fin
case[i, j].mine = vrai
pour chaque case (m, n) autour
case[m, n].valeur = case[m, n].valeur + 1
fin
fin


détailler d'avantage la condition de "pour chaque case (m, n) autour"
- ou bien entre dans des détails vraiment sordides de réalisation
- ou bien fait écrire un truc illisible donnant explicitement la liste des cases autour
donc à ce niveau on ne détaille pas sous peine de rendre l'algorithme totalement illisible

on pourrait écrire un truc du genre :

pour chacune des valeurs de {m, n} parmi {{i-1,j-1}, {i, j-1}, {i+1, j-1}, {i-1, j}, [i+1, j}, {i-1, j+1}, {i, j+1}, {i+1, j}} telles que case[m, n].existe
|
|

ce qui est loin d'être lisible !!! (ça rentre mêm pas dans la ligne !)

on peut un peu améliorer ce truc en créant une "liste des voisins" mais comme ça dépend des valeurs de i et j (variables) on ne peiut pas metre ça dans une liset de constnates et on n'est pas vraimpenty plus avancés
si on ne cherche pas trop la rigueur on peut

définir
voisins := {{i-1,j-1}, {i, j-1}, {i+1, j-1}, {i-1, j}, [i+1, j}, {i-1, j+1}, {i, j+1}, {i+1, j}}


et écrire :
pour chacune des valeurs de {m, n} parmi voisins(i, j) telles que case[m, n].existe

reste le coup de la case[m, n].existe que l'on pourrait préciser par une bardée de tests sur les valeurs de m et n
pour vérifier que 0 < m < N+1 et de même sur n
ce qui complique d'autant et comme on a une petite idée derrière la tête pour virer carrément ce test d'existence, on reste dans le flou
on considère que toute case "en dehors du tableau" répond faux à case[m, n].existe
sans préciser comment c'est fait.

à suivre...
décortique déja ça.

Posté par
juudu62
re : algorithme 12-12-13 à 06:49

Merci, je vais "decortiquer" comme tu dit et je te tiens au courant si mon prof n'est tjrs pas satisfait

Posté par
mathafou Moderateur
re : algorithme 12-12-13 à 11:32

Histoire de pouvoir décortiquer la suite, je te mets tout d'un coup
je t'invite bien entendu à relire soigneusement tout ce qui a été dit sur le sujet au fur et à mesure de l'élaboration de cet algorithme
un algo ça ne s'écrit pas en alignant les lignes et en commençant ligne 1 mais en découpant l'ensemble en morceaux plus petits : modules ou sous programmes, que l'on étudie séparément puis que l'on met "ensemble" pour en faire un tout.

le gros morceau ajouté c'est la procédure pour découvrir les mines
comme déja dit on peut écrire cette procédure sous forme récursive ou bien avec une pile et un tant que
je te mets la procédure avec un tant que, qui permettrait de la réaliser même dans un langage qui n'accèpte pas la récursion
d'ailleurs en mettant "tout à la suite" (pas de sous programme du tout) sauf le sous programme "afficher une case" qui n'est pas détaillé, car c'est du pur affichage physique sur l'écran (dépend du matériel)
ni la façon de saisir une case (idem, clavier / souris etc)

j'ai rajouté la gestion "automatique" de la non existence de voisins du bord
le principe est de créer un tableau de (N+2)*(N+2) cases en rajoutant tout autour une case "vide" qui évite de se poser la question du coup : toutes les cases "existent", simplement celles du bord sont marquées comme "à ne jamais traiter" en les décrétant "visibles" (pour ce que ça change, elles ne seront jamais affichées)

L'algo n'est pas ici du pur algo car j'ai mis un peu les mains dans le cambouis pour :
- utiliser un tableau lineaire au lieu d'un tableau à deux dimensions
(du coup la gestion des voisins et de la pile est plus "propre" car utilise des valeurs ordinaires et non des éléments constitués de deux valeurs)
- préciser le codage de l'état des cases sous forme d'un seul nombre en binaire de sorte que l'état mine = faux, visible = faux, valeur = 0 soit simplement codé par le nombre 0


Constantes :
===========
  N := 10            // dimensions physiques (par ex 10)
  NC := (N+2)*(N+2)  // dimension du tableau linéaire avec bordures
  M := 20        // nombre de mines (par exemple 20 mines sur le tableau de 10x10
  // tableau des différences pour cases voisines (sur le tableau linéaire)
  delta[] := {-(N+3),-(N+2), -(N+1, -1, +1, N+1, N+2, N+3}

variables :
==========
  case[]        // de dimensions NC = (N+2)x(N+2) 
  fini booléen  // (vrai / faux)
  x, y, i, j    // position de la case traitée
  nd            // nombre de cases cachées sans mines
  pile[]        // cases à traiter, dimension maxi N*N
  p             // index dans la pile
  k             // index voisins

initialisation :
===============
  pour x de 0 à NC-1   // toutes les cases du tableau de NC cases, bordure comprise
     case[x] := 0      // (mine et visible = faux, valeur = 0, voir codage)
     j := x%(N+2)      // numero ligne et colonne % = reste de la division
     i := (x-i)/(N+2)
     si i == 0 ou j == 0 ou i == N+1 ou j == N+1 // case du bord
        // astuce pour le programme découvrir(), veut en fait dire "case inexistante"
        case[x] := case[x].visible := vrai  
  fin pour

  // placement des mines et comptage une fois pour toutes des mines autour d'une case
  pour n de 1 à M          // M = nombre de mines
     x := alea(0,NC-1)     // un entier aléatoire = index du tableau case[] 
     // pas de mine sur une mine ni dans le néant
     tant que case[x].mine == vrai ou case[x].visible == vrai
        x := alea(0,NC-1)
     fin tant que
     case[x].mine := vrai
     pour k de 0 à 7  // balayage des cases autour,
         // on met à jour la valeur, que la case autour existe ou pas,
         // contienne elle même une mine ou pas
         y :=  x + delta[k]
         case[y].valeur := case[y].valeur + 1
     fin pour
  fin pour        // le tableau est rempli et prêt à jouer
  nd = N*N - M    // nombre de cases à découvrir (sans mine)

  // affichage initial du tableau
  pour x de 0 = NC-1
     si case[x].visible == faux  // n'affiche pas les cases de la bordure
        afficher case[x]         // affiche en fait ici un tableau entièrement caché
     fin si
  fin pour
  fini := faux  // la partie n'est pas finie, elle n'est même pas commencée !
  
programme principal :
====================
   tant que fini == faux
      demander une case : {i, j}
      x = (N+2)*i + j    // convertit en index linéaire
      si case[x].mine == vrai
         afficher "perdu"
         fini := vrai
      sinon si case[x].visible == faux // cliquer sur une case déja visible ne fait rien
         // découvrir la case x et toutes celles qui en découlent
         p := 0        // la pile est vide
         pile[p] := x  // on met cette case dans la pile. "à traiter"
         p := p+1      // un élément de plus dans la pile
         tant que p != 0  // tant qu'il reste des cases à traiter
             p := p - 1   // on extrait une case à traiter
             x := pile[p]  
             si case[x] == 0  // visible = faux, mine = faux et valeur == 0
                 pour k de 0 à 7  // toutes les cases voisines
                    y := x + delta[k]
                    si case[y].mine == faux et case[y].visible == faux
                       // les cases du bord "inexistantes" ne sont pas concernées
                       // (car mises à "visibles" !)
                       pile[p] := y  // cette case est mise dans la pile, à traiter
                       p := p + 1
                    fin si
                 fin pour
             fin si
             case[x].visible = vrai
             nd := nd - 1
             Afficher case[x]
         fin tant que
         // fin du sous programe découvrir
         si nd == 0  // on a découvert toutes les cases qui étaient sans mines
            afficher "gagné"
            fini := vrai
         fin si
      fin si
   fin tant que
   // fin de la partie : dévoiler les mines
   pour x de 0 à NC-1    // balaye tout le tableau à la recherche de mines 
      si case[x].mine == vrai    // pas d'états d'ame : pas de mine dans la bordure
         case[x].visible = vrai  // l'affichage dépend de l'état !
         afficher case[x]
      fin si
   fin pour
fin


affichage d'une case selon la valeur de case[x],
en position j = x%(N+2) et i = (x-j)/(N+2) (% = reste de la division)
0xxxxx : image d'une case cachée
11xxxx : image d'une mine découverte
100000 : image d'une case vide (valeur nulle)
10nnnn : valeur nnnn != 0 sur l'image d'une case vide
(codage matériel de "valeur" sur les 4 derniers bit, de "mine" sur le bit de poids 16 et de "visible" sur le bit de poids 32)



Vous devez être membre accéder à ce service...

Pas encore inscrit ?

1 compte par personne, multi-compte interdit !

Ou identifiez-vous :


Rester sur la page

Inscription gratuite

Fiches en rapport

parmi 1768 fiches de maths

Désolé, votre version d'Internet Explorer est plus que périmée ! Merci de le mettre à jour ou de télécharger Firefox ou Google Chrome pour utiliser le site. Votre ordinateur vous remerciera !