IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> Algo de recherche de solution Myst 4, Pour Schlum et les autres
Options
SuperCed
posté 12 Aug 2004, 13:30
Message #1


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 831
Inscrit : 19 Jul 2001
Lieu : Живим у Греноблу
Membre no 519



J'ai téléchargé hier la démo de Myst 4, et il y a un puzzle dans la pièce principale.

Il s'agit, je crois, de faire transformer tout un damier de 8*6 en rouge.
En fait, lorsque l'on clique sur une case, alors celle juste en haut change de couleur, celle du bas, celle de gauche et celle de droite aussi.

N'ayant pas trouvé la solution facilement, j'ai décidé d'essayer de faire un programme en C qui permet de faire la recherc à ma place. Le problème, c'est que mon algo est de complexité 48^N ou N est le nombre de clic sur une case.
Or, il parait évident qu'il faut au moins 12 clics pour y arriver, et mon algo peine déjà beaucoup à partir de N = 8.

Le mieux est de voir le problème directement dans Myst 4 pour mieux le comprendre. C'est dans une sorte de cheminé ou il y a une pierre précieuse rouge. Il faut se retourner et cliquer sur un bouton qui ferme une trappe et fait apparaitre le puzzle.

Je vais poster mon programme en C, et je voudrais savoir si quelqu'un a une idée pour optimiser ça. J'ai fait mon programme rapidement, et il y a certainement des meilleurs algos.

Par exemple, ne serait-il pas mieux de stocker les états rencontrés du puzzle (bien qu'il y en ait 2^48...). Ou peut-être réduire le nombre d'état par 4 en utilisant les symétries axiales? Si on stocke ainsi un état du puzzle, on pourrait ainsi comparer les nouveaux états et éliminer des branches de l'arbre de recherche.

Bon, je mets mon code (peut-être faux, je ne l'ai pas beaucoup testé non plus) :

CODE

#include <stdio.h>

#define COLS 6
#define VERBOSE 0

int recursiveSearch (unsigned char *tab, unsigned char level, unsigned char *solutionPath, unsigned char totalLevels, char verboseFlag);
int printTab(unsigned char *tab);
int testTab(unsigned char *tab);
int simulateTurn(unsigned char *tab, unsigned char x, unsigned char y);

int main (int argc, const char * argv[]) {
unsigned char levelMax;
unsigned char level;
unsigned char *solutionPath;
unsigned char myTab[COLS];
unsigned char test,i;
if (argc != 2) {
 printf("Bad argument number : ia deepLevel\n");
 return -1;
}
printf("IA is going to search a solution for you...\n");
levelMax = (unsigned char)atoi(argv[1]);
level = 1;
solutionPath = (unsigned char*)malloc(sizeof(unsigned char) * levelMax *2);
bzero(solutionPath, sizeof(unsigned char)*level*2);
bzero(myTab, sizeof(char)*COLS);
test = 0;
while ((!test) && (level<levelMax)) {
 test = recursiveSearch(myTab, level, solutionPath, level, VERBOSE);
 level++;
 printf("Level is : %d\n", level);
 bzero(solutionPath, sizeof(unsigned char)*level*2);
 bzero(myTab, sizeof(char)*COLS);
}
if (test) {
 printf("Solution :\n");
 for (i=0;i<levelMax-1;i++) {
  printf("(%d",*solutionPath);
  solutionPath++;
  printf(",%d),",*solutionPath);
  solutionPath++;
 }
 printf("\n\n");
}
return 0;
}

int printTab(unsigned char *tab) {
unsigned char i,j;
printf("\n####################");
for (i=0;i<COLS;i++) {
 printf("\n");
 for (j=0;j<sizeof(unsigned char)*8;j++) {
  if (tab[i] & (unsigned char)(0x1 << j)) {
   printf("#");
  } else {
   printf("O");
  }
 }
}
printf("####################\n");
return 0;
}

int testTab(unsigned char *tab) {
unsigned char i,j;
for (i=0;i<COLS;i++) {
 for (j=0;j<sizeof(unsigned char)*8;j++) {
  if (tab[i] | (unsigned char)(0x1 << j)) {
   return 0;
  }
 }
}
return 1;
}

int simulateTurn(unsigned char *tab, unsigned char x, unsigned char y) {
if (x>0) {
 tab[y] = tab[y] ^ (unsigned char)(0x1 << (x-1));
}
if (x<(COLS-1)) {
 tab[y] = tab[y] ^ (unsigned char)(0x1 << (x+1));
}
if (y>0) {
 tab[y-1] = tab[y-1] ^ (unsigned char)(0x1 << x);
}
if (y<(COLS-1)) {
 tab[y+1] = tab[y+1] ^ (unsigned char)(0x1 << x);
}
return 0;
}

int recursiveSearch (unsigned char *tab, unsigned char level, unsigned char *solutionPath, unsigned char totalLevels, char verboseFlag) {
unsigned char x,y;
unsigned char tabTemp[COLS];
if (verboseFlag) {
 printTab(tab);
}
if (testTab(tab)) {
 solutionPath[(totalLevels-level)*2] = x;
 solutionPath[(totalLevels-level)*2 +1] = y;
 return 1;
}
if (!level) {
 return 0;
}
for (x=0;x<(sizeof(unsigned char)*8);x++) {
 for (y=0;y<COLS;y++) {
  bcopy(tab, tabTemp, sizeof(unsigned char)*COLS);
  simulateTurn(tabTemp, x, y);
  if (recursiveSearch(tabTemp, level -1, solutionPath, level, verboseFlag)) {
   solutionPath[(totalLevels-level)*2] = x;
   solutionPath[(totalLevels-level)*2 +1] = y;
   return 1;
  }
 }
}
return 0;
}




--------------------
Хајде Јано коло да играмо
iMac 27 mi 2010
Macbook air mi 2011
Mac Mini M1
Go to the top of the page
 
+Quote Post
Philram
posté 12 Aug 2004, 14:15
Message #2


Macbidouilleur de bronze !
**

Groupe : Membres
Messages : 327
Inscrit : 19 Jun 2003
Lieu : Lausanne, Suisse
Membre no 8 131



Bonjour,
C'est bien de trouver des problèmes pratiques pour s'exercer au codage, mais même si tu arrives à remplir toutes les cases en rouge, c'est pas ça qui va actionner l'ascenseur.

La vérité est ailleurs wink.gif


--------------------
Mac Pro 2.66GHz,Tibook 1GHz, G4 Bi 533@600, LC III, SE.
Go to the top of the page
 
+Quote Post
SuperCed
posté 12 Aug 2004, 14:42
Message #3


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 831
Inscrit : 19 Jul 2001
Lieu : Живим у Греноблу
Membre no 519



rahhh, zutr... Ben tant pis alors, je me disais que c'était plus dans le style de 7th Guest que de Myst. c'ets pas le genre de Myst de mettre un puzzle au millieu comme ça...

Mais ça ne remet pas en cause le programme...


--------------------
Хајде Јано коло да играмо
iMac 27 mi 2010
Macbook air mi 2011
Mac Mini M1
Go to the top of the page
 
+Quote Post
Benzebut
posté 16 Aug 2004, 12:42
Message #4


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 4 596
Inscrit : 5 Mar 2003
Lieu : Ville de Notre-Dame
Membre no 6 523



QUOTE(SuperCed @ 12 Aug 2004, 14:42)
rahhh, zutr... Ben tant pis alors, je me disais que c'était plus dans le style de 7th Guest que de Myst. c'ets pas le genre de Myst de mettre un puzzle au millieu comme ça...

Mais ça ne remet pas en cause le programme...

Non, bien sur, mais dans le jeu si on regarde attentivement les changements dans le puzzle, on remarque que chaque pression génére une réponse en croix, formée de 4 cases pleines ...
Un p'tit bout de code à modifier ! tongue.gif


--------------------
Sur iMac Pro (fin-2017) en Xeon 8 coeurs à 3.2 GHz / 32 Go Ram / Radeon Pro Vega 56 8 Go / 1 To SSD
Sous macOS 10.14.6 (Mojave) à jour et en réseau Wifi 6 avec une boite Fibre

Nostalgique de l'Apple IIgs ? Un petit émulateur : www.casags.net
Go to the top of the page
 
+Quote Post
SuperCed
posté 16 Aug 2004, 13:58
Message #5


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 831
Inscrit : 19 Jul 2001
Lieu : Живим у Греноблу
Membre no 519



QUOTE(Benzebut @ 16 Aug 2004, 12:42)
QUOTE(SuperCed @ 12 Aug 2004, 14:42)
rahhh, zutr... Ben tant pis alors, je me disais que c'était plus dans le style de 7th Guest que de Myst. c'ets pas le genre de Myst de mettre un puzzle au millieu comme ça...

Mais ça ne remet pas en cause le programme...

Non, bien sur, mais dans le jeu si on regarde attentivement les changements dans le puzzle, on remarque que chaque pression génére une réponse en croix, formée de 4 cases pleines ...
Un p'tit bout de code à modifier ! tongue.gif
[right][snapback]811221[/snapback][/right]


Ben c'est ce que j'ai fait dans mon code non?


--------------------
Хајде Јано коло да играмо
iMac 27 mi 2010
Macbook air mi 2011
Mac Mini M1
Go to the top of the page
 
+Quote Post
le grimpeur
posté 16 Aug 2004, 22:14
Message #6


Expressivité Bovine
****

Groupe : Membres
Messages : 1 268
Inscrit : 23 Jun 2003
Lieu : Chez les Gones, mais vert de coeur...
Membre no 8 222



Je crois qu'il suffit de partir des angles, puis il y a un motif à répéter, et c'est bon...y'a ça dans Spyro sur Playstation et dans des vieux jeus macs


--------------------
Hackintosh | i3 540 3,07 Ghz | 8 Go DDR 1333 | SSD 60 Go Vertex 2 | Samsung EcoGreen F3 500 Go | Radeon 5770 HD 1Go DDR5 | Mac Os Lion 10.7.4
Synology Ds211j 2 x 1To RAID 1
iPhone 3GS | 16Go | iOS 5.1.1

Plus t'en chies fort, moins t'en chies longtemps. - proverbe montagnard -
Go to the top of the page
 
+Quote Post
schlum
posté 17 Aug 2004, 08:14
Message #7


Terminaltor
Moderating Machine
*****

Groupe : Admin
Messages : 24 449
Inscrit : 25 Oct 2002
Lieu : Jeumont (59)
Membre no 4 319



J'ai déjà programmé ce truc ... Si tu veux je te passe l'algo, mais le principe est simple wink.gif
Il suffit de partir d'une ligne ou d'une colonne au bord (6 -> 2^6 = 64 possibilités), et pour chaque possibilité de compléter avec la ligne du dessus à chaque fois (ou la colonne d'à côté si on a pris une colonne) ... Si c'est possible à faire, une des possibilités complètera exactement la dernière ligne.
C'est donc en complexité n*m*2^min(n,m), soit pour 6*8, pas grand chose wink.gif


[Edit] j'espère qu'on parle bien du même problème, le damier qu'il faut remplir et quand on touche une case, elle et ses 4 voisines (ou 3 pour un bord ou 2 pour un coin) changent d'état ...


--------------------
          I think therefore I Mac          
Go to the top of the page
 
+Quote Post
SuperCed
posté 17 Aug 2004, 08:59
Message #8


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 831
Inscrit : 19 Jul 2001
Lieu : Живим у Греноблу
Membre no 519



QUOTE(schlum @ 17 Aug 2004, 08:14)
J'ai déjà programmé ce truc ... Si tu veux je te passe l'algo, mais le principe est simple  wink.gif
Il suffit de partir d'une ligne ou d'une colonne au bord (6 -> 2^6 = 64 possibilités), et pour chaque possibilité de compléter avec la ligne du dessus à chaque fois (ou la colonne d'à côté si on a pris une colonne) ... Si c'est possible à faire, une des possibilités complètera exactement la dernière ligne.
C'est donc en complexité n*m*2^min(n,m), soit pour 6*8, pas grand chose  wink.gif


[Edit] j'espère qu'on parle bien du même problème, le damier qu'il faut remplir et quand on touche une case, elle et ses 4 voisines (ou 3 pour un bord ou 2 pour un coin) changent d'état ...
[right][snapback]812033[/snapback][/right]


Pas tout a fait car dans mon cas, la case du millieu ne change pas. ce qui est beaucoup plus difficile.
Mais bon, j'ai trouvé l'astuce de Myst sans trop de problème...
Par contre, ce topic était plus pour parler un peu optimisation combinatoire.


--------------------
Хајде Јано коло да играмо
iMac 27 mi 2010
Macbook air mi 2011
Mac Mini M1
Go to the top of the page
 
+Quote Post
schlum
posté 17 Aug 2004, 14:31
Message #9


Terminaltor
Moderating Machine
*****

Groupe : Admin
Messages : 24 449
Inscrit : 25 Oct 2002
Lieu : Jeumont (59)
Membre no 4 319



QUOTE(SuperCed @ 17 Aug 2004, 09:59)
QUOTE(schlum @ 17 Aug 2004, 08:14)
J'ai déjà programmé ce truc ... Si tu veux je te passe l'algo, mais le principe est simple  wink.gif
Il suffit de partir d'une ligne ou d'une colonne au bord (6 -> 2^6 = 64 possibilités), et pour chaque possibilité de compléter avec la ligne du dessus à chaque fois (ou la colonne d'à côté si on a pris une colonne) ... Si c'est possible à faire, une des possibilités complètera exactement la dernière ligne.
C'est donc en complexité n*m*2^min(n,m), soit pour 6*8, pas grand chose  wink.gif


[Edit] j'espère qu'on parle bien du même problème, le damier qu'il faut remplir et quand on touche une case, elle et ses 4 voisines (ou 3 pour un bord ou 2 pour un coin) changent d'état ...
[right][snapback]812033[/snapback][/right]


Pas tout a fait car dans mon cas, la case du millieu ne change pas. ce qui est beaucoup plus difficile.
Mais bon, j'ai trouvé l'astuce de Myst sans trop de problème...
Par contre, ce topic était plus pour parler un peu optimisation combinatoire.
[right][snapback]812071[/snapback][/right]

Qu'appelles-tu la case du millieu pour un damier 6*8 ? huh.gif Et que veut dire "ne change pas" ?


--------------------
          I think therefore I Mac          
Go to the top of the page
 
+Quote Post
SuperCed
posté 17 Aug 2004, 16:37
Message #10


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 831
Inscrit : 19 Jul 2001
Lieu : Живим у Греноблу
Membre no 519



Quand tu cliques sur une case, cette case ne change pas de couleur, ce sont les 4 cases autour qui changent de couleur.

Le mieux est de regarder Myst pour comprendre.


--------------------
Хајде Јано коло да играмо
iMac 27 mi 2010
Macbook air mi 2011
Mac Mini M1
Go to the top of the page
 
+Quote Post
schlum
posté 17 Aug 2004, 17:30
Message #11


Terminaltor
Moderating Machine
*****

Groupe : Admin
Messages : 24 449
Inscrit : 25 Oct 2002
Lieu : Jeumont (59)
Membre no 4 319



QUOTE(SuperCed @ 17 Aug 2004, 17:37)
Quand tu cliques sur une case, cette case ne change pas de couleur, ce sont les 4 cases autour qui changent de couleur.

Le mieux est de regarder Myst pour comprendre.
[right][snapback]812653[/snapback][/right]


Ahh, ok ! Bah ça change pas grand chose wink.gif
Il fait déjà remarquer que quand on appuie 2 fois sur la même touche, ça fait comme si on y avait pas appuyé (même si on réappuie à un autre moment) ; donc toutes les configurations possibles s'obtiennent en appuyant une et une seule fois sur un nombre de cases qui est un sous-ensemble de l'ensemble des cases. Ca réduit déjà ta complexité de 48^N à 48!/(48-N)!
Ensuite, on peut remarquer aussi que l'ordre dans lequel on appuie sur les cases ne compte pas pour le résultat ... Ca réduit considérablement encore la complexité.
Enfin, si le problème est de remplir toutes les cases, on peut remarquer que tout dépend du remplissage de la première ligne / colonne, car une fois celle-ci remplie, un algorithme simple donne le remplissage de la ligne / colonne immédiatement à côté (il faut combler les trous de la dite ligne / colonne ; on ne pourra le faire qu'à cet endroit, après on sera trop loin) ... C'est réussi si et seulement si en arrivant à la dernière ligne / colonne, le remplissage de l'avant-dernière la comble aussi complètement.
Il suffit donc de tester toutes les possibilités sur une seule ligne / colonne wink.gif
On peut appliquer le même algorithme à n'importe quelle figure à atteindre wink.gif


--------------------
          I think therefore I Mac          
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 28th April 2024 - 00:08