/****************************************************
input:extern int sudo[9][9]
output:对于数独中空位进行检查
简介:判断输入的数据在数独数列中是否正确
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "SudoPrint.h"
extern int sudo[9][9]; //调用main函数中的数独数列
extern int sudocheck[9][9];
void SudoCheck()
{
int x=17,y=8; //数独数组中的空位坐标
int i=0,j=0; //数独数组中的第0行和第0列开始进行数据判断
char inputdata;
while(inputdata!='o'&&inputdata!='O')
{
gotoxy(x,y);
scanf("%c",&inputdata);
fflush(stdin);
if(sudo[i][j]==(inputdata-48)) //判断输入是否正确 符合数独唯一解
{
gotoxy(5,5);
printf("恭喜你数据输入正确,请输入下一个数据!");
sudocheck[i][j]=(inputdata-48); //存入数独数组中
if(i==8&&j==8) //如果进行到最后一个正确情况 跳出循环
{
break;
}
if(x==57) //如果坐标x到达57 说明奇数行应该进入下一行判断
{
y++;
x=22;
i++;
j=1;
}
else if(x==52)//如果坐标x到达52 说明偶数行应该进入下一行判断
{
y++;
i++;
x=17;
j=0;
}
else
{
x+=10; //如果不是57,我们正常进行下一步
j+=2;
}
}
else
{
gotoxy(5,5);
printf("抱歉!你的输入数据有误,请重新尝试!");
}
SudoPrint();
}
system("cls");
gotoxy(5,5);
printf("游戏结束!");
getch();
gotoxy(5,5);
printf("还想不想再来一次? 非常想(y) 不想(按任意键)");
}
/****************************************************
input:int temp[9][9]
output:输出数独游戏界面
简介:输出数独游戏界面 输出过场动画 ,生成一个最初的游戏数独数组
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
extern int sudo[9][9]; //调用main函数中的数独数列
extern int sudocheck[9][9]; //游戏中使用部分挖空的数独数组
void gotoxy(int x, int y)
{
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
void plane(int i) //输出两架飞机
{
/*左边的飞机*/
gotoxy(i,10);
printf(" *");
gotoxy(i,11);
printf("* **");
gotoxy(i,12);
printf("* ***");
gotoxy(i,13);
printf("*******");
gotoxy(i,14);
printf("* ***");
gotoxy(i,15);
printf("* **");
gotoxy(i,16);
printf(" *");
/*右边的飞机*/
gotoxy(80-i,10);
printf(" *");
gotoxy(80-i,11);
printf(" ** *");
gotoxy(80-i,12);
printf(" *** *");
gotoxy(80-i,13);
printf("*******");
gotoxy(80-i,14);
printf(" *** *");
gotoxy(80-i,15);
printf(" ** *");
gotoxy(80-i,16);
printf(" *");
}
/*数独数列部分区域需要挖空,填0,作为游戏空
偶数行,偶数列挖空。奇数行奇数列挖空。
完成后一个宫空位4个或5个 */
void Gamearray()
{
int i,j;
for(i=0;i<9;i++)
{
gotoxy(15,8+i);
for(j=0;j<9;j++)
{
if(i%2==0) //当i为偶数时候
{
if(j%2==1) //j为奇数的数据填入
{
sudocheck[i][j]=sudo[i][j];
}
}
else
{
if(j%2==0) //j为偶数的数据填入
{
sudocheck[i][j]=sudo[i][j];
}
}
}
}
}
void Sudo_Interface() //打印游戏前的过场动画
{
int i;
system("COLOR 34"); // DOS2f 窗 背景绿色字白色
for(i=1;i<8;i++)
{
gotoxy(26,4);
printf("-----欢迎进入数独游戏-----");
plane(i*10);
sleep(1);
system("cls");
}
gotoxy(26,4);
printf("-----欢迎进入数独游戏-----");
gotoxy(25,8);
printf("-----请按任意键继续-----");
getch();
system("cls");
}
void SudoPrint()
{
gotoxy(5,1);
printf("**请把数字1-9填入数列中数据为0的空格中,按回车确定**");
gotoxy(5,2);
printf("**要求填入数字不能在同一行、列或宫中出现多于一次**");
gotoxy(5,3);
printf("**按照光标引导一次填入数据,直到完成数独数列游戏**");
int i,j;
gotoxy(15,7);
printf("*********************************************");
for(i=0;i<9;i++)
{
gotoxy(15,8+i);
for(j=0;j<9;j++)
{
printf("| %d |",sudocheck[i][j]);
}
}
gotoxy(15,17);
printf("*********************************************");
gotoxy(5,21);
printf("字母O 退出 Enter 确认输入 Backspce 删除当前输入 ");
}
#ifndef _SuduPrint_H
#define _SuduPrint_H
void gotoxy(int x, int y);
void Gamearray();
void Sudo_Interface();
void SudoPrint();
#endif
/****************************************************
input:int temp[9][9],int i,int j,int k
output:boolean
简介:判断数组temp中第i行,第j列,中是否能够存放k数据,
是否符合数独数列规则
*****************************************************/
#include <stdio.h>
#include "SuduCheck.h"
int SuduCheck(int temp[9][9],int i,int j,int k) //判断是否可以将第i行、第j列的数设为k
{
int m,n;
//判断行
for(n=0;n<9;n++)
{
if(temp[i][n]==k)
return 0;
}
//判断列
for(m=0;m<9;m++)
{
if(temp[m][j]==k)
return 0;
}
//判断所在小九宫格
int t1=(i/3)*3,t2=(j/3)*3;
for(m=t1;m<t1+3;m++)
{
for(n=t2;n<t2+3;n++)
{
if(temp[m][n]==k)
return 0;
}
}
//可行,返回true
return 1;
}
#ifndef _SudoCheck_H
#define _SudoCheck_H
void SudoCheck();
#endif
/****************************************************
input:int temp[9][9]
output:生成一个随机的数独列表
简介:输入一个空的数组,可以生成一个符合规范的数独数列
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "SuduInput.h"
#include "SuduCheck.h"
#include "SuduGain.h"
void cleanup(int temp[9][9])
{
int i,j;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
temp[i][j]=0;
}
}
}
int SuduGain(int temp[9][9])
{
int i,j,m,n,random=1; //初始值第一个随机数是我学号最后一位,201810775001
//srand((unsigned)time(NULL)); //随机数据初始化
for(i=0;i<9;i++) //循环每一行
{
for(j=0;j<9;j++) //循环每一列
{
m=0;
while(SuduCheck(temp,i,j,random)==0) //判断此随机数是否能够使用,如果能够使用跳出循环,否则继续循环
{
random=rand()%9+1; //生成一个0-9的随机数
m++;
if(m>100) //如果同一个位置循环100次失败,判断此数独行失败,返回从新开始
{
return 0;//此数独数列失败,从新开始
}
}
temp[i][j]=random;//此数已经通过检查,可以放入数组
//SuduInput(temp);
//printf("m=%d n=%d\trandom=%d\n",m,n,random);
//getch();
}
}
return 1; //数独列表生成成功
}
void SudoBuilde(int temp[9][9])
{
int i,n;
n=1; //输入需要数独数据个数
for(i=0;i<n;i++) //循环获得数独
{
do
{
cleanup(temp); //清理数组
}while(SuduGain(temp)==0); //如果数独生成失败,返回结果为0,则清空sudo数组,继续再试直到成功
SuduInput(temp);
}
}
#ifndef _SuduGain_H
#define _SuduGain_H
void cleanup(int temp[9][9]);
int SuduGain(int temp[9][9]);
#endif
/****************************************************
input:int temp[9][9]
output:输出数组temp到文件中和打印到屏幕上
简介:把传递的数组打印到 sudotiku.txt文件中和屏幕上
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "SuduInput.h"
void SuduInput(int temp[9][9])
{
int i,j;
FILE *fp;
#if 0
//数独输出到屏幕
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
printf("%d",temp[i][j]);
}
printf("\n");
}
printf("\n");
#endif
//数独输出到文档
if((fp = fopen("sudotiku.txt", "w+")) == NULL)
{
printf("Can,t opent file!");
exit(1);
}
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
fprintf(fp,"%d ",temp[i][j]);
}
fprintf(fp,"\n");
}
fprintf(fp,"\n");
fclose(fp);
}
#ifndef _SuduInput_H
#define _SuduInput_H
void SuduInput(int temp[9][9]);
#endif
/****************************************************
说明: main.c 2018.10.14 longjt
input:None
output:None
简介:主函数完成数独游戏
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "SuduInput.h"
#include "SuduCheck.h"
#include "SuduGain.h"
#include "SudoPrint.h"
int sudo[9][9]={0};
int sudocheck[9][9]={0};
int main(int argc, char *argv[])
{
do{
cleanup(sudocheck); //先清理干净游戏数独数组
SudoBuilde(sudo); //生成一个数独数列
Sudo_Interface(); //数独游戏过场动画
Gamearray(); //生成一个最初的数独游戏数组
SudoPrint(); //打印游戏界面
SudoCheck();
fflush(stdin); //清理干净flash
}while(getch()=='y');
getch();
return 0;
}