Java制造智能拼圖游戲道理及代碼。本站提示廣大學習愛好者:(Java制造智能拼圖游戲道理及代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是Java制造智能拼圖游戲道理及代碼正文
明天突發奇想,想做一個智能拼圖游戲來給哄女友。
須要完成這些功效
第一圖片自界說
第二宮格自界說,固然我一開端就想的是3*3 4*4 5*5,沒有應用3*5如許的宮格。
第三要完成主動拼圖的功效,信任年夜家曉得女人耍游戲都不是很凶猛,所以這個主動拼圖功效得有。
其他甚麼暫停、排行就不寫了!
如今重點成績出來了
要完成主動拼圖功效仿佛請求有點高哦!盤算機有可不克不及像人一樣只能:
先窮究下實質
拼圖游戲其實就是分列成績:
分列有這麼一個界說:在一個1,2,...,n的分列中,假如一對數的前後地位與年夜小次序相反,即後面的數年夜於前面的數,那末它們就稱為一個逆序。一個分列中逆序的總數就稱為這個分列的逆序數。逆序數為偶數的分列稱為偶分列;逆序數為奇數的分列稱為奇分列。如2431中,21,43,41,31是逆序,逆序數是4,為偶分列。
再來一個界說:交流一個分列中的兩個數,則分列的奇偶性產生轉變。
以上界說都摘自《高級代數》。
拼圖分列必需是偶分列。這個在我參考文獻中可以找到。
所以我的只能拼圖是如許完成的!
後續在寫
參考:http://en.wikipedia.org/wiki/Fifteen_puzzle
主動拼圖:
起首主動拼圖應當有必定的規矩,依據我拼圖的經歷,要完成拼圖,分歧區域應用的拼圖規矩是分歧的,所以:
我的宮格圖分為了4個區域(假設宮格圖是n*n個格子)
第一個區域:x坐標規模 0到n-2,y坐標規模 0到n-3
第二個區域:x坐標n-1,y坐標規模 0到n-3
第三個區域:x坐標規模 0到n-3 ,y坐標規模 n-2和n-1
第四個區域:x坐標規模 n-2到n-1 ,y坐標規模 n-2和n-1;即最初四格
每一個區域依照各自區域的規矩便可完成
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;// 宮格基數 private int[][] puzzle; private int resetBlock = 0;// //空白塊地位 private int whiteBlockX; private int whiteBlockY; //以後要預備挪動的塊的坐標即復位塊 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]; 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; int times = 100;// 打亂次數,必需是偶數 Random random = new Random(); while (times > 0) { int x0 = random.nextInt(n); int y0 = random.nextInt(n); int x1 = random.nextInt(n); int y1 = random.nextInt(n); if (x0 != x1 && y0!=y1) {// 包管是偶排序 if((x0==n-1&&y0==n-1)||(x1==n-1&&y1==n-1)){//最初一個不更換 continue; } times--; int t = puzzle[x0][y0]; puzzle[x0][y0] = puzzle[x1][y1]; puzzle[x1][y1] = t; } } // int[][] 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) {// 最初一個為空白, } else { reset(x, y); } } } } //把塊復位挪動目的地位 private void reset(int targetX, int targetY) { // 找到復位塊以後的地位 initResetBlock(targetX, targetY); /* * 復位次序是從左到右,從上到下 * 挪動方法 先上挪動,再左挪動 * 以後復位塊,它要復位的地位可分為 四種情形 * 1、不在最左邊一行也不是最上面兩行 * 2、最左邊一行 x=n-1,但不是上面兩行; * 3、最上面兩行 y=n-2,但不是最左邊一行; * 4、即便最左邊的一行也是最上面兩行 */ if(targetX < n-1 && targetY < n-2){ if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } resetBlockToTarget(targetX, targetY); }else if(targetX==n-1 && targetY < n-2){//第二種情形 if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } reset2(targetX, targetY); }else if(targetX < n-2 && targetY == n-2){ // isPrint=true; reset3(targetX); return; }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);//遞歸 } 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就是復位塊的地位 resetBlockX = x; resetBlockY = y; break; } } } } private void reset3(int targetX){ // if(targetX>=2){ // } initResetBlock(targetX, n-1); resetBlockToTarget(targetX, n-2); initResetBlock(targetX, n-2); resetBlockToTarget(targetX+1, n-2); l: while (!(whiteBlockX==targetX && whiteBlockY==n-1)) { if(whiteBlockY<n-1){ whiteBlockDown(); continue l; } if(whiteBlockX>targetX){ whiteBlockLeft(); continue l; } break; } whiteBlockUp(); swapWhiteBlockAndCurrentBlock(); if(puzzle[n-2][targetX]!=resetBlock||puzzle[n-1][targetX]!=(resetBlock+n)){//沒有復位勝利 // isPrint=true; swapWhiteBlockAndCurrentBlock(); reset3_0(); reset3(targetX); } } private void reset3_0(){ if(resetBlockX<n-1){ whiteBlockDown(); whiteBlockRight(); whiteBlockRight(); whiteBlockUp(); swapWhiteBlockAndCurrentBlock(); reset3_0(); return; } return; } private void reset2_3(){ if(whiteBlockX==resetBlockX && whiteBlockY==resetBlockY+1){ return;//知足前提,加入遞歸 } //白塊能夠在復位塊的:左方、左下、下方 if(whiteBlockY==resetBlockY){//左方 whiteBlockDown(); }else if(whiteBlockX < resetBlockX){//左下 whiteBlockRight(); }else { whiteBlockUp(); } reset2_3();//遞歸 } private void reset2_2(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//2、把復位塊移到目的地位正下方 return;//加入遞歸 } //復位塊能夠地位,目的地位左方、正下方、左下方 if(resetBlockX==targetX){//正下方 上移 resetBlockUp(targetX, targetY); }else{//左方或左下方;先右移再上移 resetBlockRight(targetX, targetY); } reset2_2(targetX, targetY);//遞歸 } private void reset2(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } /* 1、假如白塊正好占了目的地位:假如復位塊正好鄙人方,交流及完成復位,假如下方不是復位塊,把白塊移開目的地位 * 2、把復位塊移到目的地位正下方 * 3、把白塊挪動復位塊下方 * 4、依照劃定的步調復位 */ //第一步 if(whiteBlockX==targetX&& whiteBlockY==targetY){ if(whiteBlockX==resetBlockX&&whiteBlockY==resetBlockY+1){//復位塊鄙人方 swapWhiteBlockAndCurrentBlock(); return; }else{ whiteBlockDown(); } } //第二步 把復位塊移到目的地位正下方 reset2_2(targetX, targetY+1); //第三步 把白塊挪動復位塊下方 reset2_3(); //第四步 依照劃定的步調復位 swapWhiteBlockAndCurrentBlock(); whiteBlockLeft(); whiteBlockUp(); whiteBlockRight(); whiteBlockDown(); whiteBlockLeft(); whiteBlockUp(); whiteBlockRight(); whiteBlockDown(); swapWhiteBlockAndCurrentBlock(); whiteBlockLeft(); whiteBlockUp(); whiteBlockUp(); whiteBlockRight(); swapWhiteBlockAndCurrentBlock(); } private void resetBlockToTarget(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } if(resetBlockY==targetY){//正左 resetBlockLeft(targetX, targetY); }else{//左下,下,右下 if(resetBlockX>=targetX){//右下||下;上移 if(resetBlockX==n-1){//復位塊在最左邊,先左移;便利上移時同一的采取白塊逆時針方法 resetBlockLeft(targetX, targetY); }else{ resetBlockUp(targetX, targetY); } }else{//左下;右移 resetBlockRight(targetX, targetY); } } resetBlockToTarget(targetX, targetY);//遞歸 } private void resetBlockRight(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } if(resetBlockX==n-1){//復位塊在最左邊了,沒法右移,直接加入 return; } // System.out.println("resetBlockRight"); if(whiteBlockY<resetBlockY){//上方 if(whiteBlockY<resetBlockY-1){//上方多行 whiteBlockDown(); }else{//上方一行 if(whiteBlockX<resetBlockX+1){//左上和正上 whiteBlockRight(); }else{//右上 whiteBlockDown(); } } }else if(whiteBlockY==resetBlockY){//統一行 if(whiteBlockX<resetBlockX){//左方 if(whiteBlockY==n-1){//究竟了,只能往上 whiteBlockUp(); }else{ whiteBlockDown(); } }else{//右方 if(whiteBlockX==resetBlockX+1){ swapWhiteBlockAndCurrentBlock(); return;//加入遞歸 }else{ whiteBlockLeft(); } } }else{//下方 if(whiteBlockX <= resetBlockX){//左下、下 whiteBlockRight(); }else{//右下 whiteBlockUp(); } } resetBlockRight(targetX, targetY);//遞歸 } private void resetBlockLeft(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } if(resetBlockX==0){//在右邊界限 復位塊沒法左移,直接加入遞歸 return; } // System.out.println("resetBlockLeft"); if(whiteBlockY<resetBlockY){//上方 if(whiteBlockY<resetBlockY-1){//上方多行 whiteBlockDown(); }else{//上方一行 if(whiteBlockX==resetBlockX){//上方 if(whiteBlockX==n-1){//最左邊,白塊沒法右移,只能左移 whiteBlockLeft(); }else{ if(resetBlockY==n-1){//復位塊在最低端,白塊不克不及順時針挪動 whiteBlockLeft(); }else{ whiteBlockRight(); } } }else if(whiteBlockX>resetBlockX){//右上方 if(resetBlockY==n-1){//復位塊在最低端,白塊不克不及順時針挪動 whiteBlockLeft(); }else{ whiteBlockDown(); } }else{//左上方 whiteBlockDown(); } } }else if(whiteBlockY==resetBlockY){//左方、右方 if(whiteBlockX<resetBlockX){//左方 if(whiteBlockX==resetBlockX-1){//右邊一格 swapWhiteBlockAndCurrentBlock();//加入遞歸 return; }else{ whiteBlockRight(); } }else{//右方 if(whiteBlockY==n-1){//究竟了,不克不及下移。只能上移 whiteBlockUp(); }else{ whiteBlockDown(); } } }else{//左下、下方、右下 if(whiteBlockX<resetBlockX){//左下 if(whiteBlockX==resetBlockX-1){ whiteBlockUp(); }else{ whiteBlockRight(); } }else{//下方、右下 whiteBlockLeft(); } } resetBlockLeft(targetX, targetY);//遞歸 } private void resetBlockUp(int targetX, int targetY){ if(resetBlockX==targetX&&resetBlockY==targetY){//地位准確不消挪動 return;//加入遞歸 } if(resetBlockY==0){//復位塊到頂了,沒法上移 return; } // System.out.println("resetBlockUp"); if (whiteBlockY < resetBlockY) {//上方 if(whiteBlockY < resetBlockY - 1){//上方多行 whiteBlockDown(); }else{//上方一行 if(whiteBlockX == resetBlockX){//白塊和復位塊在統一列(豎列) 白塊和復位塊直接交流地位 swapWhiteBlockAndCurrentBlock();//加入遞歸 return; }else{ if(whiteBlockX<resetBlockX){//白塊在復位塊的右邊;白塊右移 whiteBlockRight(); }else{//白塊在復位塊的左邊;白塊左移 whiteBlockLeft(); } } } } else if (whiteBlockY == resetBlockY) {//白塊和復位塊統一行;白塊上移 if(whiteBlockX<resetBlockX){//正左 if(whiteBlockX<resetBlockX-1){//正左多格 whiteBlockRight(); }else{//正左一格 if(whiteBlockY==n-1){//究竟了 whiteBlockUp(); }else { if(resetBlockX==n-1){//復位塊在最左邊,沒法逆時針,只要順指針挪動白塊 whiteBlockUp(); }else{ whiteBlockDown(); } } } }else{//正右 whiteBlockUp(); } }else{//白塊在復位塊下方,白塊須要饒過復位塊上移,白塊逆時針繞到白塊下面 //三種情形:左下,下,右下 if(whiteBlockX<=resetBlockX){//左下,下;白塊右移 if(resetBlockX==n-1){//復位塊在最左邊,沒法逆時針,只要順指針挪動白塊 if(whiteBlockX==resetBlockX){//正下方 whiteBlockLeft(); }else{//左下方 whiteBlockUp(); } }else{ whiteBlockRight(); } }else{//右下;白塊上移 whiteBlockUp(); } } resetBlockUp(targetX, targetY);//遞歸 } //白塊和復位塊交流地位 private void swapWhiteBlockAndCurrentBlock(){ step++; int tempX = whiteBlockX,tempY = whiteBlockY; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[resetBlockY][resetBlockX]; puzzle[resetBlockY][resetBlockX] = temp; whiteBlockX = resetBlockX; whiteBlockY = resetBlockY; resetBlockX = tempX; resetBlockY = tempY; println("swap"); } private void whiteBlockDown(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY+1][whiteBlockX]; puzzle[whiteBlockY+1][whiteBlockX] = temp; whiteBlockY++; println("↓"); } private void whiteBlockUp(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY-1][whiteBlockX]; puzzle[whiteBlockY-1][whiteBlockX] = temp; whiteBlockY--; println("↑"); } private void whiteBlockLeft(){ step++; int temp = puzzle[whiteBlockY][whiteBlockX]; puzzle[whiteBlockY][whiteBlockX] = puzzle[whiteBlockY][whiteBlockX-1]; puzzle[whiteBlockY][whiteBlockX-1] = temp; whiteBlockX--; println("←"); } 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 = new 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("\n"); } 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); } return str; } private void println(String str){ if(isPrint){ System.out.println(str); System.out.println(this); } } public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException { // System.setOut(new PrintStream("e:/puzzle.txt","UTF-8")); Puzzle p = new Puzzle(); System.out.println(p); try { p.sort(); } catch (Exception e) { e.printStackTrace(); System.out.println("Exception:"); }finally{ System.out.println(p); } } }
以上所述就是本文的全體內容了,願望年夜家可以或許愛好。