java实现九宫格拼图游戏

作者:林小陈 时间:2023-05-28 09:26:07 

本文实例为大家分享了java实现九宫格拼图游戏的具体代码,供大家参考,具体内容如下

设计步骤:

 先将框架构思出来,首先将拼图游戏的雏形实现,即一个界面,九个按钮,按钮上的图片显示出自己想要的图片。

(1)其次构思移动版块的问题,想到按钮直接互换是极为麻烦的一件事,所以采用更换按钮上的图片。按钮类上有两个属性,a[9]表示按钮的位置,b[9]表示按钮上图片的编号, 空白快图片编号为8标记,点击按钮之后,点击事件得到点击的块数在哪(1-9),if -else判断相邻是否为标记的空白快。方法简单但是代码量长。

(2)在完成了上述游戏的灵魂——移动算法之后。接下来便是加入一个判断是否胜利的算法了。在上一段中我们提到有两个按钮属性 a,b来记录信息,在未打乱之前,ab对应,值相等。那么我们在每一次的鼠标点击拼图按钮之后进行一次判断,是否每一个a[i]都对应着自身b[i]值,如果是的话就给出胜利信号。

(3)完成了结束条件后,我们再设计一个开始游戏,打乱拼图的算法。一开始先考虑了随机置入图片的方法,但是在八数码问题中,随机置入的话会存在奇偶性,有一半的几率是没有解法的。如果采用此法,我不得不再写一个判断随机打乱之后是否有解的算法。这样会非常麻烦,并且与我之前写的版块内容不兼容。由于我们写好了移动算法,所以我们随机移动可移动的版块若干次,次数足够多的情况下便可以做到打乱拼图的效果,并且保证此法必然有解。

(4)在第三步完成之后,新增了一个点击锁click,初始化为零。当且仅当有效移动之后click自增1。在结束条件中新增一个点击锁是否大于零的判断条件,这样我们就可以避免在游戏未开始时随机点击一个方块就给出胜利。

(5)添加还原图片功能。在每一次完成游戏之后,或者感觉太难想从头来过,按照人们的思维,总想点击一键还原。还原的算法有智能的搜索算法,有广度,深度,a+等,输入人工智能中的八数码问题,还有最简单的直接“重置”,我采用代码量少的重置,留下八数码当成提示功能。思想是先将按钮显示的图片重置,再还原按钮的两个属性。

(6)在上述功能实现之后,此设计初具备一个拼图游戏的功能了。在兴趣之下想做提示功能,本意想做出根据当前局面。搜索出最佳的步骤并提示,但是对广度搜索的学习不够,只能算出最短步骤次数,还不会将最短路径回溯显示出来。所以只能做出简单的提示,搜索的过程显示在eclipse控制台。

以上便是本程序的设计步骤,源代码于下,可直接运行,图片位置需要自己设置。

package 拼图;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.*;
class Palace{                           //算出最短步数
String start;//初始字符串
String end;//目标字符串
int result=-1;//最终结果
public int Palacea(String shuju){
 this.start = shuju;
 end = "12345678.";
 HashMap<String, Integer> memery = new HashMap<>(100000);//用于保存之前状态,key代表状态字符串,value代表到key状态所用的最小步数
 Queue<String> process = new LinkedList<String>();//bfs用到的队列
 memery.put(start,0);//放入初始字符串
 process.offer(start);//放入初始字符串
 while(result==-1){//当没有搜索到结果是继续搜索
  String cur = process.poll();
  char[] a=cur.toCharArray();
  int count=0;
  for(int b=0;b<a.length;b++) {
   count++;
   System.out.print(a[b]+"  ");
   if(count%3==0)System.out.println();
   }
  System.out.println("++++++++++++++");  
  int tmp = 0;
  while(cur.charAt(tmp)!='.'){
   tmp++;
  }      
  int[] d = {-3,3,-1,1};//方向数组,分别表示上下左右
  for(int i=0;i<4;i++){
   int p = tmp+d[i];
   int chengji = tmp*p;
   if(p>-1&&p<9&&chengji!=6&&chengji!=30){        //2-->3,3-->2,5-->6,6-->5跨行了,要去掉
    String change = cur;
    char c = cur.charAt(p);
    change = cur.replace('.', '*');//交换String中的两个字符,借助中间字符‘*'
    change = change.replace(c,'.');
    change = change.replace('*',c);
    if(change.equals(end)){//找到了目标状态    
     result = memery.get(cur)+1;
    }
    if(!memery.containsKey(change)){//如果之前没有这种状态
     memery.put(change,memery.get(cur)+1);
     process.add(change);//存入队列
    }
   }
  }
 }
 System.out.println(result);
      return result;
}
}
class tu extends JButton {
int ID;
int nowID;
int IMAGEWIDTH;
int IMAGEHEIGHT;
int nowx;
int nowy;
Icon icon;
public tu(Icon icon) {
this.setIcon(icon);
}
public tu(Icon icon, int id, int imagewidth, int height,int nowx,int nowy,int nowid)//构造函数初始化,传入两个参数,一个是图像的图标,一个是该按钮的数组ID
{
this.setIcon(icon);
   this.ID = id;
   this.nowID = nowid;
   this.IMAGEWIDTH = imagewidth;
   this.IMAGEHEIGHT = height;
   this.setSize(IMAGEWIDTH, IMAGEHEIGHT);
   this.nowx=nowx;
   this.nowy=nowy;
   this.icon=icon;    
}
public Icon geticon() {
   return icon;
}
public int getID() {
   return ID;
}
public int getnowID() {
   return nowID;
}
public int getx()
{
   return this.getBounds().x;
}

public int gety()
{
   return this.getBounds().y;
}
public int getnowx()
{
   return nowx;
}
public int getnowy()
{
   return nowy;
}
}

class pintus extends JFrame  implements  MouseListener,  ActionListener {
private JButton strat,strat1,strat2,yuan,restart,save,readsave,tishi;      //按钮
private JLabel raw;      //按钮
private tu tu[]=new tu[9];              //标签
private tu tuz[]=new tu[9];
JLabel tishikuan;                         //标签
private int ID;
ImageIcon icon1=null;
int jishu=0;
JPanel j1=new JPanel();//新建中间容器
JPanel j2=new JPanel();
JPanel j3=new JPanel();
public pintus() {
 BufferedImage tutu=null;
 ImageIcon icon = null;

BufferedImage  bufnew=null;
 int w=0;
 int h=0;
 int m = 0;  
  //jframe设置基本属性
 setTitle("05林-拼图游戏");          

添加布局
 j1.setLayout(new GridLayout(3, 3));  //设置中间流式布局
 //j2.setLayout(new GridLayout(1, 4));  //设置中间流式布局  
 ///图片切割并存入
  try {
   tutu = ImageIO.read(new File("C:\\Users\\czldd\\eclipse-workspace\\拼图\\src\\拼图\\原.png"));
   w=tutu.getWidth()/3;
   h=tutu.getHeight()/3;
    setSize(tutu.getWidth(),tutu.getHeight()+175);        // //jframe设置大小属性
    //System.out.println(w+" "+h);
 } catch (IOException e) {
        System.out.println("错误");
  e.printStackTrace();
 }

for(int i = 0; i < 3 ;i++)
        {
            for(int j = 0; j < 3; j++)
            {
             m=j*3+i;            
          bufnew = tutu.getSubimage(w*i, h*j, w, h);
                icon = new ImageIcon(bufnew);
                tu [m]=new tu(icon,m,w,h,i,j,m);
                tu [m].setLocation(w*j, h*i);
                tuz [m]=new tu(icon,m,w,h,i,j,m);
                tuz [m].setLocation(w*j, h*i);                
                if(m==8)
                {  
                 icon=new ImageIcon("C:\\Users\\czldd\\eclipse-workspace\\拼图\\src\\拼图\\白.png");                  
                 tu[m]=new tu(icon,m,w,h,i,j,m);
                 tuz[m]=new tu(icon,m,w,h,i,j,m);
                 }
            }
        }

j2.add(strat=new JButton("简单"));
 j2.add(strat1=new JButton("中等"));
 j2.add(strat2=new JButton("复杂"));
 j2.add(yuan=new JButton("还原"));
 j2.add(tishi=new JButton("提示"));
 //j2.add(restart=new JButton("重置"));
 //j2.add(save=new JButton("保存进度"));
 //j2.add(readsave=new JButton("读取进度"));  
 icon=new ImageIcon("C:\\Users\\czldd\\eclipse-workspace\\拼图\\src\\拼图\\小.png");  
 j2.add(raw=new JLabel(icon));
 strat.addActionListener(this);
 strat1.addActionListener(this);
 strat2.addActionListener(this);
 yuan.addActionListener(this);
 tishi.addActionListener(this);  
 j3.add(tishikuan=new JLabel("系统提示:请选择游戏模式"));  
  icon1=(ImageIcon) tu[8].geticon();
        zairu();
 //

setLocationRelativeTo(null);  
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setVisible(true);
  setResizable(false);  
}
/设置按钮
public void zairu() {
for(int a=0;a<9;a++)                                //输入图片
{                        
 j1.add(tu[a]);
 tu [a].addMouseListener(this);                //设置鼠标事件
}
add(j1,BorderLayout.CENTER);
add(j2,BorderLayout.PAGE_START);
add(j3,BorderLayout.PAGE_END);
}

public void qingkong() {
    removeAll();
}

public void moves(tu t) {

int a=t.getnowID();
 icon1=new ImageIcon("C:\\Users\\czldd\\eclipse-workspace\\拼图\\src\\拼图\\白.png");  
 if(a==0) {  
if(tu[a+1].getID()==8) {  tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+1].icon=t.icon;t.icon=icon1;jishu++;}
if(tu[a+3].getID()==8) {  tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+3].icon=t.icon;t.icon=icon1;jishu++;}   }
 if(a==1) {  
if(tu[a+1].getID()==8) {  tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+1].icon=t.icon;t.icon=icon1;jishu++;}
if(tu[a+3].getID()==8) {  tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+3].icon=t.icon;t.icon=icon1;jishu++;}  
if(tu[a-1].getID()==8) {  tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} }
 if(a==2) {  
if(tu[a+3].getID()==8) {  tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+3].icon=t.icon;t.icon=icon1;jishu++;}  
if(tu[a-1].getID()==8) {  tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} }
 if(a==3) {  
if(tu[a+3].getID()==8) {  tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+3].icon=t.icon;t.icon=icon1;jishu++;}  
if(tu[a-3].getID()==8) {  tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID();   t.setIcon(icon1);t.ID=8;      tu[a-3].icon=t.icon;t.icon=icon1; jishu++;}
if(tu[a+1].getID()==8) {  tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+1].icon=t.icon;t.icon=icon1;jishu++;}     }
 if(a==4) {
if(tu[a+3].getID()==8) {  tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+3].icon=t.icon;t.icon=icon1;jishu++;}  
if(tu[a-3].getID()==8) {  tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID();   t.setIcon(icon1);t.ID=8;      tu[a-3].icon=t.icon;t.icon=icon1; jishu++;}
if(tu[a+1].getID()==8) {  tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+1].icon=t.icon;t.icon=icon1;jishu++;}
if(tu[a-1].getID()==8) {  tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID();   t.setIcon(icon1);t.ID=8;   tu[a-1].icon=t.icon;t.icon=icon1;jishu++;}  }
 if(a==5) {  
if(tu[a+3].getID()==8) {  tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+3].icon=t.icon;t.icon=icon1;jishu++;}  
if(tu[a-3].getID()==8) {  tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID();   t.setIcon(icon1);t.ID=8;       tu[a-3].icon=t.icon;t.icon=icon1;jishu++;}  
if(tu[a-1].getID()==8) {  tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID();   t.setIcon(icon1);t.ID=8;   tu[a-1].icon=t.icon;t.icon=icon1;jishu++;}       }
 if(a==6) {  
if(tu[a-3].getID()==8) {  tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID();   t.setIcon(icon1);t.ID=8;       tu[a-3].icon=t.icon;t.icon=icon1;jishu++;}
if(tu[a+1].getID()==8) {  tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID();   t.setIcon(icon1);t.ID=8;     tu[a+1].icon=t.icon;t.icon=icon1;jishu++;}    }
 if(a==7) {  
if(tu[a-3].getID()==8) {  tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID();   t.setIcon(icon1);t.ID=8;       tu[a-3].icon=t.icon;t.icon=icon1;jishu++;}
if(tu[a+1].getID()==8) {  tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID();   t.setIcon(icon1);t.ID=8;    tu[a+1].icon=t.icon;t.icon=icon1; jishu++;}
if(tu[a-1].getID()==8) {  tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID();   t.setIcon(icon1);t.ID=8;   tu[a-1].icon=t.icon;t.icon=icon1;jishu++;}  }
 if(a==8) {  
if(tu[a-3].getID()==8) {  tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID();   t.setIcon(icon1);t.ID=8;      tu[a-3].icon=t.icon;t.icon=icon1;jishu++; }
if(tu[a-1].getID()==8) {  tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID();   t.setIcon(icon1);t.ID=8;   tu[a-1].icon=t.icon;t.icon=icon1;jishu++;}  }
 }
/图片移动事件
  public void mouseClicked(MouseEvent e){            //设置执行事件
 tu t =(tu) e.getSource();
 System.out.println("原本的位置:"+t.getID()+"  点击的位置:"+t.getnowID());
 int a=t.getnowID();
       moves(t);
 String s="系统提示:游戏继续"+",点击的块数目标位置为"+t.getID();
   tishikuan.setText(s);

if(win()&&jishu!=0) {jishu=0;JOptionPane.showConfirmDialog(null, "你赢了! " ,"拼图",JOptionPane.CANCEL_OPTION); }      

}
  private boolean win() {
   int sum=0;
 for(int s=0;s<9;s++)
 {
  if(tu[s].ID==tu[s].nowID)
   sum++;

}
 if(sum==9) {
 tishikuan.setText("系统提示:你赢了");
 return true;}
 else
 {

return false;
 }
}
public void actionPerformed(ActionEvent e) {        //设置执行事件}
  if(e.getSource()==strat) {
   luan();
   String s="系统提示:游戏开始,简单模式";
      tishikuan.setText(s);
   for(int a=0;a<9;a++) {
    if(tu[a].ID==8) {System.out.println(0);continue;}
       System.out.println(tu[a].ID+1);}

}
  if(e.getSource()==strat1) {
   luan1();
   String s="系统提示:游戏开始,中等模式";
      tishikuan.setText(s);
   for(int a=0;a<9;a++) {
    if(tu[a].ID==8) {System.out.println(0);continue;}
   System.out.println(tu[a].ID+1);}
  }
  if(e.getSource()==strat2) {
   luan2();
   String s="系统提示:游戏开始,复杂模式";
      tishikuan.setText(s);
   for(int a=0;a<9;a++) {
    if(tu[a].ID==8) {System.out.print(".");continue;}
   System.out.print(tu[a].ID+1);}
  }
  if(e.getSource()==yuan) {
   String s="系统提示:已经还原,请重新选择游戏模式";
      tishikuan.setText(s);
                try {
    huanyuan();
   } catch (IOException e1) {
    // TODO 自动生成的 catch 块
    e1.printStackTrace();
   }

}
  if(e.getSource()==tishi) {
   if(jishu==0) {
    String s="系统提示:系统利用广度搜索算出解法,需要0步";
       tishikuan.setText(s);
   }
   else
   {
   String d = "" ;
   for(int a=0;a<9;a++) {
   if(tu[a].ID==8)
   {d = d+".";continue;}
   d = d+Integer.toString(tu[a].ID+1);
   }

System.out.println(d);
   Palace palace = new Palace();

String s="系统提示:系统利用广度搜索算出解法,需要"+palace.Palacea(d)+"步";
    tishikuan.setText(s);

}
  }  
  }

private void huanyuan() throws IOException {
 jishu=0;
 for(int a=0;a<9;a++) {        //显示图  
  tu[tu[a].ID].setIcon(tu[a].geticon());

}    
  for(int i = 0; i < 9 ;i++) {             //还原图
     tu[i].icon=tuz[i].icon;
  }
   for(int i = 0; i < 9 ;i++) {              //还原标记点
    tu[i].ID=tu[i].nowID=i;

}  
}
                                                       //打乱顺序!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  private void luan() {
 for(int a=0;a<20;a++)
 {
  int b=(int) (Math.random()*9);
  moves(tu[b]);
 }  
   }
  private void luan1() {
 for(int a=0;a<100;a++)
 {
  int b=(int) (Math.random()*9);
  moves(tu[b]);
 }  
   }
  private void luan2() {
 for(int a=0;a<10000;a++)
 {
  int b=(int) (Math.random()*9);
  moves(tu[b]);
 }  
   }
  ///
  public void setIcon(String file, JButton iconButton) {  
        ImageIcon icon = new ImageIcon(file);  
        Image temp = icon.getImage().getScaledInstance(iconButton.getWidth(),  
                iconButton.getHeight(), icon.getImage().SCALE_DEFAULT);  
        icon = new ImageIcon(temp);  
        iconButton.setIcon(icon);  
    }

@Override
 public void mouseEntered(MouseEvent e) {
  // TODO 自动生成的方法存根

}
 @Override
 public void mouseExited(MouseEvent e) {
  // TODO 自动生成的方法存根

}
 @Override
 public void mousePressed(MouseEvent e) {
  // TODO 自动生成的方法存根

}
 @Override
 public void mouseReleased(MouseEvent e) {
  // TODO 自动生成的方法存根

}
/
public static void main(String[] args) {
 try {
  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());  
 } catch(Exception e) {}
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    new pintus();
   }
   });
 }

}

运行:

java实现九宫格拼图游戏

java实现九宫格拼图游戏

java实现九宫格拼图游戏

来源:https://blog.csdn.net/weixin_39326965/article/details/79007030

标签:java,九宫格,拼图
0
投稿

猜你喜欢

  • C#中抽象类与接口的区别详解

    2023-08-12 22:33:01
  • Java中Elasticsearch 实现分页方式(三种方式)

    2022-03-04 06:19:08
  • eclipse导入appcompat项目报错解决办法

    2021-11-10 14:25:57
  • 解决Spring或SpringBoot开启事务以后无法返回自增主键的问题

    2023-09-12 18:51:45
  • Kotlin开发笔记之委托属性与区间(译)

    2022-07-12 19:14:32
  • Android中butterknife的使用与自动化查找组件插件详解

    2021-09-18 06:58:36
  • vue+springboot前后端分离工程跨域问题解决方案解析

    2023-08-06 06:51:10
  • java基础之数组常用操作总结(必看篇)

    2022-12-09 03:32:17
  • C++判断pe文件实例

    2022-01-19 12:29:52
  • C语言实现餐饮管理系统

    2023-03-26 06:40:37
  • Android RxJava创建操作符Timer的方法

    2022-04-22 13:10:26
  • C++实现连连看游戏

    2023-12-06 02:18:09
  • c# 委托的本质是什么

    2022-01-31 17:55:46
  • 详解C#中SqlParameter的作用与用法

    2022-11-01 09:51:17
  • Android实现将一个Activity设置成窗口样式的方法

    2023-07-04 18:56:38
  • Java如何解析html中的内容并存到数据库详解

    2023-11-29 05:08:32
  • Java程序常见异常及处理汇总

    2021-08-12 04:20:44
  • Android编程实现Listview点击展开和隐藏的方法

    2023-04-26 01:36:49
  • SpringBoot如何返回Json数据格式

    2023-01-12 16:28:51
  • SpringBoot全局异常与数据校验的方法

    2023-12-11 10:46:06
  • asp之家 软件编程 m.aspxhome.com