石头迷阵游戏

  • 在一张4X4的地图上,有15个数字方块以及1个空白块。
  • 每局的排序都是随机生成,不重复,如图1所示。
  • 使用键盘的上下左右按键控制空白方块的移动。
  • 记录操作步数。
  • 可以重新开始。
  • 作弊码:Z,使用作弊码可以直接满足胜利条件。
  • 胜利条件:数字方块从上至下排序为1至15,空白方块排在最后,效果如图2所示。

在这里插入图片描述

图1 默认界面

在这里插入图片描述

图2 胜利界面

Main.java

public class Main {
    public static void main(String[] args) {
        new MainFrame();
    }
}

MainFrame.java

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 count = 0;
    int row, column; // 0号元素坐标位置

    public MainFrame() {
        // 初始化窗体
        initFrame();
        // 初始化数据
        initData();
        // 绘制窗体
        paintFrame();
        // 显示窗体
        setVisible(true);
        // 监听键盘
        this.addKeyListener(this);
    }

    // 初始化数据
    private void initData() {
        Random r = new Random();
        int temp = 0;
        // 遍历二维数组
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                // 生成随机索引
                int randomX = r.nextInt(4);
                int randomY = r.nextInt(4);
                // 数据交换
                temp = data[randomX][randomY];
                data[randomX][randomY] = data[i][j];
                data[i][j] = temp;
            }
        }
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] == 0) {
                    row = i;
                    column = j;
                }
            }
        }
    }

    // 初始化窗体
    private void initFrame() {
        // 设置窗口标题
        setTitle("石头迷阵单机版");
        // 设置窗口尺寸
        setSize(490, 595);
        // 清除默认布局
        setLayout(null);
        // 设置居中显示
        setLocationRelativeTo(null);
        // 设置窗体关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    // 绘制窗体
    private void paintFrame() {
        // 绘制前清空所有
        getContentPane().removeAll();

        // 判断是否胜利
        if (victory()) {
            JLabel img = new JLabel(new ImageIcon("C:\\Users\\Daixiang\\Downloads\\image\\win.png"));
            img.setBounds(110, 220, 266, 88);
            getContentPane().add(img);
        }

        JLabel JLText = new JLabel("步数:" + count);
        JLText.setBounds(15, 15, 60, 30);

        JButton JBtn = new JButton("重新开始");
        JBtn.setBounds(355, 15, 100, 30);
        JBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                count = 0;
                initData();
                paintFrame();
            }
        });
        // 静止默认聚焦按钮
        JBtn.setFocusable(false);

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel img = new JLabel(new ImageIcon("C:\\Users\\Daixiang\\Downloads\\image\\" + data[i][j] + ".png"));
                img.setBounds(35 + 100 * j, 100 + i * 100, 100, 100);
                getContentPane().add(img);
            }
        }

        getContentPane().add(JLText);
        getContentPane().add(JBtn);
        // 设置背景图片
        JLabel JLBackground = new JLabel(new ImageIcon("C:\\Users\\Daixiang\\Downloads\\image\\background.png"));
        JLBackground.setBounds(10, 40, 450, 484);
        getContentPane().add(JLBackground);

        // 刷新面板
        getContentPane().repaint();
    }

    // 键盘按下
    @Override
    public void keyPressed(KeyEvent keyEvent) {
        int keyCode = keyEvent.getKeyCode();
        move(keyCode);
        // 每次移动后,重新绘制界面
        paintFrame();
    }

    // 移动业务
    private void move(int keyCode) {
        int temp;
        if (victory()) {
            return;
        }
        if (keyCode == 37) {
            System.out.println("左移动");
            if (column >= 1) {
                temp = data[row][column - 1];
                data[row][column - 1] = 0;
                data[row][column] = temp;
                column--;
                count++;
            }
        } else if (keyCode == 38) {
            System.out.println("上移动");
            if (row >= 1) {
                temp = data[row - 1][column];
                data[row - 1][column] = 0;
                data[row][column] = temp;
                row--;
                count++;
            }
        } else if (keyCode == 39) {
            System.out.println("右移动");
            if (column <= 2) {
                temp = data[row][column + 1];
                data[row][column + 1] = 0;
                data[row][column] = temp;
                column++;
                count++;
            }
        } else if (keyCode == 40) {
            System.out.println("下移动");
            if (row <= 2) {
                temp = data[row + 1][column];
                data[row + 1][column] = 0;
                data[row][column] = temp;
                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}
            };
        }
    }

    // 判断是否胜利
    public boolean victory() {
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] != win[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public void keyTyped(KeyEvent keyEvent) {

    }

    @Override
    public void keyReleased(KeyEvent keyEvent) {

    }
}

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐