//测试类
import javax.swing.*;

public class Test {
    public static void main(String[] args) {
        new MainFrame();
    }
}
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class MainFrame extends JFrame implements KeyListener {
    int[][] data={
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };
    int[][] win={
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };
    int row;            //0号元素行坐标位置
    int column;        //0号元素列坐标位置
    int count;         //统计步数
public MainFrame(){
    //窗体对象.addKeyListener
    this.addKeyListener(this);
    //初始化窗体
    initFrame();
    //初始化数据
    initData();
    //绘制游戏界面
    paintView();
    //设置窗体可见
    setVisible(true);
}

    /**
     * 此方法用于初始化数据(打乱二维数组)
     */
    public void initData(){
        //准备Random对象
    Random r=new Random();
    //遍历二维数组,获取到每一个元素
    for (int i = 0; i < data.length; i++) {
        for (int j = 0; j < data.length; j++) {
           int randomX= r.nextInt(4);
            int randomY=r.nextInt(4);
            int tmp=data[i][j];
            data[i][j]=data[randomX][randomY];
            data[randomX][randomY]=tmp;
        }
    }
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data.length; j++) {
              if (data[i][j]==0){
                   row=i;
                  column=j;
              }

            }
        }
}

    /**
     *  此方法此方法用于初始化窗体
     */
    public void initFrame(){
       //设置窗体的宽和高
        setSize(514,595);
        //设置窗体的关闭模式(关闭窗体的同时程序也一并关闭)
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //设置窗体的标题
        setTitle("石头迷阵单机版1.0");
        //设置窗体在任何时候都置于屏幕最顶层
        setAlwaysOnTop(true);
        //设置窗体居中
        setLocationRelativeTo(null);
        //取消窗体默认布局
        setLayout(null);

    }

    /**
     * 此方法此方法用于绘制游戏界面
     */
    public void paintView(){
        //用于绘制游戏界面前清空面板
        getContentPane().removeAll();
        //添加胜利图片到窗体中
      if (victory()){
          JLabel winLabel=new JLabel(new ImageIcon("D:\\Develop\\Java\\石头迷阵图片\\win.png"));
          winLabel.setBounds(124,230,266,88);
          getContentPane().add(winLabel);
      }
      //统计步数
      JLabel scoreLabel=new JLabel("步数为:"+count);
      scoreLabel.setBounds(50,20,100,20);
      getContentPane().add(scoreLabel);
      //重新游戏
        JButton btn=new JButton("重新游戏");
        btn.setBounds(350,20,100,20);
        getContentPane().add(btn);
        btn.setFocusPainted(false);
        btn.addActionListener(e -> {
            count=0;
            initData();
            paintView();
        });
    for (int i=0;i<4;i++){
        for (int j=0;j<4;j++){
            JLabel imageLabel=new JLabel(new ImageIcon("D:\\Develop\\Java\\石头迷阵图片\\"+data[i][j]+".png"));
            imageLabel.setBounds(50+100*j,90+100*i,100,100);
            getContentPane().add(imageLabel);
        }
    }

    JLabel jl17=new JLabel(new ImageIcon("D:\\Develop\\Java\\石头迷阵图片\\background.png"));
    jl17.setBounds(26,30,459,484);
    getContentPane().add(jl17);
    //用于刷新界面
        getContentPane().repaint();
}
//此方法用于判断游戏是否胜利
public boolean victory(){

    for (int i = 0; i < data.length; i++) {
        for (int j = 0; j < data.length; j++) {
            if (data[i][j]!=win[i][j]){
                return false;
            }
        }
    }
    return true;
}


    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {
        if (victory()){
            return;
        }
        if (keyCode ==37){
           //空格和右侧数据做交换
            if (column==3){
                return;
            }
            //data[row][column] data[row][column+1]
            int tmp=data[row][column];
            data[row][column]=data[row][column+1];
            data[row][column+1]=tmp;
            column++;
            count++;
        }else if (keyCode ==38){
            if (row==3){
                return;
            }
            //空格和下侧数据做交换
            //data[row][column] data[row+1][column]
            int tmp=data[row][column];
            data[row][column]=data[row+1][column];
            data[row+1][column]=tmp;
            row++;
            count++;
        }else if (keyCode ==39){
            if (column==0){
                return;
            }
            //空格和左侧数据做交换
            //data[row][column] data[row][column-1]
            int tmp=data[row][column];
            data[row][column]=data[row][column-1];
            data[row][column-1]=tmp;
            column--;
            count++;
        }else if(keyCode ==40){
            if (row==0){
                return;
            }
            //空格和上侧数据做交换
            //data[row][column] data[row-1][column]
            int tmp=data[row][column];
            data[row][column]=data[row-1][column];
            data[row-1][column]=tmp;
            row--;
            count++;
        }else if(keyCode ==90){
            //触发作弊器
            data=new int[][]{
                    {1,2,3,4},
                    {5,6,7,8},
                    {9,10,11,12},
                    {13,14,15,0}
            };
        }
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        //此方法用于处理移动业务
        move(keyCode);
        //每一次移动后,都重新绘制游戏界面
        paintView();

    }

    //---------------------------------------------
    @Override
    public void keyReleased(KeyEvent e) {

    }
    @Override
    public void keyTyped(KeyEvent e) {

    }
//---------------------------------------------
}