Heute hatte ich plötzlich die Idee, ein cleveres Puzzlespiel für meine Freundin zu machen.
Diese Funktionen müssen realisiert werden. Die erste besteht darin, das Bild anzupassen, und die zweite besteht darin, das Raster anzupassen. Natürlich habe ich am Anfang an 3 * 3 4 * 4 5 * 5 gedacht und sie nicht verwendet ein Raster wie 3*5.
Die dritte besteht darin, die automatische Puzzle-Funktion zu realisieren. Ich glaube, jeder weiß, dass Frauen nicht sehr gut in Spielen sind, daher ist diese automatische Puzzle-Funktion notwendig.
Über andere Sperren und Platzierungen werde ich nicht schreiben!
Jetzt stellt sich die entscheidende Frage. Es scheint, dass die Anforderungen für die Realisierung der automatischen Puzzle-Funktion etwas hoch sind! Können Computer wie Menschen sein und können nur:
Kommen wir zunächst zum Wesentlichen
Ein Puzzle ist eigentlich nur eine Frage der Anordnung:
Es gibt eine Definition für Permutation: Wenn in einer Anordnung von 1, 2,...,n die vordere und hintere Position eines Zahlenpaares in umgekehrter Reihenfolge sind, d. h. die vordere Zahl größer als die hintere Zahl ist, dann nennt man sie eine umgekehrte Reihenfolge. Die Gesamtzahl der umgekehrten Ordnungen in einer Permutation wird als umgekehrte Ordnungszahl dieser Permutation bezeichnet. Die Anordnung, bei der die Umkehrzahl eine gerade Zahl ist, wird als gerade Anordnung bezeichnet; die Anordnung, bei der die Umkehrzahl eine ungerade Zahl ist, wird als ungerade Anordnung bezeichnet. In 2431 sind beispielsweise 21, 43, 41 und 31 in umgekehrter Reihenfolge, und die umgekehrte Reihenfolge ist 4, was einer geraden Anordnung entspricht.
Hier ist eine andere Definition: Durch den Austausch zweier Zahlen in einer Permutation ändert sich die Parität der Permutation.
Die obigen Definitionen stammen alle aus „Advanced Algebra“.
Die Puzzle-Anordnung muss gleichmäßig sein. Dies finden Sie in meinen Referenzen.
So ist also mein Rätsel umgesetzt!
Werde später schreiben
Referenz: http://en.wikipedia.org/wiki/Fifteen_puzzle
Automatisches Puzzle:
Erstens sollte es bestimmte Regeln für automatische Rätsel geben. Um das Rätsel zu lösen, verwenden verschiedene Bereiche unterschiedliche Rätselregeln, also:
Meine Gitterkarte ist in 4 Bereiche unterteilt (wenn die Gitterkarte n*n Gitter hat)
Der erste Bereich: x-Koordinatenbereich 0 bis n-2, y-Koordinatenbereich 0 bis n-3
Zweiter Bereich: x-Koordinate n-1, y-Koordinatenbereich 0 bis n-3
Der dritte Bereich: x-Koordinatenbereich 0 bis n-3, y-Koordinatenbereich n-2 und n-1
Der vierte Bereich: x-Koordinatenbereich n-2 bis n-1, y-Koordinatenbereich n-2 und n-1, also die letzten vier Zellen
Jeder Bereich kann nach den Regeln des jeweiligen Bereichs absolviert werden.
Puzzle.java
import java.io.FileNotFoundException;import java.io.PrintStream;import java.io.UnsupportedEncodingException;import java.util.Random; public class Puzzle { private long step = 0; private int n = 6;//Platform base private int [][] puzzle; private int resetBlock = 0;// //Leere Blockposition private int whiteBlockX; whiteBlockY; //Die Koordinaten des Blocks, der gerade verschoben werden soll, sind der Reset-Block private int resetBlockY; private boolean isPrint=false; public Puzzle(int n) { this. n = n; init(); } private void init() { puzzle = new int[n][n] for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { puzzle[y][x] = x + y * n; } } whiteBlockX = n-1; whiteBlockY = n-1; // Die Anzahl der Mischvorgänge muss eine gerade Zahl sein. Random random = new Random(); while (times > 0) { int x0 = int y0 = random.nextInt(n); int x1 = random.nextInt(n); if (x0 != x1 && y0!=y1) {// Garantiert gleichmäßige Sortierung if((x0 = =n-1&&y0==n-1)||(x1==n-1&&y1==n-1)){//Das letzte wird nicht ersetztcontinue } times--; int t = puzzle[x0][y0] = 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) {//Das letzte ist leer, } else { reset(x, y ) ; } } } //Setze den Block auf die Zielposition zurück private void reset(int targetX, int targetY) { //Finde die aktuelle Position des Reset-Blocks initResetBlock(targetX, targetY); Die Rücksetzsequenz ist von links nach rechts, von oben nach unten* Die Bewegungsmethode besteht darin, sich zuerst nach oben und dann nach links zu bewegen* Der aktuelle Rücksetzblock, die Position, die er zurücksetzen möchte, kann in vier Situationen unterteilt werden* 1. Nicht in der Zeile ganz rechts noch die beiden unteren Zeilen * 2. Die Zeile ganz rechts x=n-1, aber nicht die beiden Zeilen unten y=n-2, aber nicht die Zeile ganz rechts; Die Zeile ganz rechts ist auch die untersten beiden Zeilen. OK*/ if(targetX < n-1 && targetY < n-2){ if(resetBlockX==targetX&&resetBlockY==targetY){//Die Position ist korrekt, ohne dass die Rekursion verschoben wird} resetBlockToTarget(targetX, targetY); } sonst if( targetX==n-1 && targetY < n-2){//Der zweite Fall if(resetBlockX==targetX&&resetBlockY==targetY){//Die Position ist korrekt, ohne die Rekursion zu verschieben} reset2(targetX, targetY); }else if(targetX < n- 2 && targetY == n-2){// isPrint=true; reset3(targetX) }else{ initResetBlock(n-2, n-2); resetBlockToTarget(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);//recursion} private void initResetBlock(int targetX,int targetY){ resetBlock = targetX + targetY * n; for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (puzzle[y][x] == resetBlock) {// x, y ist die Position des Reset-Blocks resetBlockX = x; resetBlockY = y; if(targetX>=2){// } initResetBlock(targetX, n-1); resetBlockToTarget(targetX, n-2); : while (!(whiteBlockX==targetX && whiteBlockY==n-1)) { if(whiteBlockY<n-1){ whiteBlockDown(); continue l; puzzle[n-1][targetX]!=(resetBlock+n)){//Kein Zurücksetzen erfolgreich// isPrint=true; swapWhiteBlockRight(); reset3(targetX); swapWhiteBlockAndCurrentBlock(); reset3_0(); return; void reset2_3(){ if(whiteBlockX==resetBlockX && whiteBlockY==resetBlockY+1){ return;//Wenn die Bedingungen erfüllt sind, beenden Sie die Rekursion} //Der weiße Block kann sich links, unten links oder unten befinden Seite des Reset-Blocks if(whiteBlockY= =resetBlockY){//left whiteBlockDown(); }else if(whiteBlockX < resetBlockX){//lower left whiteBlockRight(); }else { whiteBlockUp(); } reset2_3();//recursion} private void reset2_2(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//2 Rückkehr nach unten;//Rekursion beenden} //Mögliche Positionen des Reset-Blocks, Zielposition links, direkt darunter, unten links if(resetBlockX==targetX){//Bewegen Sie sich direkt darunter und nach oben resetBlockUp(targetX, targetY); }else{//Links oder unten links zuerst; Nach rechts und dann nach oben bewegen resetBlockRight(targetX, targetY); } reset2_2(targetX, targetY);//recursion} private void reset2(int targetX, int targetY){ if (resetBlockX == target Der Boden ist kein Reset-Block, verschieben Sie den weißen Block an die Zielposition* 2. Bewegen Sie den Reset-Block direkt unter die Zielposition* 3. Bewegen Sie den weißen Block unter den Reset-Block* 4. Setzen Sie entsprechend zurück zu den vorgeschriebenen Schritten*/ //Der erste Schritt if(whiteBlockX==targetX&& whiteBlockY==targetY){ if(whiteBlockX==resetBlockX&&whiteBlockY==resetBlockY+1){//Der Reset-Block liegt unter swapWhiteBlockAndCurrentBlock(); } } //Der zweite Schritt besteht darin, den Reset-Block direkt unter die Zielposition zu verschieben reset2_2(targetX, targetY+1); //Der dritte Schritt verschiebt den weißen Block unter den Reset2_3(); //Der vierte Schritt setzt swapWhiteBlockLeft(); whiteBlockRight(); ); whiteBlockUp(); whiteBlockDown(); whiteBlockLeft(); whiteBlockUp(); whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); ;//Rekursion beenden} if(resetBlockY==targetY){//positive left resetBlockLeft(targetX, targetY); }else{//unten links, unten, unten rechts if(resetBlockX>=targetX){//unten rechts||down; nach oben verschieben (resetBlockX==n-1){//Der Reset-Block befindet sich ganz rechts. Bewegen Sie sich zuerst nach links, um die Aufwärtsbewegung zu erleichtern, der weiße Block gegen den Uhrzeigersinn resetBlockLeft(targetX, targetY); }else{ resetBlockUp(targetX, targetY); }else{//Lower left; , int targetY){ if (resetBlockX == target ; }// System.out.println("resetBlockRight"); if(whiteBlockY<resetBlockY){//Oben if(whiteBlockY<resetBlockY-1){//Mehrere Zeilen darüber whiteBlockDown(); }else{//Eine Zeile darüber if(whiteBlockX<resetBlockX+1){//Oben links und rechts oben whiteBlockRight (); }else{//upper right whiteBlockDown(); if(whiteBlockY==resetBlockY){//Gleiche Zeile if(whiteBlockX<resetBlockX){//Linke Seite if(whiteBlockY==n-1){//Am Ende können Sie nur nach oben gehen, whiteBlockUp( }else { whiteBlockDown (); } }else{//right if(whiteBlockX==resetBlockX+1){ swapWhiteBlockAndCurrentBlock(); return;//Rekursion beenden}else{ whiteBlockLeft(); } } }else{//Bottom if(whiteBlockX <= resetBlockX){//Bottom left, Bottom whiteBlockRight(); }else{//Bottom right whiteBlockUp(); } } resetBlockRight(targetX, targetY);//recursion} private void resetBlockLeft(int targetX, int targetY){ if (resetBlockX == target / System.out.println("resetBlockLeft"); if(whiteBlockY<resetBlockY){//Above if(whiteBlockY<resetBlockY-1){//Mehrere Zeilen über whiteBlockDown(); }else{//Eine Zeile über if(whiteBlockX==resetBlockX){//Above if(whiteBlockX = =n-1){//Ganz rechts kann der weiße Block nicht nach rechts verschoben werden, sondern nur nach links. whiteBlockLeft( }else{); if(resetBlockY==n-1){//Der Reset-Block befindet sich am untersten Ende, der weiße Block kann sich nicht im Uhrzeigersinn bewegen whiteBlockLeft(); }else{ whiteBlockRight(); }else if(whiteBlockX>resetBlockX){/ /Upper right if(resetBlockY==n-1){//Der Reset-Block befindet sich am untersten Ende, der weiße Block kann sich nicht im Uhrzeigersinn bewegen whiteBlockLeft() }else{ whiteBlockDown(); } }else{//upper left whiteBlockDown(); } } }else if(whiteBlockY==resetBlockY){//left, right if(whiteBlockX<resetBlockX){//left if(whiteBlockX= =resetBlockX- 1){//Ein Leerzeichen auf der linken Seite swapWhiteBlockAndCurrentBlock();//Verlassen Sie die Rekursion return; }else{ whiteBlockRight(); } }else{//Right if(whiteBlockY==n-1){//Es ist unten und kann nicht nach unten verschoben werden. Kann nur nach oben verschoben werden: whiteBlockUp(); }else{ whiteBlockDown(); } } }else{//Unten links, unten, unten rechts if(whiteBlockX<resetBlockX){//Unten links if(whiteBlockX==resetBlockX-1) { whiteBlockUp( ); }else{ whiteBlockRight( } }else{//Bottom, unten rechts whiteBlockLeft(); } } resetBlockLeft(targetX, targetY);//Recursion} private void resetBlockUp(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//Die Position ist korrekt, ohne sich zu bewegen return;//Rekursion beenden} if( resetBlockY==0){//Der Reset-Block hat die Spitze erreicht und kann nicht nach oben verschoben werden return }// System.out.println("resetBlockUp"); if (whiteBlockY < resetBlockY) {//Above if(whiteBlockY < resetBlockY - 1){//Mehrere Zeilen über whiteBlockDown(); }else{//Eine Zeile über if(whiteBlockX = = resetBlockX){//Der weiße Block und der Reset-Block befinden sich in derselben Spalte (vertikale Spalte) Der weiße Block und der Reset-Block tauschen direkt die Positionen swapWhiteBlockAndCurrentBlock();//Verlassen Sie die Rekursion return; }else{ if(whiteBlockX<resetBlockX){//Der weiße Block befindet sich links vom Reset-Block; the right whiteBlockRight(); }else{/ /Der weiße Block befindet sich auf der rechten Seite des Reset-Blocks; == resetBlockY) {//Der weiße Block und der Reset-Block befinden sich in derselben Zeile; der weiße Block bewegt sich nach oben, if(whiteBlockX<resetBlockX){//Forward left if(whiteBlockX<resetBlockX-1){//Forward left multi -cell whiteBlockRight(); } else{//Ein Quadrat nach links if(whiteBlockY==n-1){//The end whiteBlockUp( }else {); if(resetBlockX==n-1){//Der Reset-Block befindet sich ganz rechts und kann nicht im Uhrzeigersinn verschoben werden. whiteBlockUp( }else{ whiteBlockDown(); /right whiteBlockUp (); }else{//Der weiße Block befindet sich unter dem Reset-Block. Der weiße Block bewegt sich gegen den Uhrzeigersinn zum oberen Rand des weißen Blocks.//Drei Situationen: unten links, unten, unten right if(whiteBlockX<=resetBlockX) {//Unten links, nach unten; weißer Block bewegt sich nach rechts i f(resetBlockX==n-1){//Der Reset-Block befindet sich ganz rechts und kann nicht gegen den Uhrzeigersinn verschoben werden. if(whiteBlockX==resetBlockX){//Direkt unterhalb von whiteBlockLeft(); }else{//Lower left whiteBlockUp(); }else{ whiteBlockRight(); }else{//Lower right blockUp(targetX, targetY);//Recursion} / /White Block und Reset Block Swap-Positionen private void swapWhiteBlockAndCurrentBlock(){ step++; whiteBlockY; int temp = puzzle[whiteBlockY][whiteBlockX] = puzzle[resetBlockY][resetBlockX] = temp; whiteBlockY = resetBlockY; ; resetBlockY = tempY; println("swap"); } private void whiteBlockDown(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY+1][whiteBlockY+1 ][whiteBlockX] = temp; whiteBlockY++; println("↓" } private void whiteBlockUp(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY-1][whiteBlockX] = temp; ; println(" ↑"); } private void whiteBlockLeft(){ step++; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX--; private void whiteBlockRight(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX+1] = temp; whiteBlockX++; @Override public String toString() { StringBuilder sb = neuer StringBuilder(); sb.append("resetBlock=("+resetBlock+","+resetBlockX+","+resetBlockY+")/n"); if(puzzle!=null){ int len = String.valueOf(n*2-1 ). length(); for (int y = 0; y < n; y++) { for (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("puzzle is null" } 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(this); } public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {// System.setOut(new PrintStream("e:/puzzle.txt","UTF-8")); p.sort(); } Catch (Exception e) { e.printStackTrace(); System.out.println("Exception:"); }finally{ System.out.println(p);
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er gefällt Ihnen allen.