美文网首页
曹操哪里跑!--Java语言实现数字华容道游戏

曹操哪里跑!--Java语言实现数字华容道游戏

作者: 戴继勇 | 来源:发表于2020-06-16 22:32 被阅读0次

最近这段时间《最强大脑》又开播了

但是怎么却少了经典的数字华容道游戏

心血来潮,想着手写一个解数字华容道游戏的程序

但是想解题得先有个题,就先实现了一个数字华容道

基本思路

使用一维数组表示数字华容道的游戏内容 根据用户的输入值m,
随机生成一个大小为m*m大小的一维数组
一维数组内容的大小为0到m-1,
其中0代表空格 考虑到随机生成的数组内容可能存在无解的情况 我是先生成了一个有序的数组,
0在最后一位 然后随机移动300次,
并保证生成的一维数组不是有序的 用户通过输入某个数字x,
移动x和0之间的数字 并将0数字放到x的位置 每次移动数字后,
都检查一遍是否已经完成 直到完成数字华容道
话不多说上代码

代码实现

你看,良好的代码注释

/**
 * 数字华容道
 *
 * @author daijiyong
 */
public class Klotski {
    /**
     * 数字华容道的大小
     */
    private Integer size;
    /**
     * 使用一维数组表示数字华容道
     */
    private int[] klotski;
    /**
     * key:数字
     * value:数字对应的索引
     */
    Map<Integer, Integer> numberIndex = new HashMap<>();
    /**
     * key:数字
     * value:数字对应坐标位置
     */
    Map<Integer, int[]> numberCoordinate = new HashMap<>();


    public Klotski() {
    }

    public Klotski(Integer size) {
        this.size = size;
        init();
    }

    /**
     * 初始化数字华容道
     * 在排序好的数字华容道的基础上随机移动300次
     * 保证生成的华容道是有解的
     */
    public void init() {
        int totalSize = (int) Math.pow(size, 2);
        klotski = new int[totalSize];

        //初始化成员属性
        for (int i = 1; i < totalSize; i++) {
            klotski[i - 1] = i;
            numberIndex.put(i, i - 1);
            numberCoordinate.put(i, getCoordinate(i));
        }
        numberIndex.put(0, totalSize - 1);
        numberCoordinate.put(0, getCoordinate(0));

        /*
         * 初始化随机移动300次
         * 并保证生成的数字华容道不是已排序好的
         */
        while (check()) {
            for (int i = 0; i < 300; i++) {
                Random random = new Random();
                move(random.nextInt((int) Math.pow(size, 2)));
            }
        }

    }

    /**
     * 移动某一个数字
     *
     * @param number 数字
     * @return 是否移动成功
     */
    public Boolean move(Integer number) {
        /*
         *如果要移动的数字是0,即空格,则返回失败
         */
        if (number == 0) {
            return false;
        }
        int[] zeroCoordinate = numberCoordinate.get(0);
        int[] currentCoordinate = numberCoordinate.get(number);
        /*
         * 如果输入的数字,不在数字华容道的范围内,则返回失败
         */
        if (zeroCoordinate == null || currentCoordinate == null) {
            return false;
        }

        if (zeroCoordinate[0] != currentCoordinate[0] && zeroCoordinate[1] != currentCoordinate[1]) {
            return false;
        }
        /*
         * 点击的数字并不在0即空格的旁边
         * 则移动点击数字到空格之间的所有数字
         * 如果点击数字跟空格不在同一个横轴或纵轴上,则移动失败
         */
        if (zeroCoordinate[0] == currentCoordinate[0]) {
            if (zeroCoordinate[1] > currentCoordinate[1]) {
                for (int i = zeroCoordinate[1] - 1; i >= currentCoordinate[1]; i--) {
                    int moveNumber = klotski[coordinate2Index(new int[]{zeroCoordinate[0], i})];
                    move(0, moveNumber);
                }
            }
            if (zeroCoordinate[1] < currentCoordinate[1]) {
                for (int i = zeroCoordinate[1] + 1; i <= currentCoordinate[1]; i++) {
                    int moveNumber = klotski[coordinate2Index(new int[]{zeroCoordinate[0], i})];
                    move(0, moveNumber);
                }
            }
        }

        if (zeroCoordinate[1] == currentCoordinate[1]) {
            if (zeroCoordinate[0] > currentCoordinate[0]) {
                for (int i = zeroCoordinate[0] - 1; i >= currentCoordinate[0]; i--) {
                    int moveNumber = klotski[coordinate2Index(new int[]{i, zeroCoordinate[1]})];
                    move(0, moveNumber);
                }
            }
            if (zeroCoordinate[0] < currentCoordinate[0]) {
                for (int i = zeroCoordinate[0] + 1; i <= currentCoordinate[0]; i++) {
                    int moveNumber = klotski[coordinate2Index(new int[]{i, zeroCoordinate[1]})];
                    move(0, moveNumber);
                }
            }
        }
        return true;
    }

    /**
     *  移动交互某两个相邻数字的位置
     *
     * @param number1 数字1 在这里就是0
     * @param number2 数字2 根0相邻的一个数字(上下左右)
     */
    private void move(Integer number1, Integer number2) {

        int indexNumber1 = numberIndex.get(number1);
        int indexNumber2 = numberIndex.get(number2);
        klotski[indexNumber1] = number2;
        klotski[indexNumber2] = number1;
        numberIndex.put(number1, indexNumber2);
        numberIndex.put(number2, indexNumber1);

        numberCoordinate.put(number1, getCoordinate(number1));
        numberCoordinate.put(number2, getCoordinate(number2));


    }

    /**
     * 将坐标数据转变为在数组中的索引下标
     *
     * @param coordinate 在二维数组中的坐标位置
     * @return 在一维数组中的索引值
     */
    private Integer coordinate2Index(int[] coordinate) {
        return (coordinate[0] - 1) * size + coordinate[1] - 1;
    }

    /**
     * 获取某个数字的坐标,
     *
     * @param number 数字
     * @return 数字所在的位置表座
     */
    private int[] getCoordinate(Integer number) {
        int[] coordinate = new int[2];
        int index = numberIndex.get(number);
        coordinate[0] = (index / size) + 1;
        coordinate[1] = index % size + 1;
        return coordinate;
    }

    /**
     *  检查华容道是否已经完成
     *
     * @return 已完成或未完成
     */
    public Boolean check() {
        for (int i = 1; i < klotski.length; i++) {
            if (i != klotski[i - 1]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 打印华融的题面
     * @param str 提示语
     */
    public void println(String str) {
        for (int i = 0; i < klotski.length; i++) {
            if (i % size == 0) {
                System.out.println();
            }
            System.out.print(klotski[i] + "\t");
        }
        System.out.println();
        System.out.println(str);
        System.out.println("---------------");
    }


    public void setKlotski(int[] klotski) {
        this.klotski = klotski;
    }


    public static void main(String[] args) {
        System.out.println("请输入一个大于等于3的数字,用于初始化数字华容道游戏");
        Scanner input = new Scanner(System.in);
        int size = input.nextInt();

        Klotski klotski = new Klotski(size);
        klotski.println("请开始你的表演");
        while (!klotski.check()) {
            int num = input.nextInt();
            klotski.move(num);
            if (klotski.check()) {
                klotski.println("恭喜你已逃出数字华容道");
                break;
            } else {
                klotski.println("还没完,请继续你的表演");
            }
        }
    }
}

效果图

image image

你看,这么轻松就做出来了 你来试试下边这道题吧

image

文/戴先生@2020年6月7日

---end---

相关文章

  • 曹操哪里跑!--Java语言实现数字华容道游戏

    最近这段时间《最强大脑》又开播了 但是怎么却少了经典的数字华容道游戏 心血来潮,想着手写一个解数字华容道游戏的程序...

  • pyqt 简单实现3X3数字华容道

    最近看到一个小游戏“数字华容道”。 闲来没事就自己实现了一个(存在无解的情况) 实现的代码如下: # -*- co...

  • 乡里团子

    文/呢喃 很多人知道华容道,因为有款古老的游戏叫华容道,从赤壁败走的曹操走的也是华容道。却鲜有人知道我的家乡华容县...

  • 华容道小游戏(Java实现)

    Java课设做了个华容道的小游戏(3*3),包含了基本的ui交互界面,数据库存储成绩。 基本程序目录如下: 其中主...

  • 《数字华容道》游戏

    《数字华容道》是由1到15的数字组成,数字顺序被事先打乱,在听到口令后,迅速将华容道还原成按1到15顺序排...

  • 【Unity3D开发小游戏】《数字华容道》Unity开发教程

    一、前言 因为最强大脑让【数字华容道】这款老游戏又火了一把,那就让我们来看看这个游戏是怎么实现的吧,有什么样的算法...

  • 传世三国-经典华容道手游

    华容道是中国民间古老的益智游戏,有着变化多端、百玩不厌的特点。 华容道原是中国古代的一个地名,相传当年曹操曾经败走...

  • 曹操败走华容道,原来是个阳谋。

    “有没有听过华容道的故事?” “小时候看小说,曹操打败仗,被困华容道,但是关羽义薄云天,念在旧情分上,所以把曹操放...

  • 数字华容道

    疯狂数字华容道,一款全新的经典的益智类型数字游戏。 游戏的玩法是用最少的步数,最短时间将棋盘上的数字方块,按照从左...

  • 有一种胜利叫撤退,有一种失败叫占领

    诸葛亮为何要在华容道放走赤壁之战大败的曹操呢? 关羽在华容道放了曹操,有人认为这是诸葛亮故意安排的,这个情节不见于...

网友评论

      本文标题:曹操哪里跑!--Java语言实现数字华容道游戏

      本文链接:https://www.haomeiwen.com/subject/adudxktx.html