How to write a simple Gobang game (limited level, more stupid man-machine)

Keywords: C

catalogue

        1. Game logic

              1.1 game operation logic

              1.2 code implementation logic

                      1.2.1 code sub module

                        1.2.2 print menu for user selection

                        1.2.3 operating game functions

        2. Knowledge points used

                1. Two dimensional array

                 2. Nesting of loops

                 3. Generation of random numbers

                 4.#define defined symbols

                 5. Function definition and call

                 6. Selection and circulation

1.1 game operation logic

                 As like as two peas: the rules of operation are very simple, just like the rules of playing normally, it is exactly the same. As long as the three pieces on the chessboard are connected in a row, you will win, whether it is horizontal, numerical or diagonal. As long as they are connected in a row, you will win.

1.2 logic of code implementation

         1.2.1 code sub module

                 First of all, why divide the code into modules?

                        From the perspective of beginners, although this is a small game, the total amount of code exceeds 200 lines

                From an international point of view, writing in modules can not only make each function independent, but also reduce the amount of code of the main function, which is very important for beginners

                It is more organized and clear. It's a necessary skill for white programmers

                How to divide into modules?

                        First, create three files, a test source file, a game source file, and a game header file

                The source file of the test is specially used to store the code needed for the test (I can see the nonsense Literature), and the game

                To store the code to realize the game logic, and the game header file is used to put various header files and various functions

                Statement.

        1.2.2 print menu for users to choose (old dishes are single)

                

//This is the code of the test source file
#include <stdio.h>
void menu()
{
    printf("***********************\n");
    printf("**1.play*******0.exit**\n");
    printf("***********************\n")//Let the user enter a numeric selection

}
void test()
{
    int input=0;
    menu();//Call a menu function, and here is the printed menu
    scanf("%d",&input);
    do
    {
        switch(input)
        {
            case 1:
            {
                break;
            }
            case 2:
            {
                printf("Game exit\n");
            }
            default:
            {    
                printf("Please re-enter");
            }    
     }while(input);

  }
    

}
int main()
{
    test();//Only one test function is called in the main function, and the rest is completed by the test function
}

        1.2.3 operating game functions

Test file part of the game

        1. The essence of Sanzi chess is to operate a two-dimensional array and place chess pieces in different positions. In order to expand enough, we define two symbols (i.e. constants) to represent rows and columns

        So how to define constants?

                  It is defined in the header file of the game. Now we want to use row and Col. to include this header file

        2. Initialize all arrays to spaces so that we can store chess pieces in spaces later (first declared in the header file, and then defined in the source file of game).

        3. After the chessboard is printed, you can play chess. First, the player plays chess, and then the computer plays chess. After playing chess, you can print the chessboard once to see where the chess is

        4 judge the winner or loser

//This is the code of the test source file
#include "game.h" / / use "" when calling your own header file
void menu()
{
    printf("***********************\n");
    printf("**1.play*******0.exit**\n");
    printf("***********************\n");//Let the user enter a numeric selection

}

void game()
{

    char board[ROW][COL] = { 0 };//Operate on this two-dimensional array to place chess pieces
    InitBoard(board, ROW, COL);//Initialize this two-dimensional array. Step by step, see the game function below
    Display_Board(board, ROW, COL);//Reality or print out the chessboard
    char ret = is_win(board, ROW, COL);
    while (1)//Loop until the winner is judged and jump out
    {
        
        Player_move(board,ROW,COL);//Players play chess
        Display_Board(board,ROW,COL);
        ret = is_win(board, ROW, COL);
        if (ret != 'C')//This judgment condition is judged once after each printing of the chessboard until the condition is established
        {
            break;
        }

        Computer_move(board,ROW,COL);//Computer chess
        Display_Board(board,ROW,COL);
        ret = is_win(board, ROW, COL);
        if (ret != 'C')
        {
            break;
        }
    }
        if (ret == '*')
        {
            printf("Player wins\n");
        }
    if (ret == '#')
    {
        printf("Computer win\n");
    }
    if (ret == 'Q')
    {
        printf("it ends in a draw\n");
    }


}
void test()
{
    int input = 0;
   
    do
    {
        menu();//Call a menu function, and here is the printed menu
        scanf("%d", &input);
        switch (input)
        {
        case 1:
        {
            game();//Create a game function, let's start the game let's go
            break;
        }
        case 2:
        {
            printf("Game exit\n");
        }
        default:
        {
            printf("Please re-enter");
        }
        }
 

    }while (input);


}
int main()
{
    srand((unsigned int)time(NULL));
    test();//Only one test function is called in the main function, and the rest is completed by the test function
}

Game header file  

         We can put all header files in the header file we created, and finally call this header file directly and uniformly

//This is the header file of the Gobang game

#include <stdio.h>
#define ROW 3
#define COL 3
#include <stdlib.h>
#include <time.h>

void InitBoard(char board[ROW][COL],int row,int col);//Declare this function first, otherwise there will be a warning

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

Game source file

         Initial two-dimensional array

        Print chessboard

3. Print chessboard

         First of all, consider how an ordinary person will input the subscript when he sees the chessboard. When inputting, he will input according to the angle of an ordinary person. Then we will convert the input content into the subscript of a real two-dimensional array. In fact, the input value is different from the last executed value.

        For computers, there are not so many restrictions, just limit the range of random numbers to the range limited by the array subscript

        Random number: the rand() function needs to call the srand() function. The parameter of the srand() function is also an unsigned integer random number. Where does this random number come from? This requires the introduction of the concept of timestamp. Time stamp: it is the difference between the current time and the time of the first computer, which is realized by time. So srand ((unsigned int) time (NULL));

4. Judge the winner or loser

         Let's first look at how many situations there can be

                1 player wins   Return#

                2 computer wins   Return*

                3 draw       Return Q

                4 none of the above three is to continue to return to C

        When judging whether the row and column are empty, you can't directly fill in a certain array. You can only judge according to the characteristics of the loop

The same is true of return

//This is the source file of the game
#include "game.h"


//Initialize chessboard
void InitBoard(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++)
        {
            board[i][j] = ' ';//Each element is traversed and assigned a space for us to place the pieces
        }
    }
}


//Display (print) chessboard (see Figure 1 for effect)
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]);
            if (j < col - 1)
            {
                printf("|");//Because the split line cannot completely wrap the chess pieces, do not print the split line at the last time
            }
        }
        printf("\n");
            if (i < row - 1)
            {
                for (j = 0; j < col; j++)
                {
                    printf("---");
                    if (j < col - 1)
                    {
                        printf("|");
                    }
                }
                printf("\n");

            }
    }
}





//Player go
void Player_move(char board[ROW][COL], int row, int col)
{
    printf("Player walk:>");
    int i = 0;
    int j = 0;
    
    while (1)
    {
        scanf("%d%d", &i, &j);//scanf must be written in the loop, otherwise if it doesn't go, it will directly loop else
        if (i >= 1 && i <= row && j >= 1 && j <= col)//There is no concept of element small mark in the eyes of players, so let players input normally
        {
            if (board[i - 1][j - 1] == ' ')//We convert it into a language that the computer can understand. If it is empty, we can play chess
            {
                board[i - 1][j - 1] = '*';
                break;
            }
            else//If it is not empty, it means it has been occupied
                printf("This location is already occupied");
        }
        else
            printf("Coordinate input error, please re-enter");
    }

}

//Computer walk
void Computer_move(char board[ROW][COL], int row, int col)
{
    int x = 0;
    int y = 0;
    while (1)
    {
        x = rand() % row;//The random function needs to call the srand implementation (in the main function) header file < stdlib. H > (in the header file)
        y = rand() % col;//%col controls the range of random numbers in the range of 0 ~ 2

        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }
    }



}



//Judge whether to win or lose
int is_full(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++)
        {
            if (board[i][j] == ' ')
                return 0;
        }
    }
    return 1;
}

char is_win(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row;i++)
    {
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
        {
            return board[i][0];
        }
    }
    for (i = 0; i < col;i++)
    {
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
        {
            return board[0][i];
        }
    }
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
    {
        return board[1][1];
    }
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
    {
        return board[1][1];
    }
    int ret = is_full(board, row, col);
    if (ret == 0)
    {
        return 'C';
    }
    else
    {
        return 'Q';
    }
}

Posted by jib on Mon, 08 Nov 2021 19:50:59 -0800