Files
banson_hker/job1/references/S10/Source_code/S10.c
louiscklaw 191665ddf2 update,
2025-02-01 02:00:11 +08:00

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;
}
}