这个拼图游戏是帮同学做的,还是挺不错的,实现功能包括:自动选取图片,自动任意切割图片,且保证生成的一定有解,还有倒计时功能。
还写了那个迪杰斯特拉演示的,过两天再发上来,毕竟要考试了(预习了...)
先说下如何保证有解,两种方法:1,先切割然后自己后台让空格自己随机移动。
2,生成全排列,然后判断是否有解:
一个N*M数码是否有解存在以下结论: 1. 如果M为奇数,那么上下移动,左右移动都不会改变序列的逆序值的奇偶性,所以如果begin个end两个状态的逆序值奇偶性一样就有解! 2. 如果M为偶数,左右移动不会改变序列的逆序值的奇偶性,上下移动一次改变奇偶性一次,所以如果begin的空格的行数i与end的空格的行数j的绝对值之差与begin和end的逆序值的绝对值之差的奇偶性一样则有解。 3.其他情况无解!这个其实做poj那道8数码问题应该会有人提到,所以我一开始想到的就是第二种思路,第一种是后来听同学做的,感觉更加方便。
自动选取图片比较简单,套一个JFileChooser就可以,进度条用JProgressBar 难点在于这边这个进度条的线程要和游戏的有关联,我是通过将它的value设为静态成员变量实现的。
自动切割图片是谷歌到一串代码(貌似第二个就是,只不过它那个是存成相片,我这个直接保存为Imagecon即可,稍微修改了下.
puzzle类
public class puzzle extends JFrame implements ActionListener{
Game g;
private JButton jb,jb2,jb3;//依次为开始游戏,显示正确图片
private JTextField jt,jt2;//读入切割的行数和列数
JProgressBar progressbar;//进度条
Progress p;
String file;
public puzzle(){
setTitle("我的拼图");//应用标题
setLayout(null);
setBounds(0,0,900,700);//拼图程序的范围
g= new Game();//如果以后选择图片就从主界面选择好url把url传过去(game有多个构造函数)
g.setBounds(0,0,600,600);
Container container=getContentPane();
jb = new JButton("开始游戏");
jb.setBounds(650,50,200,100);
jb.addActionListener(this);
jb2 = new JButton("显示正确图片");
jb2.setBounds(650,175,200,100);
jb2.addActionListener(this);
jb3=new JButton("选择图片");
jb3.setBounds(650,300,200,100);
jb3.addActionListener(this);
JLabel jl= new JLabel("横向切割数量");
jl.setBounds(650,400,200,50);
container.add(jl);
jt=new JTextField("");
jt.setBounds(650,450,200,50);
JLabel jl2=new JLabel("纵向切割数量");
jl2.setBounds(650,500,200,50);
container.add(jl2);
jt2=new JTextField("");
jt2.setBounds(650,550,200,50);
progressbar =new JProgressBar();
progressbar.setBounds(0,600,800,75);
progressbar.setMinimum(0);
progressbar.setMaximum(100);
progressbar.setValue(0);
progressbar.setBackground(Color.blue);
progressbar.setBorderPainted(true);
container.add(progressbar);
container.add(jt);
container.add(jt2);
container.add(jb);
container.add(jb2);
container.add(jb3);
container.add(g);
container.setBackground(Color.white);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e){
int n,m;
if (e.getSource()==jb){//如果是开始游戏(获得n行,m列)
String s1=jt.getText();
String s2=jt2.getText();
if (s1.matches("\\d+")&&s2.matches("\\d+"))//如果是整数
{
n=Integer.parseInt(s1);
m=Integer.parseInt(s2);
//System.out.println(s1+""+s2);
//new picturecut(n,m);
if(file==null)
new alert4();
else
{
g.start(n,m,file);//传入n行,m列
if (p==null)//只开启