Aujourd'hui, j'ai eu l'idée soudaine de créer un jeu de réflexion intelligent pour ma petite amie.
Ces fonctions doivent être réalisées, la première est de personnaliser l'image et la seconde est de personnaliser la grille. Bien sûr, ce à quoi je pensais au début était 3*3 4*4 5*5, et je ne l'ai pas utilisé. une grille comme 3*5.
La troisième est de réaliser la fonction de puzzle automatique. Je pense que tout le monde sait que les femmes ne sont pas très douées pour les jeux, cette fonction de puzzle automatique est donc nécessaire.
Je n’écrirai pas sur les autres suspensions et classements !
Maintenant, la question clé se pose. Il semble que les exigences pour réaliser la fonction de puzzle automatique soient un peu élevées ! Les ordinateurs peuvent-ils être comme les humains et peuvent seulement :
Venons-en d’abord à l’essentiel
Un puzzle n’est en réalité qu’une question d’arrangement :
Il existe une définition de la permutation : dans un arrangement de 1, 2,...,n, si les positions avant et arrière d'une paire de nombres sont dans l'ordre inverse, c'est-à-dire que le numéro avant est supérieur au numéro arrière, alors on les appelle un ordre inverse. Le nombre total d'ordres inverses dans une permutation est appelé numéro d'ordre inverse de cette permutation. L’arrangement dans lequel le nombre inverse est un nombre pair est appelé arrangement pair ; l’arrangement dans lequel le nombre inverse est un nombre impair est appelé arrangement impair. Par exemple, en 2431, 21, 43, 41 et 31 sont dans l’ordre inverse, et l’ordre inverse est 4, ce qui est un arrangement pair.
Voici une autre définition : En échangeant deux nombres dans une permutation, la parité de la permutation change.
Les définitions ci-dessus sont toutes tirées de « Advanced Algebra ».
La disposition du puzzle doit être uniforme. Cela peut être trouvé dans mes références.
Voilà donc comment mon puzzle est mis en œuvre !
J'écrirai plus tard
Référence : http://en.wikipedia.org/wiki/Fifteen_puzzle
Casse-tête automatique :
Tout d'abord, il devrait y avoir certaines règles pour les puzzles automatiques. D'après mon expérience en matière de puzzle, pour terminer le puzzle, différentes zones utilisent des règles de puzzle différentes, donc :
Ma carte quadrillée est divisée en 4 zones (si la carte quadrillée comporte n*n grilles)
La première zone : plage de coordonnées x 0 à n-2, plage de coordonnées y 0 à n-3
Deuxième zone : coordonnée x n-1, plage de coordonnées y 0 à n-3
La troisième zone : plage de coordonnées x 0 à n-3, plage de coordonnées y n-2 et n-1
La quatrième zone : plage de coordonnées x n-2 à n-1, plage de coordonnées y n-2 et n-1, c'est-à-dire les quatre dernières cellules ;
Chaque zone peut être complétée selon les règles de la zone respective.
Puzzle.java
importer java.io.FileNotFoundException; importer java.io.PrintStream; importer java.io.UnsupportedEncodingException; importer java.util.Random; public class Puzzle { private long step = 0; private int n = 6;//Base de la plateforme private int [][] puzzle; private int resetBlock = 0;// //Position du bloc vide private int whiteBlockX private int; whiteBlockY; //Les coordonnées du bloc actuellement à déplacer sont le bloc de réinitialisation private int resetBlockX; private int resetBlockY; private boolean isPrint=false; public Puzzle() { init( } public Puzzle(int n) { this. n = n; init(); } private void init() { puzzle = new int[n][n]; y++) { for (int x = 0; x < n; x++) { puzzle[y][x] = x + y * n; } } whiteBlockX = n-1; whiteBlockY = n-1; // Le nombre de mélanges doit être un nombre pair. Random random = new Random(); while (times > 0) { int x0 = random.nextInt(n); random.nextInt(n); int x1 = random.nextInt(n); int y1 = random.nextInt(n); if (x0 != x1 && y0!=y1) {// Tri uniforme garanti if((x0 = =n-1&&y0==n-1)||(x1==n-1&&y1==n-1)){//Le dernier n'est pas remplacécontinue } fois--; int t = puzzle[x0][y0]; puzzle[x0][y0] = puzzle[x1][y1]; puzzle[x1][y1] = t; p = {{22,9 ,1 ,5 ,0 ,25 },{// 33,23,20,26,18,21},{// 6 ,16,17,10,34,31},{// 19,28,32,7 ,3 ,2},{// 11,4 ,12,14,27,24},{// 15,29 ,30,8 ,13,35}};// puzzle = p; } public void sort(){ for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (x == n - 1 && y == n - 1) {//Le dernier est vide, } else { reset(x, y ) ; } } } } //Réinitialiser le bloc à la position cible private void reset(int targetX, int targetY) { //Trouver la position actuelle du bloc de réinitialisation initResetBlock(targetX, targetY); La séquence de réinitialisation est de gauche à droite, de haut en bas* La méthode de mouvement consiste à se déplacer d'abord vers le haut, puis vers la gauche* Le bloc de réinitialisation actuel, la position qu'il souhaite réinitialiser peut être divisée en quatre situations* 1. Pas dans le la ligne la plus à droite ni les deux lignes du bas * 2. La ligne la plus à droite x=n-1, mais pas les deux lignes du bas ; * 3. Les deux lignes du bas y=n-2, mais pas la ligne la plus à droite ; la ligne la plus à droite est également les deux lignes du bas OK*/ if(targetX < n-1 && targetY < n-2){ if(resetBlockX==targetX&&resetBlockY==targetY){//La position est correcte sans déplacer le retour ;//Quitter la récursion} resetBlockToTarget(targetX, targetY }); sinon if( targetX==n-1 && targetY < n-2){//Le deuxième cas if(resetBlockX==targetX&&resetBlockY==targetY){//La position est correcte sans bouger return;//Quitter la récursion} reset2(targetX, targetY); n- 2 && targetY == n-2){// isPrint=true; return3(targetX); else{ initResetBlock(n-2, n-2); réinitialiserBlockToTarget(n-2, n-2); if(whiteBlockX<n-1){ whiteBlockRight(); } if(whiteBlockY<n-1){ whiteBlockDown( } if(whiteBlockX==n-1&&whiteBlockY==n) -1){ return ; } } reset(targetX, targetY);//récursion} private void initResetBlock(int targetX,int cibleY){ resetBlock = cibleX + cibleY * n; for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (puzzle[y][x] == resetBlock) {// x, y est la position du bloc de réinitialisation resetBlockX = x; resetBlockY = y; break; if(targetX>=2){// } initResetBlock(targetX, n-1); resetBlockToTarget(targetX, n-2); initResetBlock(targetX, n-2); : while (!(whiteBlockX==targetX && whiteBlockY==n-1)) { if(whiteBlockY<n-1){ whiteBlockDown(); continue l; } if(whiteBlockX>targetX){ whiteBlockLeft(); continue l; } whiteBlockUp(); if(puzzle[n-2][targetX]!=resetBlock|| puzzle[n-1][targetX]!=(resetBlock+n)){//Aucune réinitialisation réussie// isPrint=true; swapWhiteBlockAndCurrentBlock(); reset3(targetX); } privé void reset3_0(){ if(resetBlockX<n-1){ whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); reset3_0(); return } privé; void reset2_3(){ if(whiteBlockX==resetBlockX && whiteBlockY==resetBlockY+1){ return;//Si les conditions sont remplies, quittez la récursion} //Le bloc blanc peut être à gauche, en bas à gauche ou en bas côté du bloc de réinitialisation if(whiteBlockY= =resetBlockY){//left whiteBlockDown(); }else if(whiteBlockX < resetBlockX){//inférieur gauche whiteBlockRight(); }else { whiteBlockUp(); } reset2_3();//recursion} private void reset2_2(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//2. Retour ci-dessous ;//Quitter la récursivité} //Positions possibles du bloc de réinitialisation, position cible à gauche, directement en dessous, en bas à gauche if(resetBlockX==targetX){//Déplacez-vous directement en dessous et vers le haut resetBlockUp(targetX, targetY); }else{//À gauche ou en bas à gauche en premier ; Déplacez-vous vers la droite puis vers le haut. si (resetBlockX == target Le bas n'est pas un bloc de réinitialisation, déplacez le bloc blanc vers la position cible* 2. Déplacez le bloc de réinitialisation directement en dessous de la position cible* 3. Déplacez le bloc blanc sous le bloc de réinitialisation* 4. Réinitialisez selon aux étapes prescrites*/ //La première étape if(whiteBlockX==targetX&& whiteBlockY==targetY){ if(whiteBlockX==resetBlockX&&whiteBlockY==resetBlockY+1){//Le bloc de réinitialisation est en dessous de swapWhiteBlockAndCurrentBlock(); } } //La deuxième étape consiste à déplacer le bloc de réinitialisation directement en dessous de la position cible reset2_2(targetX, targetY+1); //La troisième étape déplace le bloc blanc sous le bloc de réinitialisation reset2_3(); //La quatrième étape réinitialise swapWhiteBlockAndCurrentBlock() selon les étapes prescrites ; whiteBlockUp(); ); whiteBlockUp(); whiteBlockRight(); whiteBlockDown(); whiteBlockLeft(); whiteBlockUp(); whiteBlockUp(); whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); } private void resetBlockToTarget(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//Corriger la position sans déplacer le retour ;//Quitter la récursion} if(resetBlockY==targetY){//positive left resetBlockLeft(targetX, targetY); }else{//inférieur gauche, inférieur, inférieur droit if(resetBlockX>=targetX){//inférieur droit||down monter si ; ( resetBlockX==n-1){//Le bloc de réinitialisation est à l'extrême droite, déplacez-vous d'abord vers la gauche pour faciliter le mouvement vers le haut, le bloc blanc dans le sens inverse des aiguilles d'une montre resetBlockLeft(targetX, targetY); }else{ resetBlockUp(targetX, targetY); } }else{//En bas à gauche ; décalage à droite resetBlockRight(targetX, targetY);//Recursion} private void resetBlockRight(int targetX); , int cibleY){ if (resetBlockX == target ; }// System.out.println("resetBlockRight"); if(whiteBlockY<resetBlockY){//Au-dessus de if(whiteBlockY<resetBlockY-1){//Plusieurs lignes au-dessus de whiteBlockDown(); }else{//Une ligne au-dessus de if(whiteBlockX<resetBlockX+1){//En haut à gauche et juste au-dessus de whiteBlockRight (); }else{//en haut à droite whiteBlockDown(); if(whiteBlockY==resetBlockY){//Même ligne if(whiteBlockX<resetBlockX){//Côté gauche if(whiteBlockY==n-1){//À la fin, vous ne pouvez remonter que whiteBlockUp( }else); { whiteBlockDown (); } }else{//right if(whiteBlockX==resetBlockX+1){ swapWhiteBlockAndCurrentBlock(); return;//Quitter la récursion}else{ whiteBlockLeft(); } } }else{//Bottom if(whiteBlockX <= resetBlockX){//En bas à gauche, en bas whiteBlockRight(); }else{//En bas à droite whiteBlockUp(); } } resetBlockRight(targetX, targetY);//recursion} private void resetBlockLeft(int targetX, int targetY){ if (resetBlockX == target / System.out.println("resetBlockLeft"); if(whiteBlockY<resetBlockY){//Au-dessus de if(whiteBlockY<resetBlockY-1){//Plusieurs lignes au-dessus de whiteBlockDown(); }else{//Une ligne au-dessus de if(whiteBlockX==resetBlockX){//Au-dessus de if(whiteBlockX) = =n-1){//À l'extrême droite, le bloc blanc ne peut pas être déplacé vers la droite, mais ne peut être déplacé que vers la gauche whiteBlockLeft(); if(resetBlockY==n-1){//Le bloc de réinitialisation est à l'extrémité la plus basse, le bloc blanc ne peut pas se déplacer dans le sens des aiguilles d'une montre whiteBlockLeft(); }else{ whiteBlockRight(); /En haut à droite if(resetBlockY==n-1){//Le bloc de réinitialisation est à l'extrémité la plus basse, le bloc blanc ne peut pas se déplacer dans le sens des aiguilles d'une montre whiteBlockLeft( }else{); whiteBlockDown(); } }else{//en haut à gauche whiteBlockDown(); } } }else if(whiteBlockY==resetBlockY){//gauche, droite if(whiteBlockX<resetBlockX){//gauche if(whiteBlockX= =resetBlockX- 1){//Un espace à gauche swapWhiteBlockAndCurrentBlock();//Quitter le retour de récursion ; }else{ whiteBlockRight(); } }else{//Right if(whiteBlockY==n-1){//Il est en bas et ne peut pas descendre. Ne peut être déplacé que vers le haut. { whiteBlockUp( ); }else{ whiteBlockRight(); }else{//En bas, en bas à droite whiteBlockLeft(); } } resetBlockLeft(targetX, targetY);//Recursion} private void resetBlockUp(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//La position est correcte sans déplacer le retour;//Quitter la récursion} if( resetBlockY==0){//Le bloc de réinitialisation a atteint le sommet et ne peut pas être déplacé vers le haut return }// System.out.println("resetBlockUp"); if (whiteBlockY < resetBlockY) {//Au-dessus de if(whiteBlockY < resetBlockY - 1){//Plusieurs lignes au-dessus de whiteBlockDown(); }else{//Une ligne au-dessus de if(whiteBlockX); = = resetBlockX){//Le bloc blanc et le bloc reset sont dans la même colonne (colonne verticale) Le bloc blanc et le bloc de réinitialisation échangent directement leurs positions swapWhiteBlockAndCurrentBlock();//Quitter la récursion return; }else{ if(whiteBlockX<resetBlockX){//Le bloc blanc est à gauche du bloc de réinitialisation ; le droit whiteBlockRight(); }else{/ /Le bloc blanc est sur le côté droit du bloc de réinitialisation ; le bloc blanc se déplace vers la gauche whiteBlockLeft(); == resetBlockY) {//Le bloc blanc et le bloc réinitialisé sont sur la même ligne ; le bloc blanc monte if(whiteBlockX<resetBlockX){//Avant à gauche if(whiteBlockX<resetBlockX-1){//Avant à gauche multi -cell whiteBlockRight(); } else{//Un carré à gauche if(whiteBlockY==n-1){//La fin whiteBlockUp( }else {); if(resetBlockX==n-1){//Le bloc de réinitialisation est à l'extrême droite et ne peut pas être déplacé dans le sens inverse des aiguilles d'une montre. whiteBlockUp(); }else{ whiteBlockDown(); /right blancBlockUp (); }else{//Le bloc blanc est en dessous du bloc de réinitialisation. Le bloc blanc doit remonter au-delà du bloc de réinitialisation. Le bloc blanc fait le tour dans le sens inverse des aiguilles d'une montre jusqu'au haut du bloc blanc.//Trois situations : en bas à gauche, en bas, en bas. right if(whiteBlockX<=resetBlockX) {//En bas à gauche, le bloc blanc se déplace vers la droite i f(resetBlockX==n-1){//Le bloc de réinitialisation est à l'extrême droite et ne peut pas être déplacé dans le sens inverse des aiguilles d'une montre. Seul le bloc blanc peut être déplacé dans le sens des aiguilles d'une montre if(whiteBlockX==resetBlockX){//Juste en dessous de whiteBlockLeft(); }else{//En bas à gauche whiteBlockUp(); } }else{ whiteBlockRight(); }else{//En bas à droite ; le bloc blanc monte whiteBlockUp(); /Positions d'échange de blocs blancs et de réinitialisation private void swapWhiteBlockAndCurrentBlock(){ step++; whiteBlockY; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[resetBlockY][resetBlockX]; puzzle[resetBlockY][resetBlockX] = temp; ; resetBlockY = tempY; println("swap"); } private void whiteBlockDown(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY+1][whiteBlockX]; ][whiteBlockX] = temp; whiteBlockY++; println("↓"); whiteBlockUp(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY-1][whiteBlockX]; puzzle[whiteBlockY-1][whiteBlockX] = temp; ; println("↑"); } private void whiteBlockLeft(){ step++; puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX-1]; puzzle[whiteBlockY][whiteBlockX-1] = temp; whiteBlockX--; private void whiteBlockRight(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX+1]; puzzle[whiteBlockY][whiteBlockX+1] = temp; whiteBlockX++; println("→" } @Override public String toString() { StringBuilder sb = nouveau StringBuilder(); sb.append("resetBlock=("+resetBlock+","+resetBlockX+","+resetBlockY+")/n"); if(puzzle!=null){ int len = String.valueOf(n*2-1 ). longueur(); pour (int y = 0; y < n; y++) { pour (int x = 0; x < n; x++) { if(x>0){ sb.append(","); } sb.append(_str(String.valueOf(puzzle[y][x]), len)); ; } sb.append("--------------------------------------"); else{ sb.append("le puzzle est nul"); } return sb.toString(); } private String _str(String str,int len){ str=str==null?"":str; if(str.length()<len){ return _str(str+" ", len); private void println(String str){ if(isPrint){ System.out.println(str); System.out.println(this } } public static void main(String[] args); lance FileNotFoundException, UnsupportedEncodingException {// System.setOut(new PrintStream("e:/puzzle.txt","UTF-8")); Puzzle p = new Puzzle(); p.sort(); } catch (Exception e) { e.printStackTrace(); System.out.println("Exception :"); }enfin{ System.out.println(p); } }}
Ce qui précède représente l’intégralité du contenu de cet article, j’espère que vous l’aimerez tous.