Java realisiert das eindeutige Zahlenspiel entsprechend den eingehenden Parametern

Ich habe viele Blogs und Materialien gelesen, die alle 9*9-Sudoku-Spiele sind, und es gibt immer noch viele unvollständige Codes. Das ist sehr ärgerlich, und es wird viel Zeit kosten, es selbst zu schreiben, also habe ich ein flexibleres Sudoku hier. Spiel, Sie können 3 * 3 6 * 6 7 * 7 8 * 8 oder 9 * 9 ... und so weiter nach Ihren eigenen Bedürfnissen generieren.

package com.odcchina.fai.util;

public class DoShudu {

    static int number = 0;
    static int limit = 0;
    /**
     * 存储数字的数组
     */
    static int[][] n = new int[number][number];
    static int[] num = null;

    public static void main(String[] args) {
        int[] numas = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        generateSingular(10,numas);
        //输出结果
        for (int i = 0; i < number; i++) {
            for (int j = 0; j < number; j++) {
                System.out.print(n[i][j] + " ");
            }
            System.out.println();
        }
    }

    /**
     * @param numberPas 要生成的位数 6*6 7*7 8*8 9*9 。。。。。。
     * @param numPas    生成的数组,里面不能有为0的数字
     */
    public static void generateSingular(int numberPas,int[] numPas){
        number = numberPas;
        limit = numberPas - 1;
        n = new int[numberPas][numberPas];
        num = numPas;
        int code = 0;
        //生成数字
        for (int i = 0; i < number; i++) {
            //尝试填充的数字次数
            int time = 0;
            //填充数字
            for (int j = 0; j < number; j++) {
                code++;
                if(code > 50000){
                    //生成失败,重新生成
                    n = new int[number][number];
                    generateSingular(numberPas,numPas);
                    return;
                }
                //产生数字
                n[i][j] = generateNum(time);
                //如果返回值为0,则代表卡住,退回处理
                //退回处理的原则是:如果不是第一列,则先倒退到前一列,否则倒退到前一行的最后一列
                if (n[i][j] == 0) {
                    //不是第一列,则倒退一列
                    if (j > 0) {
                        j -= 2;
                        continue;
                    } else {//是第一列,则倒退到上一行的最后一列
                        i--;
                        j = limit;
                        continue;
                    }
                }
                //填充成功
                if (isCorret(i, j)) {
                    //初始化time,为下一次填充做准备
                    time = 0;
                } else { //继续填充
                    //次数增加1
                    time++;
                    //继续填充当前格
                    j--;
                }
            }
        }
    }

    /**
     *  * 是否满足行、列和3X3区域不重复的要求 * @param row 行号 * @param col 列号 * @return true代表符合要求
     */
    public static boolean isCorret(int row, int col) {
        if(number % 3 == 0){
            //3的倍数才调checkNine校验
            return (checkRow(row) & checkLine(col) & checkNine(row, col));
        }else{
            return (checkRow(row) & checkLine(col) & true);
        }
    }

    /**
     *  * 检查行是否符合要求 * @param row 检查的行号 * @return true代表符合要求
     */
    public static boolean checkRow(int row) {
        for (int j = 0; j < limit; j++) {
            if (n[row][j] == 0) {
                continue;
            }
            for (int k = j + 1; k < number; k++) {
                if (n[row][j] == n[row][k]) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     *  * 检查列是否符合要求 * @param col 检查的列号 * @return true代表符合要求
     */
    public static boolean checkLine(int col) {
        for (int j = 0; j < limit; j++) {
            if (n[j][col] == 0) {
                continue;
            }
            for (int k = j + 1; k < number; k++) {
                if (n[j][col] == n[k][col]) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     *  * 检查3X3区域是否符合要求 * @param row 检查的行号 * @param col 检查的列号 * @return true代表符合要求
     */
    public static boolean checkNine(int row, int col) {
        //获得左上角的坐标
        int j = row / 3 * 3;
        int k = col / 3 * 3;
        //循环比较
        for (int i = 0; i < limit; i++) {
            if (n[j + i / 3][k + i % 3] == 0) {
                continue;
            }
            for (int m = i + 1; m < number; m++) {
                if (n[j + i / 3][k + i % 3] == n[j + m / 3][k + m % 3]) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     *  * 产生1-N之间的随机数字 * 规则:生成的随机数字放置在数组limit-time下标的位置,
     * 随着time的增加,已经尝试过的数字将不会在取到 * 说明:即第一次次是从所有数字中随机,
     * 第二次时从前八个数字中随机,依次类推, * 这样既保证随机,也不会再重复取已经不符合要求的数字,
     * 提高程序的效率 * 这个规则是本算法的核心 * @param time 填充的次数,0代表第一次填充 * @return
     */
    public static int generateNum(int time) {
        //第一次尝试时,初始化随机数字源数组
        if (time == 0) {
            for (int i = 0; i < number; i++) {
                num[i] = i + 1;
            }
        }
        //第number次填充,表明该位置已经卡住,则返回0,由主程序处理退回
        if (time == number) {
            return 0;
        }
        //不是第一次填充
        //生成随机数字,该数字是数组的下标,取数组num中该下标对应的数字为随机数字
        int ranNum = (int) (Math.random() * (number - time));
        //把数字放置在数组倒数第time个位置,
        int temp = num[limit - time];
        num[limit - time] = num[ranNum];
        num[ranNum] = temp;
        //返回数字
        return num[limit - time];
    }
}

Zum Ausführen klicken, die eindeutige Nummer wurde erfolgreich generiert

已连接到目标 VM, 地址: ''127.0.0.1:51558',传输: '套接字''
4 1 10 2 6 8 9 3 5 7 
10 7 9 8 3 2 5 4 6 1 
6 3 2 1 10 5 7 8 4 9 
8 4 5 7 2 10 6 9 1 3 
5 9 1 4 8 3 10 7 2 6 
3 6 7 9 1 4 2 10 8 5 
9 2 4 10 5 1 3 6 7 8 
7 8 3 5 9 6 4 1 10 2 
1 5 6 3 4 7 8 2 9 10 
2 10 8 6 7 9 1 5 3 4 
与目标 VM 断开连接, 地址为: ''127.0.0.1:51558',传输: '套接字''

进程已结束,退出代码为 0

Guess you like

Origin blog.csdn.net/qq_38935605/article/details/126954686