713 lines
22 KiB
C
713 lines
22 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
//gteet the user
|
|
void greetintmessage(void);
|
|
|
|
//state the rules of playing the game
|
|
void rules(void);
|
|
|
|
//ask the user to select level
|
|
int levelchoosing(void);
|
|
|
|
//verify the correctness of input(length and range)
|
|
int verifyinput(void);
|
|
|
|
//Put content of cell filled with 0 to be a space
|
|
void initboard(void);
|
|
|
|
//print out the game board
|
|
void printboard(void);
|
|
|
|
//fill in some numbers as tips for user by open a sudoku file
|
|
int generatecontent(int);
|
|
|
|
//verify the correctness of option choenn(length and range)
|
|
int verifyoption(void);
|
|
|
|
//accept input from user and modify the array accorgingly
|
|
//also it checks wether the number is allowed to place at the cell or not
|
|
void acceptinput(void);
|
|
|
|
//enter row and check allowance
|
|
int enterrow(void);
|
|
|
|
//enter column and check allowance
|
|
int entercolumn(void);
|
|
|
|
//give hints to user when requested
|
|
void givehint(int);
|
|
|
|
//delete inputed number before
|
|
void deletenumber(int);
|
|
|
|
//check whether the user has finished the game
|
|
//by testing wether all the blankets are filled with number
|
|
//return '1' when all the cell is filled
|
|
//'o' when not yet finished
|
|
int checkgameend(void);
|
|
|
|
//check if the numbers in each row are unique and digits 1-9 are present
|
|
//after the user had finished the game
|
|
int checkrow(void);
|
|
|
|
//compare the elements in the same row to check uniqueness
|
|
//used inside int checkrow
|
|
int comparerow(int,int a);
|
|
|
|
//check if the numbers in each column are unique and digits 1-9 are present
|
|
//after the user had finished the game
|
|
int checkcolumn(void);
|
|
|
|
//compare the elements in the same column to check uniqueness
|
|
//used inside int checkcolumn
|
|
int comparecolumn(int,int a);
|
|
|
|
//print out the correct solution if the user'solution is not correct
|
|
void printsolution(int);
|
|
|
|
//congratulation message to the user if solution is correct
|
|
void congratulation(void);
|
|
|
|
//ask wether the user want to play another game
|
|
int playothergame(void);
|
|
|
|
//array used to store value of the game
|
|
int gameboard[9][9];
|
|
|
|
//The following is the main part of this program
|
|
main()
|
|
{
|
|
int level,option;//variable for receive levelchoosing
|
|
int randnum;//variable for receive random number from generatecontent
|
|
int crow,ccol;//variables for receive results from checkrow and checkcolumn
|
|
|
|
greetintmessage();
|
|
rules();
|
|
do{
|
|
level = levelchoosing();
|
|
initboard();
|
|
printf("=================================================================\n\n");
|
|
randnum = generatecontent(level);
|
|
do{
|
|
printboard();
|
|
printf("1.Enter number\n2.Give hints to current board\n3.Delete input before\n4.Generate new board\n5.Solution to current board\n");
|
|
printf("Your choice: ");
|
|
option = verifyoption();
|
|
if(option == '1')
|
|
{
|
|
printf("\nPlease choose the grid you want and input number.");
|
|
acceptinput();
|
|
system("CLS");
|
|
}
|
|
else if(option == '2')
|
|
{
|
|
givehint(randnum);
|
|
}
|
|
else if(option == '3')
|
|
{
|
|
printf("\nPlease choose the grid you want to delete:");
|
|
deletenumber(randnum);
|
|
}
|
|
else if(option == '4')
|
|
{
|
|
randnum = generatecontent(level);
|
|
system("CLS");
|
|
}
|
|
else
|
|
{
|
|
printf("\nCorrect solution is:\n");
|
|
printsolution(randnum);
|
|
}
|
|
}while(checkgameend() != 1);
|
|
|
|
if(option != '5'){
|
|
//after the user have completed the sudoku
|
|
printf("Great!You have completed the sudoku!\n");
|
|
printf("Let's check the answers now........\n\n");
|
|
//check solution
|
|
printboard();
|
|
crow = checkrow();
|
|
ccol = checkcolumn();
|
|
if(crow == 1 && ccol == 1)
|
|
{
|
|
congratulation();
|
|
}
|
|
else
|
|
{
|
|
printf("\nSorry,your solution is not correct.\n");
|
|
printf("The correct solution should be: \n");
|
|
printsolution(randnum);
|
|
}
|
|
}
|
|
}while(playothergame() == 1);
|
|
}
|
|
|
|
/*The following is the detail part of all funtions*/
|
|
/*gteet the user*/
|
|
void greetintmessage()
|
|
{
|
|
printf("\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
|
|
printf("%18cWelcome to play S-U-D-O-K-U game!\n",' ');
|
|
printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
|
|
printf("\n");
|
|
}
|
|
|
|
/*state the rules of playing the game*/
|
|
void rules()
|
|
{
|
|
printf("%32cRules :\n",' ');
|
|
printf("\n%5cFill in all the cells so that every column, row and 3 x 3\n",' ');
|
|
printf("%5cboxes contains each of the digits 1 to 9 without repetition.\n",' ');
|
|
}
|
|
|
|
/*ask the user to select level*/
|
|
int levelchoosing()
|
|
{
|
|
char input[10];
|
|
printf("\n=================================================================\n");
|
|
printf("Please choose the level you want( 1-easy 2-medium 3-hard ) : ");
|
|
do{
|
|
scanf("%s",input);
|
|
if ((strlen(input) != 1) || !( (input[0]<'4') && (input[0]>'0') ))
|
|
{
|
|
printf("Input out of range!Input again please: ");
|
|
}
|
|
} while ((strlen(input) != 1) || !( (input[0]<'4') && (input[0]>'0') ));
|
|
|
|
printf("You have choose level %d\n",input[0]-48);
|
|
printf("Game start!\nChoose the following options please.\n");
|
|
|
|
return input[0];
|
|
}
|
|
|
|
/*verify the correctness of input(length and range)*/
|
|
int verifyinput()
|
|
{
|
|
char input[10];
|
|
do{
|
|
scanf("%s",input);
|
|
if ((strlen(input) != 1) || !( (input[0]<'2') && (input[0]>='0') ))
|
|
{
|
|
printf("Input out of range!Input again please: ");
|
|
}
|
|
} while ((strlen(input) != 1) || !( (input[0]<'2') && (input[0]>='0') ));
|
|
return input[0];
|
|
}
|
|
|
|
/*Put content of cell filled with 0 to be a space*/
|
|
void initboard()
|
|
{
|
|
int i,j;
|
|
for(i = 0;i < 9;i++){
|
|
for(j = 0;j < 9;j++){
|
|
gameboard[i][j] = ' ';
|
|
}//for i
|
|
}//for j
|
|
}
|
|
|
|
/*print out the game board */
|
|
void printboard()
|
|
{
|
|
char space = ' ';
|
|
char separator[] = "+- - - -+- - - -+- - - -+";
|
|
char row = 'a';
|
|
int i, j;
|
|
|
|
printf("%20c 1 2 3 4 5 6 7 8 9\n",space);
|
|
for (i=0;i<9;i++)
|
|
{
|
|
if(i%3 ==0)
|
|
{
|
|
printf("%20c%s\n",space,separator);
|
|
}
|
|
printf("%18c%c | %c %c %c | %c %c %c | %c %c %c |\n",space,row+i,gameboard[i][0],gameboard[i][1],gameboard[i][2],gameboard[i][3],gameboard[i][4],gameboard[i][5],gameboard[i][6],gameboard[i][7],gameboard[i][8]);
|
|
}
|
|
printf("%20c%s\n",space,separator);
|
|
}
|
|
|
|
/*fill in some numbers by open a sudoku file*/
|
|
int generatecontent(level)
|
|
{
|
|
int i,j,randnum;
|
|
char readchar,filename[20],string[10] = ".txt";
|
|
FILE *fp;
|
|
srand(time(NULL));
|
|
//randomly genereta a game for users according to their request level
|
|
if(level == '1')
|
|
{
|
|
randnum = (rand() %10) + 1;
|
|
sprintf(filename,"%d%s",randnum,string);//group number and string together
|
|
}
|
|
else if(level == '2')
|
|
{
|
|
randnum = (rand() %10) + 11;
|
|
sprintf(filename,"%d%s",randnum,string);
|
|
}
|
|
else if(level == '3')
|
|
{
|
|
randnum = (rand() %10) + 21;
|
|
sprintf(filename,"%d%s",randnum,string);
|
|
}
|
|
//open file
|
|
fp=fopen(filename,"r");
|
|
if(fp==NULL)
|
|
{
|
|
printf("cannot open the file!\n");//when failed to open file
|
|
exit(1);
|
|
}
|
|
//read character from the file
|
|
readchar = fgetc(fp);
|
|
while(readchar != EOF) {
|
|
for(i=0;i<9;i++)
|
|
{
|
|
for(j=0;j<=9;j++)
|
|
{
|
|
gameboard[i][j] = readchar;
|
|
readchar = fgetc(fp);
|
|
}//for i
|
|
}//for j
|
|
}//for while loop
|
|
fclose(fp);
|
|
|
|
return randnum;
|
|
}
|
|
|
|
/*verify the correctness of option chosen(length and range)*/
|
|
int verifyoption(void)
|
|
{
|
|
char option[10];
|
|
do{
|
|
scanf("%s",option);
|
|
if ((strlen(option) != 1) || !( (option[0]<'6') && (option[0]>'0') ))
|
|
{
|
|
printf("Input out of range!Input again please: ");
|
|
}
|
|
}while((strlen(option) != 1) || !( (option[0]<'6') && (option[0]>'0') ));
|
|
return option[0];
|
|
}
|
|
|
|
//accept input from user and modify the array accorgingly
|
|
//accept input from user and modify the array accorgingly
|
|
//it checks wether the number is allowed to place at the cell or not*/
|
|
void acceptinput()
|
|
{
|
|
int i , j,row, col, number;
|
|
char input[20];
|
|
int count1 = 0,count2 = 0;
|
|
int startingrow,startingcol;
|
|
|
|
//repeatly ask to do input if the cell being chosen is occupied
|
|
do{
|
|
//ask to enter column
|
|
col = entercolumn() - 49;
|
|
//ask to enter row
|
|
row = enterrow() - 97;
|
|
//check wether the cell chosen is already filled or not
|
|
//if yes,print warning message
|
|
//if not,fill the cell with number assigned by user
|
|
if (gameboard[row][col] !='.')
|
|
{
|
|
printf("The cell is already occupied!\n");
|
|
printf("Input again please.");
|
|
}
|
|
}while(gameboard[row][col] !='.');
|
|
//ask to enter number
|
|
printf("Which number(1-9)do you want to type in? ");
|
|
do {
|
|
scanf("%s",input);
|
|
if ((strlen(input) != 1) || !( (input[0]<='9') && (input[0]>'0') ))
|
|
{
|
|
printf("Input out of range! Input again please: ");
|
|
}
|
|
} while ((strlen(input) != 1) || !( (input[0]<='9') && (input[0]>'0') ));
|
|
number = input[0];
|
|
//checks wether the number is allowed to place at the cell or not
|
|
//check row and cloumn
|
|
//by testing wether the same number is presented
|
|
for(i = 0;i < 9;i++)
|
|
{
|
|
if(gameboard[row][i] == number)
|
|
{
|
|
count1++;
|
|
}
|
|
if(gameboard[i][col] == number)
|
|
{
|
|
count1++;
|
|
}
|
|
}
|
|
//check 3x3 boxes
|
|
//check by dividing the game board into 9 small boxes
|
|
//after detecting which small box the chosen grid lying on
|
|
//it test wether same number is presented in other grids within the same box
|
|
if(row < 3)
|
|
{
|
|
startingrow = 0;
|
|
}
|
|
else if((row > 2) && (row < 6))
|
|
{
|
|
startingrow = 3;
|
|
}
|
|
else if((row > 5) && (row < 9))
|
|
{
|
|
startingrow = 6;
|
|
}
|
|
if(col < 3)
|
|
{
|
|
startingcol = 0;
|
|
}
|
|
else if((col > 2) && (col < 6))
|
|
{
|
|
startingcol = 3;
|
|
}
|
|
else if((col > 5) && (col < 9))
|
|
{
|
|
startingcol = 6;
|
|
}
|
|
for(i = 0;i < 3;i++)
|
|
{
|
|
for(j = 0;j < 3;j++)
|
|
{
|
|
if(gameboard[startingrow+i][startingcol+j] == number)
|
|
{
|
|
count2++;
|
|
}
|
|
}
|
|
}
|
|
//assign value to the cell
|
|
if((count1 == 0) && (count2 == 0))
|
|
{
|
|
gameboard[row][col] = number;
|
|
}
|
|
else
|
|
{
|
|
printf("=================================================================\n");
|
|
printf("Sorry,input number is repeated either in row,column or 3x3 box\n");
|
|
printf("Do you really want to input(1-yes 0-no)? ");
|
|
input[0] = verifyinput();
|
|
if(input[0] == '1' )
|
|
{
|
|
gameboard[row][col] = number;
|
|
}
|
|
}
|
|
//restore value of two counter
|
|
count1 = 0;
|
|
count2 = 0;
|
|
}
|
|
|
|
//enter row and check allowance
|
|
int enterrow(void)
|
|
{
|
|
char input[10];
|
|
printf("Which row do you want to choose(e.g.a)? ");
|
|
do {
|
|
scanf("%s",input);
|
|
if ((strlen(input) != 1) || !( (input[0]<'j') && (input[0]>='a') ))
|
|
{
|
|
printf("Input out of range! Input again please: ");
|
|
}
|
|
} while ((strlen(input) != 1) || !( (input[0]<'j') && (input[0]>='a') ));
|
|
return input[0];
|
|
}
|
|
|
|
//enter column and check allowance
|
|
int entercolumn(void)
|
|
{
|
|
char input[10];
|
|
printf("\nWhich column do you want to choose(e.g.1)? ");
|
|
do {
|
|
scanf("%s",input);
|
|
if ((strlen(input) != 1) || !( (input[0]<='9') && (input[0]>'0') ))
|
|
{
|
|
printf("Input out of range! Input again please: ");
|
|
}
|
|
} while ((strlen(input) != 1) || !( (input[0]<='9') && (input[0]>'0') ));
|
|
return input[0];
|
|
}
|
|
|
|
//give hints to user when requested
|
|
void givehint(randnum)
|
|
{
|
|
int i,j,row,col;
|
|
char space = ' ';
|
|
char readchar,filename[20],string[10] = "s.txt";
|
|
FILE *fp;
|
|
//ask to enter column
|
|
col = entercolumn() - 49;
|
|
//ask to enter row
|
|
row = enterrow() - 97;
|
|
sprintf(filename,"%d%s",randnum,string);
|
|
fp=fopen(filename,"r");
|
|
if(fp==NULL)
|
|
{
|
|
printf("cannot open the file!\n");
|
|
exit(1);
|
|
}
|
|
readchar = fgetc(fp);
|
|
while(readchar != EOF) {
|
|
for(i=0;i<9;i++)
|
|
{
|
|
for(j=0;j<=9;j++)
|
|
{
|
|
if(i ==row && j == col)
|
|
{
|
|
if(gameboard[row][col] == '.')
|
|
{
|
|
gameboard[i][j] = readchar;
|
|
printf("=================================================================\n");
|
|
}
|
|
else
|
|
{
|
|
printf("=================================================================\n");
|
|
printf("%23c####################\n",space);
|
|
printf("%23cNumber is presented!\n",space);
|
|
printf("%23c####################\n",space);
|
|
}
|
|
}
|
|
readchar = fgetc(fp);
|
|
}//for i
|
|
}//for j
|
|
}//for while loop
|
|
fclose(fp);
|
|
}
|
|
|
|
//delete inputed number before
|
|
void deletenumber(randnum)
|
|
{
|
|
int i,j,row,col;
|
|
char space = ' ';
|
|
char readchar,filename[20],string[10] = ".txt";
|
|
FILE *fp;
|
|
|
|
//ask to enter column
|
|
col = entercolumn() - 49;
|
|
//ask to enter row
|
|
row = enterrow() - 97;
|
|
sprintf(filename,"%d%s",randnum,string);
|
|
fp=fopen(filename,"r");
|
|
if(fp==NULL)
|
|
{
|
|
printf("cannot open the file!\n");
|
|
exit(1);
|
|
}
|
|
readchar = fgetc(fp);
|
|
while(readchar != EOF) {
|
|
for(i=0;i<9;i++)
|
|
{
|
|
for(j=0;j<=9;j++)
|
|
{
|
|
if(i ==row && j == col)
|
|
{
|
|
if(readchar == '.' && gameboard[row][col] != '.')
|
|
{
|
|
gameboard[row][col] = '.';
|
|
printf("=================================================================\n");
|
|
}
|
|
else if(readchar == '.' && gameboard[row][col] == '.')
|
|
{
|
|
printf("=================================================================\n");
|
|
printf("%21c#######################\n",space);
|
|
printf("%21cNothing can be deleted!\n",space);
|
|
printf("%21c#######################\n",space);
|
|
}
|
|
else
|
|
{
|
|
printf("=================================================================\n");
|
|
printf("%8c########################################################\n",space);
|
|
printf("%8cThe number can't be cancelled.It is provided originally!\n");
|
|
printf("%8c########################################################\n",space);
|
|
}
|
|
}
|
|
readchar = fgetc(fp);
|
|
}//for i
|
|
}//for j
|
|
}//for while loop
|
|
fclose(fp);
|
|
}
|
|
|
|
/*check whether the user has finished the game
|
|
by testing wether all the blankets are filled
|
|
with number*/
|
|
//return '1' when all the cell is filled
|
|
//'o' when not yet finished
|
|
int checkgameend()
|
|
{
|
|
int i,j;
|
|
int counter = 0;
|
|
for(i = 0;i < 9;i++){
|
|
for(j = 0;j < 9;j++){
|
|
if(gameboard[i][j] != '.'){
|
|
counter ++;
|
|
}
|
|
}//for i
|
|
}//for j
|
|
|
|
if(counter == 81)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//check if the numbers in each row are unique and digits 1-9 are present
|
|
int checkrow(void)
|
|
{
|
|
int i,j;
|
|
int sum,counter1 = 0,counter2 = 0,counter3 = 0;
|
|
for(i = 0;i < 9;i++)
|
|
{
|
|
sum = (gameboard[i][0]+gameboard[i][1]+gameboard[i][2]+gameboard[i][3]+gameboard[i][4]+gameboard[i][5]+gameboard[i][6]+gameboard[i][7]+gameboard[i][8])-48*9;
|
|
if(sum == 45)
|
|
{
|
|
counter1 ++;
|
|
}
|
|
}
|
|
//check uniqueness
|
|
for(i = 0;i < 9;i++){
|
|
for(j = 1;j < 9;j++){
|
|
counter3 = comparerow(i,j);
|
|
counter2 += counter3;
|
|
counter3 = 0;
|
|
}//for j
|
|
}//for i
|
|
if((counter1 == 9) && (counter2 == 324))//The total combination in comparison is 324(36x9)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//compare the elements in the same row to check uniqueness
|
|
//used inside int checkrow
|
|
int comparerow(i,a)
|
|
{
|
|
int j,counter = 0;
|
|
for(j = a;j < 9;j++)
|
|
{
|
|
if(gameboard[i][a-1] != gameboard[i][j])
|
|
{
|
|
counter ++;
|
|
}
|
|
else
|
|
{
|
|
printf("More than one %c are found in row %d!\n",gameboard[i][a-1],i+1);
|
|
}
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
//check if the numbers in each column are unique and digits 1-9 are present
|
|
int checkcolumn(void)
|
|
{
|
|
int i,j;
|
|
int sum,counter1 = 0,counter2 = 0,counter3 = 0;
|
|
for(i = 0;i < 9;i++)
|
|
{
|
|
sum = (gameboard[0][i]+gameboard[1][i]+gameboard[2][i]+gameboard[3][i]+gameboard[4][i]+gameboard[5][i]+gameboard[6][i]+gameboard[7][i]+gameboard[8][i])-48*9;
|
|
if(sum == 45)
|
|
{
|
|
counter1 ++;
|
|
}
|
|
}
|
|
//check uniqueness
|
|
for(i = 0;i < 9;i++){
|
|
for(j = 1;j < 9;j++){
|
|
counter3 = comparecolumn(i,j);
|
|
counter2 += counter3;
|
|
counter3 = 0;
|
|
}//for j
|
|
}//for i
|
|
if((counter1 == 9) && (counter2 == 324))//The total combination in comparison is 324(36x9)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//compare the elements in the same column to check uniqueness
|
|
//used inside int checkcolumn
|
|
int comparecolumn(i,a)
|
|
{
|
|
int j,counter = 0;
|
|
for(j = a;j < 9;j++)
|
|
{
|
|
if(gameboard[a-1][i] != gameboard[j][i])
|
|
{
|
|
counter ++;
|
|
}
|
|
else
|
|
{
|
|
printf("More than one %c are found in column %d!\n",gameboard[a-1][i],i+1);
|
|
}
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
/*print out the correct solution if the user'solution is not correct*/
|
|
void printsolution(randnum)
|
|
{
|
|
|
|
int i,j;
|
|
char readchar,filename[20],string[10] = "s.txt";
|
|
FILE *fp;
|
|
|
|
sprintf(filename,"%d%s",randnum,string);
|
|
fp=fopen(filename,"r");
|
|
if(fp==NULL)
|
|
{
|
|
printf("cannot open the file!\n");
|
|
exit(1);
|
|
}
|
|
readchar = fgetc(fp);
|
|
while(readchar != EOF) {
|
|
for(i=0;i<9;i++)
|
|
{
|
|
for(j=0;j<=9;j++)
|
|
{
|
|
gameboard[i][j] = readchar;
|
|
readchar = fgetc(fp);
|
|
}//for i
|
|
}//for j
|
|
|
|
}//for while loop
|
|
fclose(fp);
|
|
printboard();
|
|
}
|
|
|
|
/*congratulation message to the user if solution is correct*/
|
|
void congratulation()
|
|
{
|
|
char space = ' ';
|
|
printf("%8c+++++++++++++++++++++++++++++++++++++++++++++++++++\n",space);
|
|
printf("%8cCONGRATULATION!!You have done the sudoku correctly!\n",space);
|
|
printf("%8c+++++++++++++++++++++++++++++++++++++++++++++++++++\n",space);
|
|
}
|
|
|
|
/*ask wether the user want to play another game*/
|
|
int playothergame()
|
|
{
|
|
char input[10];
|
|
printf("=================================================================\n");
|
|
printf("Do you want to play another game(1-yes 0-no)? ");
|
|
input[0] = verifyinput();
|
|
if(input[0] == '1')
|
|
{
|
|
return 1;
|
|
}
|
|
else if(input[0] == '0')
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|