[C language] super detailed -- sanziqi game -- implementation and analysis
This time I learn to write a Sanzi chess software, which basically uses all the knowledge I have learned before. Now I begin to analyze this Sanzi chess game.
Three pieces of chess are composed of: chessboard, our chess and opponent's chess. It consists of three parts.
Brief description of elements of chessboard
First, the chessboard is a 3 * 3 square (so a two-dimensional array is used). Each grid should be initialized into a space 'to put the chessboard.
Second, there should be separation lines between squares, but note that there are no division lines around the chessboard.
Third, define the implementation of chess pieces. We use * to represent our chess pieces and # to represent computer chess pieces.
Fourth, define the victory condition. The same symbol becomes a diagonal, and the three symbols in the horizontal or vertical row form a line.
Complete game display
Before implementing the game in detail, let's take a complete look at our code.
The game always uses three files, game. H, game. C and test. C. These three files are used in one project and are inseparable.
test.c is the main file, which stores the function calls of the main function and game.c file.
game.h is a header file that stores the game.c function declaration and the header files and constants referenced by the whole program.
game.c is a file used to store the function body
test.c
#include "game.h" void menu() { printf("***************************\n"); printf("******** 1.play *********\n"); printf("******** 0.exit *********\n"); printf("***************************\n"); } void game() { char board[ROW][COL] = { 0 }; char ret = 0; Initboard(board, ROW, COL);//Initialize array to '' display_board(board, ROW, COL);//Print chessboard while (1) { player_move(board, ROW, COL);//Players play chess display_board(board, ROW, COL);//After playing chess, you should also print the chessboard ret = is_win(board,ROW,COL);//Judge victory conditions if (ret != 'C') { break; } computer_move(board, ROW, COL);//Computer chess display_board(board, ROW, COL);//After playing chess, you should also print the chessboard ret = is_win(board,ROW,COL); if (ret != 'C') { break; } } //Judge victory conditions if (ret == 'Q') { printf("it ends in a draw!\n"); } if (ret == '#') { printf("Computer wins!\n"); } if (ret == '*') { printf("Players win!\n"); } } //Main function int main() { int input = 0; srand((unsigned int)time(NULL)); menu(); do { printf("Please enter:(1 or 0) > "); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("Exit the game\n"); break; default: printf("Input error. Please re-enter\n"); break; } } while (input); return 0; }
game.c (file for storing function body)
#include "game.h" //Initialize chessboard to '' void Initboard(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ' '; } } } //Print chessboard void display_board(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf(" %c ",board[i][j]); //Split line printing of chessboard if (j < col - 1) { printf("|"); } } printf("\n"); if (i < row - 1) { for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) { printf("|"); } } } printf("\n"); } } //Players play chess. void player_move(char board[ROW][COL], int row, int col) { printf("Player walk:> "); int x = 0; int y = 0; while (1) { scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("The coordinate is already occupied"); } } else { printf("Input error, please re-enter"); } } } //Computer chess layout. void computer_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } //is_ The full () function determines whether the chessboard is full, because it is only used in is_win() function, so you don't need to declare it in the header file game.h. int is_full(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; } //Judge victory conditions char is_win(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' ') { return board[i][1]; } } for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') { return board[1][j]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') { return board[1][1]; } //If the chessboard is full, it's a draw, isn't it_ The full() function determines whether the chessboard is full if (is_full(board, row ,col) == 1) { return 'Q'; } return 'C'; }
game.h (header file)
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <time.h> #include <stdlib.h> #define ROW 3 #define COL 3 void Initboard(char board[ROW][COL], int row, int col); void display_board(char board[ROW][COL], int row, int col); void player_move(char board[ROW][COL], int row, int col); void computer_move(char board[ROW][COL], int row, int col); char is_win(char board[ROW][COL], int row, int col);
Detailed analysis
Using segmented parsing, please see the above code for the complete code.
It mainly parses the game.c file, that is, the function body file!!!
**Note: all functions parsed this time will be declared in the header file * * game.h.
Before parsing the body function, we first parse the header file
game.h
#define _CRT_SECURE_NO_WARNINGS 1 //These three header files are needed for the whole project #Include < stdio. H > / / this is the most familiar input / output function. #Include < time. H > / / this function is used to obtain the system time. This time, it is mainly used to form a timestamp in conjunction with the header file < stdlib. H >. #Include < stdlib. H > / / the rand function and srand function are mainly used. They are random number generators. #define ROW 3 / / define a constant ROW to represent a ROW #define COL 3 / / define a constant COL to represent a column //The following functions will be discussed later void Initboard(char board[ROW][COL], int row, int col); void display_board(char board[ROW][COL], int row, int col); void player_move(char board[ROW][COL], int row, int col); void computer_move(char board[ROW][COL], int row, int col); char is_win(char board[ROW][COL], int row, int col);
test.c
Define a two-dimensional array in the game() function of our main file.
void game() { char board[ROW][COL] = { 0 };//Define a two-dimensional array. Note that we use the constants referenced in the header file to define rows and columns. Note that we initialize 0 here. }
game.c
The first function: Initboard() initializes the chessboard coordinates
Initialize the two-dimensional array board [] [] defined by us, and initialize the array to space ';
//Control all rows and columns to initialize 0 in the array to '' void Initboard(char board[ROW][COL], int row, int col) { //In this, variables i and j are defined to control rows and columns respectively. for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ' '; // Initialize all 0's in the array as spaces' } } }
The second function: displaybaord() prints the chessboard
This function is implemented, which is difficult for novices to design, so we divide it into two steps;
The first step is to print the coordinate position in the chessboard
void displayboard(char board[ROW][COL] , int row,int col){ for(int i = 0; i < row; i++){ for(int j = 0 ; j < col ; j++){ printf(" %c ",board[i][j]);//Note that there is a space on both sides of% c. } printf("\n");//Wrap after each line is printed. } }
The second step is to add a division line between coordinate positions
This is also the full version of the chessboard
void displayboard(char board[ROW][COL] , int row,int col){ int i = 0; int j = 0; for(i = 0; i < row; i++) { for(j = 0 ; j < col ; j++) { printf(" %c ",board[i][j]); //The following is the newly added code; Split line of column if(j<col-1){ //Because there is only a dividing line between each column, it must be j < COL-1 printf("|"); } } printf("\n"); //The following are all new codes to print the split line of each line if(i < row -1) // Because there is only between each line, all conditions are I < row-1; { for( j= 0; j < col; j++) //Print split lines { printf("---"); if (j < col - 1) //Note: the dividing line of the line also has "|"; { printf("|"); } } } printf("\n");If a line is not printed, it will be wrapped; } }
The third function: player_move players play chess
This function controls the direction of the player's coordinates. For example, if you enter 2, it will play chess in the second row and the second column.
However, the coordinate range of our function is 3 * 3. After all, it is only a three word chess. If the number is not 1 ~ 3, we will give the prompt we wrote.
void player_move(char board[ROW][COL] , int row ,int col){ int x = 0; //x-axis coordinates, i.e. abscissa int y = 0;//y-axis coordinates, that is, ordinates //Set up a cycle. If the coordinate value is not entered correctly, it will cycle all the time. Enter the correct coordinates to jump out of the loop. while(1) { printf("Players play chess: "); scanf("%d %d",&x,&y); if(x >= 1 && x <= row && y >= 1 && y <= 3)//Limit the range of x and y, which will take effect. { //The subscript of the array is 0 ~ 2, so our x and y can coincide with the subscript of the board [] [] array after subtracting 1 if (board[x-1][y-1] == ' ') //If the coordinates we entered have not been played by the computer, we can replace them with '*' to play chess on our behalf. { board[x-1][y-1] = '*'; printf("%c",board[x-1][y-1]); break; } else //If the coordinates we entered are not '', it will mean that we don't want to use the robot. { printf("This coordinate is already occupied. Please re-enter the coordinate"); } } else//The abscissa and ordinate values entered are greater than or less than our limited coordinate values. { printf("Illegal coordinates"); } } }
The fourth function: computer_move() computer chess
This function requires rand and srand in < stdlib. H > of the library function. rand and srand are random number generators; There is also the time function in < time. H >, which is used for the timestamp in the srand function.
void computer_move(char board[ROW][COL],int row,int col){ int x = 0;//Computer chess coordinates, because it is computer chess, so do not use coordinates - 1. int y = 0; printf("Computer chess ") while(1){//Same as the above function x = rand()%row; //rand is a random number generator,% row can limit the range of random number generation, and the remainder row, that is, the remainder 3, so the range of random number generation is 0 ~ 2 y = rand()%col;//%Col can limit the generation range of random numbers. The remainder col, that is, the remainder 3, so the generation range of random numbers is 0 ~ 2 if (board[x][y] == ' '){ board[x][y] = '#'; //The coordinates of computer chess are '#' break; //If the computer plays chess successfully, it exits the loop } } printf("\n"); }
Fifth function: in_win() judge the winner or loser
This function is used to judge whether to win or lose. If the same characters are connected in a row, a column, or a diagonal, you win.
We can use the return value of this function to judge whether we win or lose in the main function, so the return value of this function is not void, but char
If the return value is' * ', the player wins.
The return value is' # '
The return value is' Q 'draw. In judging the draw, we also created a variable is_full()
The return value is' C 'to continue playing chess. The chessboard is not full and no one has won.
int is_full(char board[ROW][COL],int row,int col){ for(int i = 0; i < row; i++){ for(int j = 0; j < col; j++){ if(board[i][j] == ' '){ //Traverse the entire two-dimensional array. If there is' 'in the array, it returns 0, indicating that the chessboard is not full. return 0; } } } return 1;//If there is no ',' in the whole two-dimensional array, it returns 1, indicating that the chessboard is full. } char is_win(char board[ROW][COL] ,int row,int col){ for(int i = 0; i < row ; i++){ if(baord[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' '){ return board[i][1]; //If the characters in a line are the same, this character is returned } for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') { return board[1][j];//If the characters in a column are the same, this character is returned } } if(board[0][0] == board[1][1] && baord[1][1] == board[2][2] && board[2][2] != ' '){ return board[1][1]; //If the characters in the diagonal are the same, that character is returned } if(board[0][2] == board[1][1] && baord[1][1] == board[2][0] && board[2][0] != ' '){ return board[1][1];//If the characters in the diagonal are the same, that character is returned } if(is_full(board[ROW][COL],row,col) == 1){//Attention is_win is a function to determine whether the chessboard is full, but it does not need to be declared in the game.h header file. return 'Q'; //If is_ The value returned by win is 1, indicating that the chessboard has been occupied, which is a draw. } return 'C';//The return value is' C 'to continue playing chess. The chessboard is not full and no one has won. } }
The above is all my function parsing in game.c, but guys, don't forget to declare it in game.h, otherwise it won't be used in the main function file.
Although we only analyzed the functions in game.c, and the other two files are only briefly mentioned, when you can understand game.c, you can understand the other two files.
epilogue
So far, our sanziqi analysis has also come to an end. There may be some errors in the code. You are welcome to correct.
This program is not difficult, but it is basically the first program we wrote. This article mainly provides some humble opinions. It would be my great honor if I could give you a little help.
I look forward to meeting you next time. I wish you all success!!!