Implementation of Sanzi chess -- Application of two-dimensional array

Keywords: C Back-end

Through the application of array, function and loop knowledge, we can independently create a project - Sanzi chess. First of all, we should have a general idea and logic for the implementation of Sanzi chess.

File creation

If you want to do a good job, you must first sharpen your tools. In order to better complete the project, first create three files -- two source files and one header file. Test file - test.c, game file game.c, game header file game.h. The game file mainly stores the code related to the implementation of the game process, such as initialization function, printing chessboard function, etc; The test file mainly stores the main function and some auxiliary functions; The game header file is the function declaration in the game file. The header file is introduced by the test file.

First write the main function in test.c:

int main()
{
	test();
	return 0;
}
//Write the test as a function and process it in blocks to make the logic clearer

Write the test function again. When the program runs to the test function, it has entered the initial interface of the game.

#include<stdio.h>


void menu()
{
	printf("---------------------\n");
	printf("------1.play---------\n");
	printf("------0.exit---------\n");
	printf("---------------------\n");
}


void test()
{
    int input = 0;//The variables used should be introduced in front of the function, not in the compound statement,
                  //In this way, its scope is small. If you want to use this variable outside the compound statement, you can't use it.
    do
    {
        menu();
        printf("Please select:");
        scanf("%d",&input);
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:                              //Because the game is often not played enough at one time, the loop structure is selected
            printf("Leave the game\n");
            break;
        default:
            printf("Input error, please re-enter");
            break;
        }
    }while(input); 
}


int main()
{
	test();
	return 0;
}

General idea

1. The chess pieces under are also data. Where should the data be stored?

2. First initialize the chessboard and print it to see what the initial chessboard is like.

3. The game starts, the player takes the next step, and the computer takes the next step. It should be clear that this is a conditional cyclic process.

4. What is the basis for judging whether to win or lose?

Write down the idea in the function of game()

void game()
{
    char board[3][3] = {0};//Initializes an array to hold data
    //Initialize the chessboard;
    //Print chessboard;
    //The game begins: players go, computers go. Cycle process.
    //Judge whether you win or lose.
}

In order to make the program more transformative, macros are defined in game.h. Then use the string to represent the number. Later, it needs to be changed into Gobang, cross, etc. just change 3 to 5,10 in the header file.

#define ROW 3
#define COL 3
void game()
{
    char board[3][3] = {0};//Initializes an array to hold data
    //Initialize the chessboard;
    //Print chessboard;
    //The game begins: players go, computers go. Cycle process.
    //Judge whether you win or lose.
}

1. Data storage

Three Gobang -- three lines and three columns. Such data must be stored in a set of two-dimensional arrays. And is an array of character types.

2. Initialize the chessboard and print the chessboard

Initialize the chessboard. When no chess is played, each chess point should be a space. Write an array initialization function under the game file

//Write in game.c
//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] = ' ';
		}
	}
}

  Print the chessboard. To print the chessboard, you need to know what the chessboard looks like,

That's about it. According to the gourd painting ladle, the code was born:

void Displayboard(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for(i = 0; i < row; i++)
    {
        //print data
        printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2] );
        //Print split lines
        if(i < col -1)
            printf("___|___|___\n");
    }
}

But this code has obvious limitations, that is, it can only print three columns. For example, if a Gobang or cross comes one day, you have to modify this code again, and the modified code is long. Now optimize the following code:

void Displayboard(char board[ROW][COL], int row, int col)
{
    int i = 0;
    int j = 0;
    for(i = 0; i < row; i++)
    {
        //print data
        for(j = 0; j < col; j++)
        {
            printf(" %c ", board[i][j]);
            if ( j < col - 1)
                printf("|"); 
        }
        //Line feed
        printf("\n");
        //Print split lines
        if( i < row - 1)
        {
            for( j = 0; j < col; j++)
            {
                printf("___");
                if( j < col - 1)
                    printf("|");
            }
        }
        //Line feed
        printf("\n");
    }
}

The initialization function and printing function of such a chessboard are completed.

3. The game begins

The process of the game is nothing more than players playing chess and computers playing chess. Just write two functions, one is the player's chess function, the other is the computer's chess function, or write it in the game.c file.

void Player_move(char board[ROW][COL], int row, int col)
{
    printf("Players play chess>");
    int x = 0;
    int y = 0;
    scanf("%d %d",&x,&y);
    while (1)
    {
        if( x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if( board[x - 1][y - 1] ==' ')
            {
                board [x - 1][y - 1] = '*';//Players play chess with '*'
                break;
            }
            else
            {
                printf("This coordinate is occupied. Please select again\n");
            }
        } 
        else
        {
            printf("Input error, please re-enter\n");
        }
    }
}
void Computer_move(char board[ROW][COL], int row, int col)
{
    int x = rand() % 3;//Randomly generated numbers, take the remainder of 3, always 0 ~ 2
    int y = rand() % 3;
    while (1)
    {
        if( board[x][y] ==' ')
        {
            board[x][y] = '#';//Computer chess' # '
            break;
        }
    }
}

None of this code seems to be wrong. But I can't run! Because the computer chess function, randomly generated x, y into the function is fixed! If it doesn't meet the conditions, it will cycle all the time! Can't jump out. So the randomly generated number should be inside the loop.

void Computer_move(char board[ROW][COL], int row, int col)
{
    while (1)
    {
        int x = rand() % 3;//Randomly generated numbers, take the remainder of 3, always 0 ~ 2
        int y = rand() % 3;
        if( board[x][y] ==' ')
        {
            board[x][y] = '#';//Computer chess' # '
            break;
        }
    }
}

4. Judge the winner or loser

Finally, write a function to judge whether you win or lose. Return '*' if the player wins, return '#' if the computer wins, return 'p' if the draw, and return 'c' if the game continues.

int is_full(char board[ROW][COL]´╝îint row, int col)
{
    int n = 0;
    int m = 0;
    for ( n = 0; n < row; n++)
    {
        for ( m = 0; m < col;  m++)
        {
            if ( board[n][m] == ' ')
            {
                return 0;
            }
        }
    }
    return 1;
}

char is_win( char board[ROW][COL],int row, int col)
{
    int i = 0;
    //Judge whether the line has 3 identical pieces
    for (i = 0; i < row; i++)
    {
        if( board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] !=' ')
        {
            return board[i][1];
        }
    }
    //Judge whether the column is three identical pieces
    for (i = 0; i < col; i++)
    {
        if( board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] !=' ')
        {
            return board[1][i];
        }
    }
    //Judge whether there are three identical pieces on the diagonal
    for(i = 0; i < col; i++)
    {
        if( board[0][0] == board[1][1] && board[1][1] ==board[2][2] && board[1][1] != ' ')
            return board[1][1];
        if( board[2][0] == board[1][1] && board[1][1] ==board[0][2] && board[1][1] != ' ')
            return board[1][1];
    //Judge whether there is a draw
    if (1 == is_full())
        return 'p';
    return 'c';
    
}

The winning or losing function is done.

5. Improve game functions

All the functions to be used have been written, and it's time to assemble them. It is mainly added to the game () function under test.c. Before that, you should declare all the functions used in game.h, and then import the test.c file into the game.h header file, so that the functions in the game can be called normally.

//All codes under game.h

#include<stdio.h>
#include<time.h>

#define ROW 3
#define COL 3

//Initialize chessboard
void Initboard(char board[ROW][COL], int row, int col);

//Print chessboard
void Displayboard(char board[ROW][COL], int row, int col);

//Players play chess
void Player_move(char board[ROW][COL], int row, int col);

//Computer chess
void Computer_move(char board[ROW][COL], int row, int col);

//Judge whether to win
char is_win(char board[ROW][COL], int row, int col);
void game()
{
    char board[3][3] = {0};//Initializes an array to hold data
    //Initialize chessboard
    Initboard(board,ROW,COL);
    //Print chessboard
    Displayboard(board,ROW,COL);

    //The game begins
    while(1)
    {
    //Player go
    Player_move(board,ROW,COL);
    Displayboard(board,ROW,COL);
    if ( is_win(board,ROW,COL) != 'c')
        break;

    //Computer walk
    Computer_move(board,ROW,COL);
    Displayboard(board,ROW,COL);
    if ( is_win(board,ROW,COL) != 'c')
        break;
    }
    //Judge whether to win or lose
    if ( is_win(board) == '*' )
        printf("Player wins");
    if ( is_win(board) == '#' )
        printf("Computer wins");
    if ( is_win(board) == 'p' )
        printf("it ends in a draw");
}

The game () function has been perfected!

6. Complete code

//All codes under game.h

#include<stdio.h>
#include<time.h>

#define ROW 3
#define COL 3

//Initialize chessboard
void Initboard(char board[ROW][COL], int row, int col);

//Print chessboard
void Displayboard(char board[ROW][COL], int row, int col);

//Players play chess
void Player_move(char board[ROW][COL], int row, int col);

//Computer chess
void Computer_move(char board[ROW][COL], int row, int col);

//Judge whether to win
char is_win(char board[ROW][COL], int row, int col);
//All codes under test.c


#include"game.h"

void game()
{
	char ret;
	//The data is stored in a two-dimensional array of one character. Players are '*' and computers are '*'#‘
	char board[ROW][COL] = { 0 };  //Initial should all be spaces
	Initboard(board,ROW,COL);	//Initialize chessboard
	Displayboard(board, ROW, COL);  //Print chessboard
	while (1)
	{
		Player_move(board,ROW,COL);		
		Displayboard(board, ROW, COL);  //Print chessboard
		ret = is_win(board, ROW, COL);
		if (ret != 'c')
			break;
		Computer_move(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'c')
			break;
	}
	if (ret == '*')
	{
		printf("Player wins\n");
	}
	if (ret == '#')
	{
		printf("Computer wins\n");
	}
	if (ret == 'p')
	{
		printf("it ends in a draw\n");
	}
}


void menu()
{
	printf("---------------------\n");
	printf("------1.play---------\n");
	printf("------0.exit---------\n");
	printf("---------------------\n");
}


void test()
{
	srand((unsigned)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("Please select:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("Leave the game");
			break;
		default:
			printf("Input error, please re-enter");
			break;
		}
	} while(input);
}


int main()
{
	test();
	return 0;
}
	
//All codes under game.c

#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] = ' ';
		}
	}
}

//Display chessboard
void Displayboard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		//print data
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//Print split lines
		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("Players play chess>");
	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("This coordinate is occupied, please re-enter\n");
		}
		else
		{
			printf("Out of range! Please re-enter\n");
		}
	}
}

//Computer walk
void Computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("Computer walk>\n");
	while (1)
	{
		x = rand() % ROW;
		y = rand() % COL;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

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


//The player returns' * ', the computer returns' #', the draw returns' p ', and continue to return to' c '
char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//that 's ok
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
			return board[i][1];
	}
	//column
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
			return board[1][i];
	}
	//diagonal
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
		return board[1][1];
	//it ends in a draw
	if (1 == is_full(board, ROW, COL))
		return 'p';
	//continue
	return 'c';

}

Run it to see the effect:

  Basically, it can realize the function of Sanzi chess, but there are still deficiencies. Can we give computers intelligence? That is to let the computer have its own ideas and can pk with us, rather than simply randomly generate numbers to play chess. We still need to think about this, so we won't explain it too much here.

Posted by grantson on Wed, 10 Nov 2021 13:35:33 -0800