拼图java代码_Java制作智能拼图游戏原理及代码

今天突发奇想,想做一个智能拼图游戏来给哄女友。

需要实现这些功能

第一图片自定义

第二宫格自定义,当然我一开始就想的是3*3 4*4 5*5,没有使用3*5这样的宫格。

第三要实现自动拼图的功能,相信大家知道女人耍游戏都不是很厉害,所以这个自动拼图功能得有。

其他什么暂停、排行就不写了!

现在重点问题出来了

要实现自动拼图功能似乎要求有点高哦!计算机有可不能像人一样只能:

先追究下本质

拼图游戏其实就是排列问题:

排列有这么一个定义:在一个1,2,...,n的排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。

再来一个定义:交换一个排列中的两个数,则排列的奇偶性发生改变。

以上定义都摘自《高等代数》。

拼图排列必须是偶排列。这个在我参考文献中可以找到。

所以我的只能拼图是这样实现的!

后续在写

自动拼图:

首先自动拼图应该有一定的规则,根据我拼图的经验,要完成拼图,不同区域使用的拼图规则是不同的,所以:

我的宫格图分为了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

whiteBlockRight();

}

if(whiteBlockY

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

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

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

if(whiteBlockY

whiteBlockDown();

}else{//上方一行

if(whiteBlockX

whiteBlockRight();

}else{//右上

whiteBlockDown();

}

}

}else if(whiteBlockY==resetBlockY){//同一行

if(whiteBlockX

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

if(whiteBlockY

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

if(whiteBlockX==resetBlockX-1){//左边一格

swapWhiteBlockAndCurrentBlock();//退出递归

return;

}else{

whiteBlockRight();

}

}else{//右方

if(whiteBlockY==n-1){//到底了,不能下移。只能上移

whiteBlockUp();

}else{

whiteBlockDown();

}

}

}else{//左下、下方、右下

if(whiteBlockX

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

whiteBlockRight();

}else{//白块在复位块的右边;白块左移

whiteBlockLeft();

}

}

}

} else if (whiteBlockY == resetBlockY) {//白块和复位块同一行;白块上移

if(whiteBlockX

if(whiteBlockX

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()

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);

}

}

}

以上所述就是本文的全部内容了,希望大家能够喜欢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
import java.awt.*; import java.applet.*; import java.awt.event.*; public class PPuzzle extends Applet{ Image imgPuzzle,buff; Point fifteen=new Point(3,3); int[][] map={{0,4,8,12},{1,5,9,13},{2,6,10,14},{3,7,11,15}}; int sx,sy; Canvas screen; Graphics gs,gb; boolean running=false; Button bStart= new Button("新游戏"); Button bSee=new Button("显示正确图像"); public void init(){ prepareImage(); sx=imgPuzzle.getWidth(this)/4; sy=imgPuzzle.getHeight(this)/4; setBackground(Color.blue); initScreen(); initButtons(); add(screen); add(bStart); add(bSee); } void prepareImage(){ imgPuzzle=getImage(getCodeBase(),"images/3.jpg");// MediaTracker mt=new MediaTracker(this); mt.addImage(imgPuzzle, 0); try{ mt.waitForAll(); }catch(Exception e){} //创建buffer并获取graphics对象 buff=createImage(imgPuzzle.getWidth(this),imgPuzzle.getHeight(this)); gb=buff.getGraphics(); } void initMap(){ java.util.Random rnd=new java.util.Random(); int temp,x1,x2,y1,y2; for(int i=0;i<100;i++){ x1=rnd.nextInt(4); x2=rnd.nextInt(4); y1=rnd.nextInt(4); y2=rnd.nextInt(4); temp=map[x1][y1]; map[x1][y1]=map[x2][y2]; map[x2][y2]=temp; } outer:for(int j=0;j<4;j++) for(int i=0;i<4;i++) if(map[i][j]==15){ fifteen.setLocation(i,j); break outer; } } void initScreen(){ screen=new Canvas(){ public void paint(Graphics g){ if(gs==null) gs=getGraphics(); if(running) drawScreen(); else g.drawImage(imgPuzzle,0,0,this); } }; screen.setSize(imgPuzzle.getWidth(this), imgPuzzle.getHeight(this)); screen.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent me){ if(!running)return; int x=me.getX()/sx,y=me.getY()/sy; int fx=(int)fifteen.getX(),fy=(int)fifteen.getY(); if (Math.abs(fx-x)+Math.abs(fy-y)>=2)return; map[fx][fy]=map[x][y]; map[x][y]=15; fifteen.setLocation(x,y); drawScreen(); } }); } void initButtons(){ //新游戏 按钮事件的处理 bStart.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent ae){ initMap(); drawScreen(); running=true; bSee.setLabel("显示正确图像"); } }); //显示正确图像 按钮事件处理 bSee.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent ae){ //bsee 按钮标题为”继续游戏“ if(bSee.getLabel().equals("继续游戏")){ drawScreen(); bSee.setLabel("继续游戏"); } else{ //bsee的标题显示为”显示正确图像“ gs.drawImage(imgPuzzle,0,0,screen); bSee.setLabel("继续游戏"); } } }); } void drawScreen(){ gb.clearRect(0, 0, sx*4, sy*4); //将指定位置的图像块绘制到Buffer中 for(int j=0;j<4;j++) for(int i=0;i<4;i++) if(map[i][j]!=15) drawSegment(map[i][j],i,j); //向Screen绘制buffer中的图像 gs.drawImage(buff,0,0,screen); } void drawSegment(int seg,int x,int y){ int dx=seg%4*sx,dy=seg/4*sy; //可能有错误 gb.drawImage(imgPuzzle, x*sx,y*sy ,x*sx+sx-1 ,y*sy+sy-1 , dx , dy,dx+sx-1,dy+sy-1 ,screen ); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值