C语言实现数独游戏

本文实例为大家分享了C语言实现数独游戏的具体代码,供大家参考,具体内容如下

目标

写一个数独游戏,有以下功能:

1:能随机产生题目并给出答案。

2:求解输入的题目并输出答案。

实现说明

参照百度百科等资料可以知道求解数独的主要算法是:1.通过行、列和宫格确定可填数字。2.所有可行数字逐一填入得到结果。本程序求解数独部分也采用这样的算法。而生成题目的算法是:

随机产生一个长度为9的一维数组,元素是随机产生的1到9的不同数字。
比如为root = [1, 4, 3, 5, 6 ,7, 8 ,9, 2].

1、先获得一个填满的九宫格accord。
2、假如九宫格accord的第一行为[6, 4, 5, 7, 3, 9, 8, 1, 2], 则可获得的九宫格squa的第一行第一列元素这样产生:看accord对应元素为6,则看root中6后一位的数为7,则所求数字为7。以此类推。
3、根据难度随机去除一定数量的空格则得到了随机产生的数独题目。

下面介绍本程序的主要难点和创新点:

1、解数独的递归法。首先要定义一个检查函数judge用于判断某个数字在某个位置是否合适,进而根据找到的递归头即至最后一个位置后,分是否为0两种情况,否则,继续递归。

2、随机产生1到9之间的数。由于编译器自带函数rand会出现元素不变的确点,所以使用系统时间为种子,并引入全局变量index,使得时间差加大,避免固定不变。

3、定义各种函数简化程序。本程序定义了fprintf用于打印九宫格,定义reRank来获取元素在数组中位置等,简化了程序。

结果

下面是分别选择1(产生题目)和2(计算数独)后的结果图:

代码:

语言: C

//期末实验报告-简单的数独计算器
#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
long index = 0;    //全局变量index是保证每次产生的随机元素随机性
void main()
{
    void solve(int squa[9][9], int num); 
    void fprintf(int squa[9][9]);
    int reRank(int root[9], int numb);
    int myRand(int range);
    int squa[9][9], accord[9][9]={   //定义用于生成数独的参照数组
        {6, 4, 5, 7, 3, 9, 8, 1, 2},
        {2, 1, 8, 6, 4, 5, 9, 7, 3},
        {7, 3, 9, 2, 8, 1, 6, 4, 5},
        {5, 9, 6, 3, 7, 4, 2, 8, 1},
        {4, 8, 7, 5, 1, 2, 3, 6, 9},
        {3, 2, 1, 8, 9, 6, 7, 5, 4},
        {9, 5, 3, 4, 6, 7, 1, 2, 8},
        {8, 7, 2, 1, 5, 3, 4, 9, 6},
        {1, 6, 4, 9, 2, 8, 5, 3, 7}
        };
    int root[9], answ[9][9]; //定义用于生成数组的一维数组和临时数组
    int i, j, k, p = 0;
    int row;
    int choose, rtemp, diff; //分别定义选择变量,难度
    char result;
    printf("———请选择*1*生成一个数独——*2*计算一个数独———\n");
    scanf("%d", &choose);
//**************选择1生成一个填好的数独****************************
    //根据生成数独题目算法先存入一个数独
    if(1 == choose)
    { //产生范围为1-9的一维数组root
      for(i = 0; i < 9; i++)
      {
          root[i] = myRand(9);
      }
      for(i = 0; i < 9; i++)
      {
            for(j = 0; j < i; j++)
            {
                if(root[i]==root[j]) //使root中元素各不相同
                root[i] = myRand(9);
            }
      }
      //随机产生完整九宫格
      for(i=0;i<9;i++)
      {
         for(j=0;j<9;j++)
         {
            row = reRank(root,accord[i][j]);
            squa[i][j] = root[(row+1)%9];
         }
      }
      for (i = 0; i < 9; i++)
      {
         for (j = 0; j < 9; j++)
         {
            answ[i][j] = squa[i][j];
         }
      }
      //根据不同难度需求处理数组
      printf("————请选择难度等级:1(低级)--2(中级)--3(高级)————\n");
      scanf("%d", &diff);
      if(diff==1)               //难度为低级时有30个空格
      {
            for(k=0; k<20;)//; k++)
            {
                 i = myRand(9)-1;
                 j = myRand(9)-1;
                 if(squa[i][j] != 0)
                 {
                  squa[i][j] = 0;
                  k++;
                 }        
            }
      }
      else if(diff==2)          //难度为中级时有50个空格
      {  
            for(k=0; k<30;)
            {
                 i = myRand(9)-1;
                 j = myRand(9)-1;
                 if(squa[i][j] != 0)
                 {
                  squa[i][j] = 0;
                  k++;
                 }        
            }
      }
      else if(diff==3)            //难度为中级时有70个空格
      {
            for(k=0; k<60;)
            {
                 i = myRand(9)-1;
                 j = myRand(9)-1;
                 if(squa[i][j] != 0)
                 {
                  squa[i][j] = 0;
                  k++;
                 }        
            }
      }
      printf("************题目如下(0表示空格)****************\n");
      fprintf(squa);
      printf("——————Enter键显示答案——————");
      fflush(stdin);           //除去缓存影响
      scanf("%c", &result);
      if(result == 10)
          fprintf(answ);
    }
//**************选择2输入并计算一个数独**************************** 
    else
    {
      //*******输入题目***********************************
      printf("*********请输入题目(空缺以0代替)**********");
      printf("\n******||1*2*3*4*5*6*7*8*9\n");
      for (i = 0; i < 9; i++)
      {
         printf("******%d:", i + 1);
         for (j = 0; j < 9; j++)
         {
            scanf("%d", &squa[i][j]);
         }
      }
      solve(squa, 0);    //调用函数计算结果
    }
}
 
//定义函数可以产生随机产生1-9的数
int myRand(int range) 
{
    srand((unsigned)time( NULL ) + index);
    index++;
     return rand()%range + 1;     
}

//定义函数可以在root中根据元素找位置
int reRank(int root[9], int numb)
{    
    int i; 
    for(i = 0; i < 9; i++)
    {
        if(root[i] == numb)
        return i;
    }
}

//解决的第一步:判断空缺处可填数字的judge函数
int judge(int squa[9][9], int m, int n, int posb)
{
    int num, gridi, gridj;              
    int gi = m / 3 * 3, gj = n / 3 * 3;   //计算元素的宫格位置
    for (num = 0; num < 9; num++)         //根据行元素判断
    {
        if (squa[m][num] == posb)
            return 0;
    }
    for (num = 0; num < 9; num++)          //根据列元素判断
    {
        if (squa[num][n] == posb)
            return 0;
    }
    //根据宫格元素判断
    for (gridi = gi; gridi < gi + 3; gridi++)
    {
        for (gridj = gj; gridj < gj + 3; gridj++)
        {
            if (squa[gridi][gridj] == posb)
                return 0;
        }
    }
    return 1;
}

//定义递归函数solve求得一种结果
void solve(int squa[9][9], int num)
{   
    void fprintf(int squa[9][9]);
    int posb;
    int i, j, value;
    int magic[9][9];//定义临时数组
    int sm,sn;
    sm=num/9;      //计算元素行数
    sn=num%9;      //计算元素列数
    //将squa中元素赋给magic
    for (i = 0; i < 9; i++)
    {
        for (j = 0; j < 9; j++)
        {
            magic[i][j] = squa[i][j];
        }
    }
    //判断位置处元素非0
    if (magic[sm][sn] != 0)  
    {
        if (sm == 8 && sn == 8) //递归头
        {
            printf("————————参考结果————————\n");
            fprintf(magic);
        }
        else
        {
            solve(magic, num+1);
        }
    }
    else //判断位置处元素为0
    {
        for (posb = 1; posb <= 9; posb++)
        {   //根据判断函数返回值决定是否赋值
            value = judge(magic, sm, sn, posb);
            if (value)
            {
                magic[sm][sn] = posb;
                if (sm == 8 && sn == 8) //递归头
                {
                    printf("————————参考结果————————\n");
                    fprintf(magic);    
                }
                else
                {
                    solve(magic, num+1);
                }
                magic[sm][sn] = 0;
            }
        }
    }

}

//打印数组结果函数fprintf的定义
void fprintf(int squa[9][9])
{ 
  int i,j;
  for (i = 0; i < 9; i++)
        {
                for (j = 0; j < 9; j++)
                {   
                     printf("%d ", squa[i][j]);
                    if ((j == 2) || (j == 5)) //换列时加空格
                    printf(" ");
                }
                printf("\n");
                if ((i == 2) || (i == 5))     //换行时加换行符
                {
                    printf("\n");
                }
        }            
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言实现数独游戏的求解

    玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个同色九宫内的数字均含1-9,不重复. 输入包含9x9的已知数字,空位用0补齐,中间用空格隔开.(输入数独题目确保正确) 输出为输入数独题目的解. 样例输入: 8 0 0 0 0 0 0 0 0 0 0 3 6 0 0 0 0 0 0 7 0 0 9 0 2 0 0 0 5 0 0 0 7 0 0 0 0 0 0 0 4 5 7 0 0 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 0 6 8

  • C语言数独游戏的求解方法

    数独游戏的解法: 先将数独分为九个格子,用一个数组将每个小九宫格的候选数存放下来,将候选数挨个放进数独里的空位,如果这一行和这一列都没有这个数字,继续放入下一个,如果不能放入的话就回到上一步继续尝试,直到成功求出数独的解为止: 比如这个数独第一个九宫格的候选数就有1,2,7,8,9,我们需要从1开始放入第一个格子挨个尝试直到8的时候发现剩下的两个格子都不能放入 这个时候我们就要撤回上一个插入的7,发现8仍然不能放入,就继续撤回2,发现8可以放入,就将8放入3号位置,然后将9插入 这个时候我们发现

  • C语言解数独程序的源码

    用C语言写的解数独的程序.在linux下测试成功运行. 效果如图: 这是带解的数独,需要填写的部分用数字0代替. 这是程序运行后的效果图.看看,数独已经搞定啦. 程序源码如下: #include <stdio.h> #include <stdlib.h> #define SIZE 9 #define get_low_bit(x) ((~x&(x-1))+1) struct{ int left; char num; char try; }board[SIZE][SIZE];

  • C语言实现数独游戏

    本文实例为大家分享了C语言实现数独游戏的具体代码,供大家参考,具体内容如下 目标 写一个数独游戏,有以下功能: 1:能随机产生题目并给出答案. 2:求解输入的题目并输出答案. 实现说明 参照百度百科等资料可以知道求解数独的主要算法是:1.通过行.列和宫格确定可填数字.2.所有可行数字逐一填入得到结果.本程序求解数独部分也采用这样的算法.而生成题目的算法是: 随机产生一个长度为9的一维数组,元素是随机产生的1到9的不同数字.比如为root = [1, 4, 3, 5, 6 ,7, 8 ,9, 2]

  • C语言实现数独小游戏

    本文实例为大家分享了C语言实现数独小游戏的具体代码,供大家参考,具体内容如下 输入包含9x9的已知数字,空位用0补齐,中间用空格隔开.(输入数独题目确保正确)输出为输入数独题目的解. 玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个同色九宫内的数字均含1-9,不重复. 样例输入: 样例输出: 代码: #include <stdio.h> #include <stdlib.h> int *fillnumber(int a[9][9][10],

  • 基于C语言实现五子棋游戏完整实例代码

    本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解. 五子棋游戏代码如下: /* * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include<malloc.h> /* * 对应键盘键的十六进制数字 */ #defi

  • JQuery开发的数独游戏代码

    用了很多Jquery的插件,支持鼠标滚轮选数字.没有什么高深的技术点.工作原因很长时间没有更新了,具体代码都有些记不清了,欢迎大家来拍砖.截图:演示地址:http://demo.jb51.net/js/jsukudo/index.html下载地址:jsukudo20081110v0.3.0.5.zip 下载列表:http://code.google.com/p/jsukudo/downloads/list 用到的JS文件 文件名 出处 说明 blockUI.js http://malsup.co

  • java数独游戏完整版分享

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 自己写的数独游戏,共9关,代码如下: 1.DoShudu类用于产生数独数组 import java.util.Random; public class DoShudu { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] cells=newshudu(); //ce

  • 简单实现java数独游戏

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之前寒假受命写的,学了一个月java的成果,现在看来有些不足但毕竟是第一个程序,就直接放上来,数独终盘的实现直接用了暴力,时间复杂度有点高,懒得改了直接放代码 终盘实现: import java.util.Random; public class SudokuPuzzleGenerator { pri

  • java版数独游戏核心算法(一)

    之前学习javascript时用javascript写过一个数独游戏,最近看了一点java的内容,于是就心血来潮想搞一个java版的数独游戏. 现在将全部代码分享出来和大家学习交流,当然代码中有着各种各样的问题和不足之处,望各位朋友批评指点. 以下是生成数独地图的核心算法,算法不是很好,也是之前参考过网上的一些思想: package hlc.shudu.src; /* * 数独的帮助类,里面提供数据所需的所有算法 */ public class ShuduHelper { //数独地图数组 pr

  • 基于Android实现数独游戏

    本文实例为大家分享了Android实现数独游戏的具体代码,供大家参考,具体内容如下 1.在src中有4个Java类: 其中代码分别是: Game.java: package com.example.test1; import android.R.integer; public class Game { public final String str="360000000004230800000004200" +"070460003820000014500013020"

随机推荐