/**************************************************** 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 random=%d ",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(" "); } printf(" "); #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," "); } fprintf(fp," "); 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; }