Hoje tive a ideia repentina de fazer um jogo inteligente para minha namorada.
Essas funções precisam ser realizadas, a primeira é customizar a imagem, e a segunda é customizar a grade. Claro, o que pensei no início foi 3*3 4*4 5*5, e não usei. uma grade como 3*5.
A terceira é realizar a função de quebra-cabeça automática. Acredito que todos sabem que as mulheres não são muito boas em jogos, então essa função de quebra-cabeça automática é necessária.
Não vou escrever sobre outras suspensões e classificações!
Agora surge a questão principal: parece que os requisitos para realizar a função de quebra-cabeça automática são um pouco altos! Os computadores podem ser como os humanos e só podem:
Vamos à essência primeiro
Um quebra-cabeça é apenas uma questão de organização:
Existe uma definição de permutação: Em um arranjo de 1, 2,...,n, se as posições anterior e posterior de um par de números estiverem em ordem inversa, ou seja, o número anterior for maior que o número posterior, então eles são chamados de ordem inversa. O número total de ordens reversas em uma permutação é chamado de número de ordem reversa desta permutação. O arranjo em que o número reverso é um número par é chamado de arranjo par; o arranjo em que o número reverso é um número ímpar é chamado de arranjo ímpar. Por exemplo, em 2431, 21, 43, 41 e 31 estão na ordem inversa, e a ordem inversa é 4, o que é um arranjo uniforme.
Aqui está outra definição: ao trocar dois números em uma permutação, a paridade da permutação muda.
As definições acima foram todas retiradas de "Álgebra Avançada".
A disposição do quebra-cabeça deve ser uniforme. Isso pode ser encontrado em minhas referências.
Então é assim que meu quebra-cabeça é implementado!
Estarei escrevendo mais tarde
Referência: http://en.wikipedia.org/wiki/Fifteen_puzzle
Quebra-cabeça automático:
Em primeiro lugar, deve haver certas regras para quebra-cabeças automáticos. De acordo com minha experiência em quebra-cabeças, para completar o quebra-cabeça, diferentes áreas usam regras de quebra-cabeça diferentes, então:
Meu mapa de grade está dividido em 4 áreas (se o mapa de grade tiver n*n grades)
A primeira área: intervalo de coordenadas x 0 a n-2, intervalo de coordenadas y 0 a n-3
Segunda área: coordenada x n-1, intervalo de coordenadas y 0 a n-3
A terceira área: intervalo de coordenadas x 0 a n-3, intervalo de coordenadas y n-2 e n-1
A quarta área: intervalo de coordenadas x n-2 a n-1, intervalo de coordenadas y n-2 e n-1, ou seja, as últimas quatro células;
Cada área pode ser completada de acordo com as regras da respectiva área.
Quebra-cabeça.java
importar java.io.FileNotFoundException;importar java.io.PrintStream;importar java.io.UnsupportedEncodingException;importar java.util.Random;classe pública Puzzle { private long step = 0; [][] puzzle; private int resetBlock = 0;// //Posição do bloco em branco private int whiteBlockX; whiteBlockY; //As coordenadas do bloco a ser movido atualmente são o bloco de reinicialização private int resetBlockX; private int resetBlockY; private boolean isPrint=false; public Puzzle() { init(); 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; // O número de embaralhamentos deve ser um 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) {// Classificação uniforme garantida if((x0 = =n-1&&y0==n-1)||(x1==n-1&&y1==n-1)){//O último não foi substituídocontinue }; vezes--; int t = quebra-cabeça[x0][y0]; quebra-cabeça[x0][y0] = quebra-cabeça[x1][y1]; 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) {//O último está em branco, } else { reset(x, y ) ; } } } } //Redefinir o bloco para a posição de destino private void reset(int targetX, int targetY) { //Encontrar a posição atual do bloco de reinicialização initResetBlock(targetX, targetY); A sequência de reinicialização é da esquerda para a direita, de cima para baixo* O método de movimento é mover primeiro para cima e depois para a esquerda* O bloco de reinicialização atual, a posição que deseja redefinir pode ser dividido em quatro situações* 1. Não está no linha mais à direita nem as duas linhas inferiores * 2. A linha mais à direita x=n-1, mas não as duas linhas inferiores * 3. As duas linhas inferiores y=n-2, mas não a linha mais à direita * 4. a linha mais à direita também é as duas linhas inferiores OK*/ if(targetX < n-1 && targetY < n-2){ if(resetBlockX==targetX&&resetBlockY==targetY){//A posição está correta sem mover o retorno;//Sair da recursão} resetBlockToTarget(targetX, targetY }); senão if( alvoX==n-1 && alvoY < n-2){//O segundo caso if(resetBlockX==targetX&&resetBlockY==targetY){//A posição está correta sem mover return;//Sair da recursão} reset2(targetX, targetY }else if(targetX <); n- 2 && targetY == n-2){// isPrint=true; 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);//recursão} private void initResetBlock(int targetX,int alvoY){ resetBlock = alvoX + alvoY * n; for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (quebra-cabeça[y][x] == resetBlock) {// x, y é a posição do bloco de redefinição 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(); continuar l; if(whiteBlockX>targetX){ whiteBlockLeft(); continuar l;=resetBlock(); puzzle[n-1][targetX]!=(resetBlock+n)){//Nenhuma redefinição foi bem-sucedida // isPrint=true; swapWhiteBlockAndCurrentBlock(); reset3_0(); whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); reset3_0(); void reset2_3(){ if(whiteBlockX==resetBlockX && whiteBlockY==resetBlockY+1){ return;//Se as condições forem atendidas, saia da recursão} //O bloco branco pode estar à esquerda, inferior esquerdo ou inferior lado do bloco de redefinição if(whiteBlockY= =resetBlockY){//left whiteBlockDown() }else if(whiteBlockX < resetBlockX){//inferior esquerdo whiteBlockRight(); }else { whiteBlockUp(); } reset2_3();//recursion} private void reset2_2(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//2. Retorne abaixo;//Sair da recursão} // Possíveis posições do bloco de redefinição, posição de destino à esquerda, diretamente abaixo, inferior esquerdo if(resetBlockX==targetX){//Mover diretamente abaixo e para cima resetBlockUp(targetX, targetY); Mover para a direita e depois para cima resetBlockRight(targetX, targetY } reset2_2(targetX, targetY);//recursão} private void reset2(int targetX, int targetY){ if (resetBlockX == target A parte inferior não é um bloco de reinicialização, mova o bloco branco para a posição de destino* 2. Mova o bloco de reinicialização diretamente abaixo da posição de destino* 3. Mova o bloco branco abaixo do bloco de reinicialização* 4. Reinicialize de acordo seguindo as etapas prescritas*/ //A primeira etapa if(whiteBlockX==targetX&& whiteBlockY==targetY){ if(whiteBlockX==resetBlockX&&whiteBlockY==resetBlockY+1){//O bloco de redefinição está abaixo de swapWhiteBlockAndCurrentBlock(); } } //O segundo passo é mover o bloco de reset diretamente abaixo da posição alvo reset2_2(targetX, targetY+1); //A terceira etapa move o bloco branco abaixo do bloco de redefinição reset2_3(); //A quarta etapa redefine swapWhiteBlockAndCurrentBlock() de acordo com as etapas prescritas; ); brancoBlockUp(); brancoBlockDown(); whiteBlockLeft(); whiteBlockUp(); if(resetBlockX==targetX&&resetBlockY==targetY){//Corrige a posição sem mover o retorno ;//Sair da recursão} if(resetBlockY==targetY){//positivo à esquerda resetBlockLeft(targetX, targetY); }else{//inferior esquerdo, inferior, inferior direito if(resetBlockX>=targetX){//inferior direito||para baixo mover para cima se; ( resetBlockX==n-1){//O bloco de redefinição está na extrema direita, mova primeiro para a esquerda para facilitar o movimento para cima, o bloco branco no sentido anti-horário resetBlockLeft(targetX, targetY); }else{ resetBlockUp(targetX, targetY); //Recursão} private void resetBlockRight(int targetX); , int alvoY){ if (resetBlockX == target; }// System.out.println("resetBlockRight"); if(whiteBlockY<resetBlockY){//Acima if(whiteBlockY<resetBlockY-1){//Várias linhas acima de whiteBlockDown(); }else{//Uma linha acima de if(whiteBlockX<resetBlockX+1){//Canto superior esquerdo e logo acima de whiteBlockRight (); }else{//canto superior direito whiteBlockDown(); if(whiteBlockY==resetBlockY){//Mesma linha if(whiteBlockX<resetBlockX){//Lado esquerdo if(whiteBlockY==n-1){//No final, você só pode subir whiteBlockUp() }else; { whiteBlockDown(); }else{//right if(whiteBlockX==resetBlockX+1){ swapWhiteBlockAndCurrentBlock(); return;//Sair da recursão}else{ whiteBlockLeft(); } } resetBlockRight(targetX, targetY);//recursão} private void resetBlockLeft(int targetX, int targetY){ if (resetBlockX == alvo / System.out.println("resetBlockLeft"); if(whiteBlockY<resetBlockY){//Acima de if(whiteBlockY<resetBlockY-1){//Várias linhas acima de whiteBlockDown();else{//Uma linha acima de if(whiteBlockX==resetBlockX){//Acima de if(whiteBlockX) = =n-1){//Na extrema direita, o bloco branco não pode ser movido para a direita, mas só pode ser movido para a esquerda whiteBlockLeft(); if(resetBlockY==n-1){//O bloco de redefinição está na extremidade inferior, o bloco branco não pode se mover no sentido horário whiteBlockLeft(); /Superior direito if(resetBlockY==n-1){//O bloco de redefinição está na extremidade inferior, o bloco branco não pode se mover no sentido horário whiteBlockLeft() }else{; whiteBlockDown(); } }else{//canto superior esquerdo whiteBlockDown();else if(whiteBlockY==resetBlockY){//esquerda, direita if(whiteBlockX<resetBlockX){//esquerda if(whiteBlockX= =resetBlockX- 1){//Um espaço à esquerda swapWhiteBlockAndCurrentBlock();//Sai do retorno da recursão; }else{ whiteBlockRight(); } }else{//Right if(whiteBlockY==n-1){//Está na parte inferior e não pode ser movido para baixo. Só pode ser movido para cima whiteBlockUp(); }else{ whiteBlockDown(); { whiteBlockUp();else{ whiteBlockRight(); }else{//inferior, canto inferior direito whiteBlockLeft(); } } resetBlockLeft(targetX, targetY);//Recursão} private void resetBlockUp(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//A posição está correta sem mover return;//Sair da recursão} if( resetBlockY==0){//O bloco de redefinição atingiu o topo e não pode ser movido para cima return }// System.out.println("resetBlockUp"); if (whiteBlockY < resetBlockY) {//Acima de if(whiteBlockY < resetBlockY - 1){//Várias linhas acima de whiteBlockDown(); = = resetBlockX){//O bloco branco e o bloco de redefinição estão na mesma coluna (coluna vertical) O bloco branco e o bloco de redefinição trocam de posição diretamente swapWhiteBlockAndCurrentBlock();//Sai do retorno da recursão; }else{ if(whiteBlockX<resetBlockX){//O bloco branco está à esquerda do bloco de redefinição; the right whiteBlockRight(); }else{/ /O bloco branco está no lado direito do bloco de redefinição; o bloco branco se move para a esquerda whiteBlockLeft(); == resetBlockY) {//O bloco branco e o bloco de redefinição estão na mesma linha; o bloco branco sobe if(whiteBlockX<resetBlockX){//Avançar para a esquerda if(whiteBlockX<resetBlockX-1){//Avançar multi para a esquerda -cell whiteBlockRight(); } else{//Um quadrado à esquerda if(whiteBlockY==n-1){//The end whiteBlockUp(); if(resetBlockX==n-1){//O bloco de redefinição está na extrema direita e não pode ser movido no sentido anti-horário. Somente o bloco branco pode ser movido no sentido horário whiteBlockUp() }else{ whiteBlockDown(); /direito brancoBlockUp(); }else{//O bloco branco está abaixo do bloco de redefinição O bloco branco precisa passar pelo bloco de redefinição O bloco branco gira no sentido anti-horário até o topo do bloco branco//Três situações: inferior esquerdo, inferior, inferior. right if(whiteBlockX<=resetBlockX) {//Inferior esquerdo, para baixo; bloco branco se move para a direita i f(resetBlockX==n-1){//O bloco de redefinição está na extrema direita e não pode ser movido no sentido anti-horário. Somente o bloco branco pode ser movido no sentido horário if(whiteBlockX==resetBlockX){//Logo abaixo de whiteBlockLeft(); }else{//Inferior esquerdo whiteBlockUp(); / Bloco branco e redefinição de posições de troca de bloco private void swapWhiteBlockAndCurrentBlock(){ step++; whiteBlockY; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[resetBlockY][resetBlockX]; ;resetBlocoY = tempY; println("swap"); private void whiteBlockDown(){ step++; puzzle[whiteBlockY][whiteBlockX] quebra-cabeça[whiteBlockY+1]; ][whiteBlockX] = temp; whiteBlockY++; whiteBlockUp(){ etapa++; quebra-cabeça[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY-1][whiteBlockX]; ; println("↑"); private void whiteBlockLeft(){ passo++; puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX-1]; puzzle[whiteBlockY][whiteBlockX-1] = temp; private void whiteBlockRight(){ step++; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX+1]; puzzle[whiteBlockY][whiteBlockX+1] = temp; = newStringBuilder(); sb.append("resetBlock=("+resetBlock+","+resetBlockX+","+resetBlockY+")/n"); ).comprimento(); for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if(x>0){ sb.append("," } sb.append(_str(String.valueOf(quebra-cabeça[y][x]), len) } sb.append("/n") ; } sb.append("--------------------------------------"); else{ sb.append("quebra-cabeça é nulo"); 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); lança FileNotFoundException, UnsupportedEncodingException {// System.setOut(new PrintStream("e:/puzzle.txt","UTF-8")); p.sort(); } catch (Exceção e) { e.printStackTrace(); }finalmente{ System.out.println(p);
O texto acima é todo o conteúdo deste artigo, espero que todos gostem.