再加个生成随机数独的功能

《更智能的解数独算法,让效率提升5倍!》 建立了解数独的基本函数,在这些基本的函数之上可以轻松的添加生成随机数独。一个完整的数独有81格,挖 50 - 60 洞便能产生数独游戏的题目。

添加以下函数:

 /* 在一个空白的数独里面,随机生成一行和一列数字,
     在这里我选择第一行的前8个格和第一列的前8个格,
     经过测试,留一格可以更稳定的生成数独,把一行
     和一列全填满,有可能因为无解而花费更多的时间  */
static void createSudoSeed() 
{
        static unsigned seed;
        int i,x,y;

        for(y = 0; y < 9; y++)        // 先将数独清空
                for(x = 0; x < 9; x++){
                        sudo[y][x] = 0;
                        sudo2[y][x] = 0;
        }
        srand(time(NULL) + seed);
        seed = rand();
        for(i = 0; i < 8;){
                srand(seed);
                seed = rand();
                sudo[0][i] =  seed % 9 + 1;
                if(verify(0, i))i++;
        }
        for(i = 0; i < 8;){
                srand(++seed);
                seed = rand();
                sudo[i][8] =  seed % 9 + 1;
                if(verify(i, 8))i++;
        }

}

/* 根据难度等级随机挖洞,等级可以选从1 到 4或5
    之间,每提高一个等级多挖3个洞                */
static void createSudoHole(int level)
{
        assert(level > 0 && level < 5);
        static unsigned seed;
        int i,x,y;
        seed--;
        srand(time(NULL) + seed);
        seed = rand();
        for(i = 0; i < 51 + level * 3;){
                srand(seed);
                x = rand();
                srand(x);
                y = rand();
                srand(y);
                seed = rand();
                x = x % 9;
                y = y % 9;
                if(sudo[y][x] != 0){
                        i++;
                        sudo[y][x] = 0;
                }
        }
}

void createSudo(int arr[9][9],int level)
{
        int x,y,i;

        do{
                createSudoSeed();      // 创造一个随机数独种子
        }while(!sudoGo(sudo));      // 解开这个数独中
        createSudoHole(level);      // 挖洞

        for(y = 0; y < 9; y++)         // 生成数独并输出
                for(x = 0; x < 9; x++)
                        arr[y][x] = sudo[y][x];
}

给出测试:

#include <stdio.h>

int sudo[9][9];

extern void sudoPrt();
extern void createSudo(int arr[9][9], int level);
extern int sudoGo(int arr[9][9]);

static void prt()
{
        int y,x;
        for(y = 0; y < 9; y++){
                for(x = 0; x < 9; x++)
                        if(sudo[y][x] == 0)
                                printf("-  ");
                        else
                                printf("%d  ",sudo[y][x]);
                printf("\n");
        }
}

int main(int argc, const char *argv[])
{
        printf("\npuzzle is:\n");
        createSudo(sudo,3);
        prt();
        printf("\nresult is:\n");
        sudoGo(sudo);
        sudoPrt();

        return 0;
}

输出结果:

puzzle is:
-  -  4  -  6  -  -  -  -  
-  -  7  -  -  9  -  -  4  
-  -  -  -  5  -  3  -  6  
-  -  -  -  -  -  -  -  -  
4  -  -  1  -  -  -  -  3  
-  -  -  -  -  -  9  -  -  
-  -  5  7  -  -  4  -  8  
-  -  -  -  -  -  -  -  -  
-  -  2  8  1  -  6  3  -  

result is
3  9  4  2  6  1  7  8  5  
5  6  7  3  8  9  1  2  4  
1  2  8  4  5  7  3  9  6  
2  5  3  6  9  4  8  7  1  
4  8  9  1  7  2  5  6  3  
6  7  1  5  3  8  9  4  2  
9  3  5  7  2  6  4  1  8  
8  1  6  9  4  3  2  5  7  
7  4  2  8  1  5  6  3  9


再来一遍:

puzzle is:
-  -  -  -  -  3  -  -  1  
-  -  -  -  -  -  2  -  8  
-  -  -  -  6  -  -  7  -  
-  -  -  -  -  -  1  4  -  
-  9  -  -  -  7  -  8  6  
-  -  -  -  1  4  -  -  3  
-  -  -  7  -  -  8  2  -  
-  1  -  -  -  -  -  -  7  
-  -  -  -  -  5  -  -  -  

result is
8  6  9  2  7  3  4  5  1  
3  7  4  1  5  9  2  6  8  
1  2  5  4  6  8  3  7  9  
7  5  3  8  9  6  1  4  2  
4  9  1  3  2  7  5  8  6  
6  8  2  5  1  4  7  9  3  
9  4  6  7  3  1  8  2  5  
5  1  8  6  4  2  9  3  7  
2  3  7  9  8  5  6  1  4 


至此,一个数独游戏的核心部分基本完成了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值