When we were young, we often wandered in class and played "tic tac toe chess" - also known as "Sanzi chess" with our deskmate. Do you want to relive the happiness of childhood on vs? Let's have a look!
catalogue
Today I want to finish a small program that is more challenging than before - Sanzi.
I believe most of us have been exposed to Sanzi chess. This is a simple and easy-to-use game.
First, briefly introduce the rules of Sanzi chess to facilitate our next programming and understanding. The rules are as follows:
On the nine palace chessboard, as long as you walk your three pieces into a line (horizontal, vertical and diagonal), the other party will lose.
The rules are very simple, but where should we start to complete this Gobang program?
First, our game program should have a menu page, which is used to let users choose to play the game or exit.
The interface can be very simple, requiring only a few printf statements.
Here we try our best to use functions to complete the functions of the game:
void menu() { printf("***************************************\n"); printf("* 1.play 0.exit *\n"); printf("***************************************\n"); }
This is a simple main menu interface. The effect is as follows:
Since there are options in the menu, we must design a variable to receive the user's selection.
Moreover, the game program itself should allow users to play repeatedly, so in the main function, we need to use a loop to complete this function.
The do while loop will run the loop body first and then make judgment when calling, so we choose to use the do while loop here:
int main() { int input; do { menu(); printf("Please select whether to(1/0)Start the game"); scanf("%d", &input); switch (choice) { case 1: game(); break; case 0: printf("Quit the game!\n"); break; default: printf("Input error, please re-enter!\n"); break; } } while (input); return 0; }
Since we need to start the game program for the user when the user selects option 1, we use a switch statement to accept the user's selection.
Select 0 to exit the program, so we just need to jump out of the loop to exit.
When entering values other than 0 and 1, we should report an input error to the user, so an error message is output in default.
The next step is the focus of our program - the Gobang game itself.
First, create a game() function that implements the Gobang, and we will fill in the contents step by step.
void game() { }
At the beginning of the program, we first create a 3 * 3 two-dimensional character array,
Since the length and width are often used, we adopt the macro definition method for the convenience of subsequent modification:
#define ROWS 3 #define COLS 3
Next, create an array in the game() function:
char board[ROWS][COLS];
And initialize the array. Because the array needs to be output and displayed in front of the user in the future, we initialize the value to space ''.
Initialization is completed with the function:
void init_board(char board[ROWS][COLS], int rows, int cols) { //Initialize checkerboard int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ' '; } } }
Next, we should output the array chessboard to check whether the initialization is completed,
However, we do not have a function to display the chessboard, so we need to complete this function to display the chessboard:
void show_board(char board[ROWS][COLS], int rows, int cols) { int i; for (int i = 0; i < rows; i++) { printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]); if (i != rows - 1) printf(" ---|---|--- \n"); } }//There are two methods for printing chessboard //This is a simple and crude method //I'll introduce another one later
Here, we need to use the loop to output the format of our chessboard. The format is not unified and can be modified according to our own preferences.
The chessboard output by my code is shown below:
It can be seen from the above that my chessboard initialization has been completed, so next we need to consider how to let the computer or users play chess.
The computer needs to let the computer generate random coordinates, and then put a '#' in this coordinate position of the array as the chess piece of the computer.
So the code is as follows:
void ComputerMove(char board[ROWS][COLS], int rows, int cols) { int x, y; printf("Computer walk:\n"); while (1) { x = rand() % rows; y = rand() % cols; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
rand() is used to generate random numbers. Here, we also need to add a line of code to the main function main;
Since we don't want him to generate random numbers many times, it's enough to generate them once, so we can directly add the following code on the next line of creating the choice variable:
srand((unsigned int)time(NULL));
Note that to generate random numbers, you need to reference the header file time.h.
After the computer plays chess, it's our user's turn to play chess. This function is similar to computer playing chess;
The chess played by the player is recorded with '*';
However, it should be noted that people's habits do not enter (0, 0) coordinates, but (1, 1);
So here we're going to pass the parameter - 1.
The code after solving this problem is as follows:
void player_move(char board[ROWS][COLS], int rows, int cols) { int x, y; printf("Player walk:\n"); while (1) { scanf("%d %d", &x, &y); if (x >= 1 && x <= rows && y >= 1 && y <= cols) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = 'O'; break; } else printf("The coordinates are occupied, please re-enter!\n"); } else printf(" Illegal coordinates, please re-enter!\n"); } }
After both sides go, we need to judge whether we win, that is, judge the rules we mentioned earlier,
At this time, we need to write an is_win() function to detect and return a value to determine who wins.
The code is as follows:
char is_win(char board[ROWS][COLS], int rows, int cols) { int i; for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') return board[i][1]; } for (i = 0; i < cols; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') return board[1][i]; } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') return board[1][1]; else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ') return board[1][1]; else if (is_full(board, rows, cols)) return 'q'; return 0; }
Since the chessboard may be full but no one wins,
So we need to judge the draw,
Here we write an is_ The full() function is used to judge whether the chessboard is full:
int is_full(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { if (board[i][j] == ' ') return 0; } } return 1; }
At this time, the rudiment of the program has been basically completed. We only need to complete the game() function according to the game steps we understand.
Therefore, the completed game() function is as follows:
void game() { char win = 0; char arr[ROWS][COLS]; init_board(board, ROWS, COLS); do { computer_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = is_win(board, ROWS, COLS); if (win != 0) break; player_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = is_win(board, ROWS, COLS); } while (win == 0); if (win == '#') printf("Congratulations, the computer won!\n"); if (win == '*') printf("Congratulations, you won!\n"); if (win == 'q') printf("it ends in a draw!\n"); }
In this way, the above parts are combined, and the program is completed by us.
Complete code
Here is the ugly code I wrote myself:
My code is divided into three parts,
The first part is the game.h header file:
#pragma once #include<stdio.h> #include<time.h> #include<Windows.h> #include<stdlib.h> #define ROWS 3 #define COLS 3 void show_board(char board[ROWS][COLS], int rows, int cols); void init_board(char board[ROWS][COLS], int rows, int cols); void computer_move(char board[ROWS][COLS], int rows, int cols); void player_move(char board[ROWS][COLS], int rows, int cols); char is_win(char board[ROWS][COLS], int rows, int cols);
In order to facilitate us to change the size of the chessboard at any time, we define the size of the chessboard row (ROWS) and column (COLS) in the game.h header file.
The second part is the function part of the game.c source file:
#include"game.h" //Method 1: void show_board(char board[ROWS][COLS], int rows, int cols) { int i; for (int i = 0; i < rows; i++) { printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]); if (i != rows - 1) printf(" ---|---|--- \n"); } } //Method 2 //void show_board(char board[ROWS][COLS], int rows, int cols) //{ // int i = 0; // int j = 0; // for (i = 0; i < rows; i++) // { // for (j = 0; j < cols; j++) // { // printf(" %c ", board[i][j]); // if (j < cols - 1) // printf("|"); // } // printf("\n"); // if (i < rows - 1) // { // for (j = 0; j < cols; j++) // { // printf("---"); // if (j < cols - 1) // printf("|"); // } // } // printf("\n"); // } //} void init_board(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ' '; } } } void computer_move(char board[ROWS][COLS], int rows, int cols) { int x, y, i; printf("Computer walk:\n"); while (1) { x = rand() % rows; y = rand() % cols; for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ') { board[i][2] = '#'; goto flag1; } else if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ') { board[i][0] = '#'; goto flag1; } else if (board[i][0] == board[i][2] && board[i][2] == '#' && board[i][1] == ' ') { board[i][1] = '#'; goto flag1; } else if (board[0][i] == board[1][i] && board[0][i] == '#' && board[2][i] == ' ') { board[2][i] = '#'; goto flag1; } else if (board[1][i] == board[2][i] && board[1][i] == '#' && board[0][i] == ' ') { board[0][i] = '#'; goto flag1; } else if (board[0][i] == board[2][i] && board[2][i] == '#' && board[1][i] == ' ') { board[1][i] = '#'; goto flag1; } else if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ') { board[2][2] = '#'; goto flag1; } else if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ') { board[0][0] = '#'; goto flag1; } else if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ') { board[1][1] = '#'; goto flag1; } else if (board[0][2] == board[1][1] && board[1][1] == '#' && board[2][0] == ' ') { board[2][0] = '#'; goto flag1; } else if (board[1][1] == board[2][0] && board[1][1] == '#' && board[0][2] == ' ') { board[0][2] = '#'; goto flag1; } else if (board[2][0] == board[0][2] && board[2][0] == 'X' && board[1][1] == ' ') { board[1][1] = '#'; goto flag1; } } for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][0] == 'O' && board[i][2] == ' ') { board[i][2] = '#'; goto flag1; } else if (board[i][1] == board[i][2] && board[i][1] == 'O' && board[i][0] == ' ') { board[i][0] = '#'; goto flag1; } else if (board[i][0] == board[i][2] && board[i][2] == 'O' && board[i][1] == ' ') { board[i][1] = '#'; goto flag1; } else if (board[0][i] == board[1][i] && board[0][i] == 'O' && board[2][i] == ' ') { board[2][i] = '#'; goto flag1; } else if (board[1][i] == board[2][i] && board[1][i] == 'O' && board[0][i] == ' ') { board[0][i] = '#'; goto flag1; } else if (board[0][i] == board[2][i] && board[2][i] == 'O' && board[1][i] == ' ') { board[1][i] = '#'; goto flag1; } else if (board[0][0] == board[1][1] && board[0][0] == 'O' && board[2][2] == ' ') { board[2][2] = '#'; goto flag1; } else if (board[1][1] == board[2][2] && board[1][1] == 'O' && board[0][0] == ' ') { board[0][0] = '#'; goto flag1; } else if (board[0][0] == board[2][2] && board[0][0] == 'O' && board[1][1] == ' ') { board[1][1] = '#'; goto flag1; } else if (board[0][2] == board[1][1] && board[1][1] == 'O' && board[2][0] == ' ') { board[2][0] = '#'; goto flag1; } else if (board[1][1] == board[2][0] && board[1][1] == 'O' && board[0][2] == ' ') { board[0][2] = '#'; goto flag1; } else if (board[2][0] == board[0][2] && board[2][0] == 'O' && board[1][1] == ' ') { board[1][1] = '#'; goto flag1; } } if (board[x][y] == ' ') { board[x][y] = '#'; goto flag1; } } flag1:; } void player_move(char board[ROWS][COLS], int rows, int cols) { int x, y; printf("Player walk:\n"); while (1) { scanf("%d %d", &x, &y); if (x >= 1 && x <= rows && y >= 1 && y <= cols) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = 'O'; break; } else printf("The coordinates are occupied, please re-enter:>\n"); } else printf(" Illegal coordinates, please re-enter:>\n"); } } int is_full(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { if (board[i][j] == ' ') return 0; } } return 1; } char is_win(char board[ROWS][COLS], int rows, int cols) { int i; for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') return board[i][1]; } for (i = 0; i < cols; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') return board[1][i]; } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') return board[1][1]; else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ') return board[1][1]; else if (is_full(board, rows, cols)) return 'q'; return 0; }
This part is developed to make the computer more intelligent, but I didn't think of a simplified way to write the code, so I had to complete it step by step with if statements.
The third part is the game test part of the test.c source file:
#include"game.h" void menu() { printf("***************************************\n"); printf("* 1.play 0.exit *\n"); printf("***************************************\n"); } void first_move() { printf("***************************************\n"); printf("* 1.computer first 2.player first *\n"); printf("***************************************\n"); } void game() { int input_1, win; char board[ROWS][COLS]; init_board(board, ROWS, COLS); first_move(); again: printf("Please choose who will go first:>"); scanf("%d", &input_1); switch (input_1)//Choose who goes first~ { case 1: do { computer_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = is_win(board, ROWS, COLS);//At each step, we need to judge whether we win or lose if (win != 0) break; player_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = is_win(board, ROWS, COLS);//At each step, we need to judge whether we win or lose } while (win == 0); if (win == '#') printf("Congratulations, the computer won!\n"); if (win == '*') printf("Congratulations, you won!\n"); if (win == 'q') printf("it ends in a draw!\n"); break; case 2: do { show_board(board, ROWS, COLS); player_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = is_win(board, ROWS, COLS); if (win != 0) break; computer_move(board, ROWS, COLS); win = is_win(board, ROWS, COLS); } while (win == 0); if (win == '*') printf("congratulations! The computer won!\n"); if (win == '#') printf("congratulations! You win!\n"); if (win == 'q') printf("it ends in a draw!\n"); break; default: printf(" Input error, please re-enter!\n"); goto again; } } int main() { int input; srand((unsigned int)time(NULL)); do { menu(); printf("Please select:"); 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; }