Hoy tuve la repentina idea de hacer un juego de rompecabezas inteligente para mi novia.
Estas funciones deben realizarse, la primera es personalizar la imagen y la segunda es personalizar la cuadrícula. Por supuesto, lo que pensé al principio fue 3 * 3 4 * 4 5 * 5, y no lo usé. una cuadrícula como 3*5.
El tercero es realizar la función de rompecabezas automático. Creo que todo el mundo sabe que las mujeres no son muy buenas en los juegos, por lo que esta función de rompecabezas automático es necesaria.
¡No escribiré sobre otras suspensiones y clasificaciones!
Ahora surge la pregunta clave. ¡Parece que los requisitos para realizar la función de rompecabezas automático son un poco altos! ¿Pueden las computadoras ser como los humanos y solo pueden:
Vayamos primero a la esencia
En realidad, un rompecabezas es sólo una cuestión de disposición:
Existe una definición de permutación: en una disposición de 1, 2,..., n, si las posiciones anterior y posterior de un par de números están en orden inverso, es decir, el número anterior es mayor que el número posterior, entonces se les llama orden inverso. El número total de órdenes inversos en una permutación se denomina número de orden inverso de esta permutación. La disposición en la que el número inverso es un número par se denomina disposición par; la disposición en la que el número inverso es un número impar se denomina disposición impar. Por ejemplo, en 2431, 21, 43, 41 y 31 están en orden inverso, y el orden inverso es 4, que es una disposición par.
Aquí hay otra definición: al intercambiar dos números en una permutación, la paridad de la permutación cambia.
Todas las definiciones anteriores están tomadas de "Álgebra avanzada".
La disposición del rompecabezas debe ser uniforme. Esto se puede encontrar en mis referencias.
¡Así es como se implementa mi rompecabezas!
Estaré escribiendo más tarde
Referencia: http://en.wikipedia.org/wiki/Fifteen_puzzle
Rompecabezas automático:
En primer lugar, debe haber ciertas reglas para los rompecabezas automáticos. Según mi experiencia con los rompecabezas, para completar el rompecabezas, diferentes áreas usan diferentes reglas de rompecabezas, por lo que:
Mi mapa de cuadrícula está dividido en 4 áreas (si el mapa de cuadrícula tiene n*n cuadrículas)
La primera área: rango de coordenadas x 0 a n-2, rango de coordenadas y 0 a n-3
Segunda área: coordenada x n-1, rango de coordenadas y 0 a n-3
La tercera área: rango de coordenadas x 0 a n-3, rango de coordenadas y n-2 y n-1
La cuarta área: rango de coordenadas x n-2 a n-1, rango de coordenadas y n-2 y n-1, es decir, las últimas cuatro celdas;
Cada área se puede completar de acuerdo con las reglas del área respectiva.
rompecabezas.java
import java.io.FileNotFoundException;import java.io.PrintStream;import java.io.UnsupportedEncodingException;import java.util.Random; public class Puzzle { private long step = 0; [][] rompecabezas; private int resetBlock = 0;// // Posición del bloque en blanco private int whiteBlockX privado int; whiteBlockY; // Las coordenadas del bloque que se va a mover actualmente son el bloque de reinicio private int resetBlockX; private int resetBlockY; private boolean isPrint=false; public Puzzle() { init(); public Puzzle(int n) { this. n = n; init(); } private void init() { rompecabezas = nuevo int[n][n]; y++) { for (int x = 0; x < n; x++) { rompecabezas[y][x] = x + y * n; whiteBlockX = n-1; whiteBlockY = n-1; // El número de mezclas debe ser un número par. 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) {// Ordenación uniforme garantizada if((x0 = =n-1&&y0==n-1)||(x1==n-1&&y1==n-1)){//El último no se reemplazacontinue } veces--; int t = rompecabezas[x0][y0]; rompecabezas[x0][y0] = rompecabezas[x1][y1]; rompecabezas[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}};// rompecabezas = 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) {// El último está en blanco, } else { reset(x, y ) ; } } } } //Restablece el bloque a la posición de destino private void reset(int targetX, int targetY) { //Encuentra la posición actual del bloque de reinicio initResetBlock(targetX, targetY); La secuencia de reinicio es de izquierda a derecha, de arriba a abajo* El método de movimiento es moverse hacia arriba primero, luego hacia la izquierda* El bloque de reinicio actual, la posición que desea restablecer se puede dividir en cuatro situaciones* 1. No en el fila más a la derecha ni las dos filas inferiores * 2. La fila más a la derecha x=n-1, pero no las dos filas inferiores * 3. Las dos filas inferiores y=n-2, pero no la fila más a la derecha * 4. La fila más a la derecha también son las dos filas inferiores. OK*/ if(targetX < n-1 && targetY < n-2){ if(resetBlockX==targetX&&resetBlockY==targetY){//La posición es correcta sin mover return;//Salir de la recursión} resetBlockToTarget(targetX, targetY }); de lo contrario si (objetivoX==n-1 && objetivoY < n-2){//El segundo caso if(resetBlockX==targetX&&resetBlockY==targetY){//La posición es correcta sin moverse return;//Salir de la recursión} reset2(targetX, targetY }else if(targetX <); n- 2 && targetY == n-2){// isPrint=true; reset3(targetX return); 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 objetivoY){ resetBlock = objetivoX + objetivoY * n; for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (puzzle[y][x] == resetBlock) {// x, y es la posición del bloque de reinicio resetBlockX = x; resetBlockY = y break; if(targetX>=2){// } initResetBlock(targetX, n-1); resetBlockToTarget(targetX, n-2); initResetBlock(targetX, n-2); : mientras (!(whiteBlockX==targetX && whiteBlockY==n-1)) { if(whiteBlockY<n-1){ whiteBlockDown(); continuar l; } if(whiteBlockX>targetX){ whiteBlockLeft(); continuar l; } break } whiteBlockUp(); swapWhiteBlockAndCurrentBlock(); rompecabezas[n-1][targetX]!=(resetBlock+n)){//Sin reinicio exitoso// isPrint=true; swapWhiteBlockAndCurrentBlock(); reset3_0(); reset3(targetX); } } whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); reset3_0(); retorno } retorno } privado void reset2_3(){ if(whiteBlockX==resetBlockX && whiteBlockY==resetBlockY+1){ return;//Si se cumplen las condiciones, salga de la recursividad} //El bloque blanco puede estar a la izquierda, abajo a la izquierda o abajo lado del bloque de reinicio 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. Volver abajo;//Salir de la recursividad} // Posibles posiciones del bloque de reinicio, posición de destino a la izquierda, directamente debajo, abajo a la izquierda if(resetBlockX==targetX){//Mover directamente hacia abajo y hacia arriba resetBlockUp(targetX, targetY }else{//Left o lower left first); Muévase hacia la derecha y luego hacia arriba resetBlockRight(targetX, targetY } reset2_2(targetX, targetY);//recursion} private void reset2(int targetX, int targetY){ if (resetBlockX == target La parte inferior no es un bloque de reinicio, mueva el bloque blanco a la posición de destino* 2. Mueva el bloque de reinicio directamente debajo de la posición de destino* 3. Mueva el bloque blanco debajo del bloque de reinicio* 4. Reinicie de acuerdo a los pasos prescritos*/ // El primer paso if(whiteBlockX==targetX&& whiteBlockY==targetY){ if(whiteBlockX==resetBlockX&&whiteBlockY==resetBlockY+1){// El bloque de reinicio está debajo de swapWhiteBlockAndCurrentBlock() return; } } //El segundo paso es mover el bloque de reinicio directamente debajo de la posición objetivo reset2_2(targetX, targetY+1); //El tercer paso mueve el bloque blanco debajo del bloque de reinicio reset2_3(); //El cuarto paso reinicia swapWhiteBlockAndCurrentBlock() de acuerdo con los pasos prescritos; whiteBlockUp(); ); whiteBlockUp(); whiteBlockRight(); blancoBlockDown(); whiteBlockLeft(); whiteBlockUp(); whiteBlockUp(); whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); private void resetBlockToTarget(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//Posición correcta sin mover ;//Salir de la recursividad} if(resetBlockY==targetY){//positive left resetBlockLeft(targetX, targetY); }else{//abajo a la izquierda, abajo, abajo a la derecha if(resetBlockX>=targetX){//abajo a la derecha||abajo; ( resetBlockX==n-1){// El bloque de reinicio está en el extremo derecho, muévase primero hacia la izquierda para facilitar el movimiento hacia arriba, el bloque blanco en sentido antihorario resetBlockLeft(targetX, targetY); }else{ resetBlockUp(targetX, targetY); } }else{//Abajo a la izquierda; resetBlockRight(targetX, targetY } } resetBlockToTarget(targetX, targetY);//Recursion} private void resetBlockRight(int targetX); , int objetivoY){ if (resetBlockX == destino; }// System.out.println("resetBlockRight"); if(whiteBlockY<resetBlockY){//Arriba if(whiteBlockY<resetBlockY-1){//Varias líneas arriba de whiteBlockDown() }else{//Una fila arriba if(whiteBlockX<resetBlockX+1){//Arriba a la izquierda y justo encima de whiteBlockRight (); }else{//arriba a la derecha whiteBlockDown(); if(whiteBlockY==resetBlockY){//Misma línea if(whiteBlockX<resetBlockX){//Lado izquierdo if(whiteBlockY==n-1){//Al final, solo puedes subir whiteBlockUp() }else; { whiteBlockDown (); } }else{//right if(whiteBlockX==resetBlockX+1){ swapWhiteBlockAndCurrentBlock(); return;//Salir de la recursión}else{ whiteBlockLeft(); } } }else{//Abajo if(whiteBlockX <= resetBlockX){//Abajo a la izquierda, abajo whiteBlockRight() }else{//Abajo a la derecha whiteBlockUp(); } } resetBlockRight(targetX, targetY);//recursion} private void resetBlockLeft(int targetX, int targetY){ if (resetBlockX == destino / System.out.println("resetBlockLeft"); if(whiteBlockY<resetBlockY){//Above if(whiteBlockY<resetBlockY-1){//Varias líneas arriba de whiteBlockDown(); }else{//Una fila arriba de if(whiteBlockX==resetBlockX){//Above if(whiteBlockX) = =n-1){// En el extremo derecho, el bloque blanco no se puede mover hacia la derecha, solo se puede mover hacia la izquierda whiteBlockLeft() }else{ if(resetBlockY==n-1){//El bloque de reinicio está en el extremo inferior, el bloque blanco no puede moverse en el sentido de las agujas del reloj whiteBlockLeft(); }else{ whiteBlockRight(); /Arriba derecha if(resetBlockY==n-1){//El bloque de reinicio está en el extremo inferior, el bloque blanco no puede moverse en el sentido de las agujas del reloj whiteBlockLeft() }else{; whiteBlockDown(); } }else{//arriba a la izquierda whiteBlockDown(); } } }else if(whiteBlockY==resetBlockY){//izquierda, derecha if(whiteBlockX<resetBlockX){//left if(whiteBlockX= =resetBlockX- 1){//Un espacio a la izquierda swapWhiteBlockAndCurrentBlock();//Salir de la recursividad return; }else{ whiteBlockRight(); } }else{//Derecha si(whiteBlockY==n-1){//Está en la parte inferior y no puede moverse hacia abajo. Solo se puede mover hacia arriba whiteBlockUp(); }else{ whiteBlockDown(); } } }else{//Abajo izquierda, abajo, abajo derecha if(whiteBlockX<resetBlockX){//Abajo izquierda if(whiteBlockX==resetBlockX-1) { whiteBlockUp() }else{ whiteBlockRight(); } }else{//Abajo, abajo a la derecha whiteBlockLeft(); } } resetBlockLeft(targetX, targetY);//Recursion} private void resetBlockUp(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//La posición es correcta sin moverse return;//Salir de la recursión} if( resetBlockY==0){//El bloque de reinicio ha llegado a la parte superior y no se puede subir return }// System.out.println("resetBlockUp"); if (whiteBlockY < resetBlockY) {//Above if(whiteBlockY < resetBlockY - 1){//Varias líneas arriba de whiteBlockDown() }else{//Una fila arriba de if(whiteBlockX); = = resetBlockX){//El bloque blanco y el bloque de reinicio están en la misma columna (columna vertical) El bloque blanco y el bloque de reinicio intercambian posiciones directamente swapWhiteBlockAndCurrentBlock();//Salir de la recursividad return; }else{ if(whiteBlockX<resetBlockX){//El bloque blanco está a la izquierda del bloque de reinicio; the right whiteBlockRight(); }else{/ /El bloque blanco está en el lado derecho del bloque de reinicio; el bloque blanco se mueve hacia la izquierda whiteBlockLeft(); == resetBlockY) {//El bloque blanco y el bloque de reinicio están en la misma fila. El bloque blanco se mueve hacia arriba if(whiteBlockX<resetBlockX){//Adelante hacia la izquierda if(whiteBlockX<resetBlockX-1){//Adelante hacia la izquierda multi; -cell whiteBlockRight(); } else{//Un cuadrado a la izquierda if(whiteBlockY==n-1){//El final whiteBlockUp() }else { if(resetBlockX==n-1){//El bloque de reinicio está en el extremo derecho y no puede moverse en sentido antihorario. Solo el bloque blanco se puede mover en el sentido de las agujas del reloj whiteBlockUp(); }else{ whiteBlockDown(); /derecha whiteBlockUp (); }else{//El bloque blanco está debajo del bloque de reinicio. El bloque blanco debe pasar más allá del bloque de reinicio. El bloque blanco gira en sentido antihorario hasta la parte superior del bloque blanco. // Tres situaciones: abajo a la izquierda, abajo, abajo. derecha si (whiteBlockX<=resetBlockX) {//Abajo a la izquierda, abajo el bloque blanco se mueve hacia la derecha i; f(resetBlockX==n-1){//El bloque de reinicio está en el extremo derecho y no puede moverse en el sentido contrario a las agujas del reloj. Solo el bloque blanco se puede mover en el sentido de las agujas del reloj if(whiteBlockX==resetBlockX){//Justo debajo de whiteBlockLeft(); }else{//Abajo a la izquierda whiteBlockUp(); } }else{ whiteBlockRight(); } }else{//Abajo a la derecha; el bloque blanco sube whiteBlockUp(); resetBlockUp(targetX, targetY);//Recursion} /Bloque blanco y restablecer posiciones de intercambio de bloque private void swapWhiteBlockAndCurrentBlock(){ step++ int tempX = whiteBlockX,tempY =; whiteBlockY; int temp = rompecabezas[whiteBlockY][whiteBlockX]; rompecabezas[whiteBlockY][whiteBlockX] = rompecabezas[resetBlockY][resetBlockX] rompecabezas[resetBlockY][resetBlockX] = tempX; ; restablecerBloqueY = temporalY; println("intercambiar"); } private void whiteBlockDown(){ paso++; rompecabezas[whiteBlockY][whiteBlockX]; rompecabezas[whiteBlockY][whiteBlockX] = rompecabezas[whiteBlockY+1][whiteBlockX]; ][BloqueblancoX] = temporal;BloqueblancoY++; println("↓"); whiteBlockUp(){ paso++; int temp = rompecabezas[whiteBlockY][whiteBlockX]; rompecabezas[whiteBlockY][whiteBlockX] = whiteBlockY-- ; println(" ↑"); } privado vacío whiteBlockLeft(){ paso++; rompecabezas[BloqueblancoY][BloqueblancoX]; rompecabezas[BloqueblancoY][BloqueblancoX] = rompecabezas[BloqueblancoY][BloqueblancoX-1]; rompecabezas[BloqueblancoY][BloqueblancoX-1] = temp; private void whiteBlockRight(){ paso++ int temp = rompecabezas[whiteBlockY][whiteBlockX]; rompecabezas[whiteBlockY][whiteBlockX] = rompecabezas[whiteBlockY][whiteBlockX+1]; rompecabezas[whiteBlockY][whiteBlockX+1] = temp; whiteBlockX++; = nuevo StringBuilder(); sb.append("resetBlock=("+resetBlock+","+resetBlockX+","+resetBlockY+")/n"); if(puzzle!=null){ int len = String.valueOf(n*2-1 ). longitud(); para (int y = 0; y < n; y++) { para (int x = 0; x < n; x++) { if(x>0){ sb.append("," } sb.append(_str(String.valueOf(puzzle[y][x]), len) } sb.append("/n") ; } sb.append("---------------------------------"); else{ sb.append("el rompecabezas es nulo"); return sb.toString(); } cadena privada _str(String str,int len){ str=str==null?"":str; if(str.length()<len){ return _str(str+" ", len) return str; private void println(String str){ if(isPrint){ System.out.println(str); System.out.println(this); public static void main(String[] args) lanza FileNotFoundException, UnsupportedEncodingException {// System.setOut(new PrintStream("e:/puzzle.txt","UTF-8")); p.sort(); } catch (Excepción e) { e.printStackTrace(); System.out.println("Excepción:"); }finalmente{ System.out.println(p);
Lo anterior es el contenido completo de este artículo, espero que les guste a todos.