Gobang games (implemented in C language)

Sanzi is a very interesting game. The rule is that players play chess on a 3 * 3 chessboard. When one of the pieces occupies the same row or column or one of the two diagonal lines, the player will win the game. Next, we use C language to design such an interesting little game of man-machine interactive game.

First of all, before writing code, we need to know what effect we want, so that we can get to what action we need to complete. Firstly, we need a chessboard to play chess. Secondly, we need to design the ways and methods for players to play chess. Then we need to design the computer playing methods. We also need to observe the situation of the chessboard to determine the next step. Therefore, we also need to print the chessboard after each step. We also need to consider the four possible situations in the process of playing chess (player wins, computer wins, draws and continues) in short, the general framework of our game is as follows.

1. Initialize the checkerboard.

2. Print the display board.

3. Player_move.

4. Computer_move.

5. Judge the situation (Is_win).

Because Sanzi is a small project, we use game.h to store the library function header file and function description according to the standard engineering, and game.c to realize the core content of the game. test.c to test the game

The header file game.h is as follows

#pragma once / / prevent header files from being included repeatedly
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3 / / specify the number of lines (using macro definitions helps maintain and modify code)
#define COL 3 / / specify the number of columns
//Initialize chessboard
void InitBoard(char board[ROW][COL], int row, int col);
//Print chessboard
void DisplayBoard(char board[ROW][COL], int row, int col);
//Player walk
void Player_move(char board[ROW][COL], int row, int col);
//Computer runner
void Computer_move(char board[ROW][COL], int row, int col);
//Judge the outcome
char Is_win(char board[ROW][COL], int row, int col);

After customizing our own header file, we can use the include instruction to include it in other places where we need it, just like including the library header file.

We need a chessboard. Naturally, we think that we can initialize the chessboard with a two-dimensional array. The initial chessboard should have nothing,

So we choose to use space as the initial state of the chessboard.

//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] = ' ';//Here is the space
		}
	}
}

  Then we will start printing the chessboard. We hope to print the chessboard with the following effect (the painting is ugly, please forgive me)

  Then our printing is divided into two steps: the first step is to print data: space data space  

Step 2 print the code of the vertical line and split line printing part as follows:

//Print 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 space character space 
		for (j = 0; j < col; ++j)
		{
			printf(" %c ", board[i][j]);
			//Print|
			if (j < col - 1)
			{
				printf("|");
			}
		}
		//Change to another line after processing one line
		printf("\n");
		//Print split lines
		for (j = 0; j < col; ++j)
		{
			printf("---");
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
	}

}

Next, write the player's move. The mark of the player's chess piece is' * '. The player plays chess by entering the abscissa and ordinate. There are several cases.

1. The player accidentally enters illegal horizontal and vertical coordinates - prompt that the coordinates are illegal.

2. The coordinates have been occupied. - prompt occupied.

3. If the coordinates are legal and empty, you can drop them.

From the above considerations, playing chess is a repetitive action, so we should use a cycle. The player's chess code is as follows:

//Player walking -- player is next '*'
void Player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("Players go, please enter the coordinates : >");
		scanf("%d", &x);
		scanf("%d", &y);
		//Judge coordinate legality
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{  //Coordinates and methods, but may be occupied
			//The array subscript starts from 0 (the user may not know, but this design reflects the interaction with the user)
			if (' ' == board[x - 1][y - 1])
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("The coordinates are occupied, please re-enter\n");
			}
		}
		else
		{
			printf("Illegal coordinates\n");
		}
	}
}

After designing the player's game, the computer will play chess. The specific principle is roughly the same as that of the player's game. The code is as follows:

//Computer walkers, using random numbers to generate coordinates, do not consider cross-border problems and legitimacy problems
//Similar to the design of player walking
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;
		}
	}
}

Then we discuss the judgment of the above four cases.

//Judge the outcome
/*
There are four situations in the game. 1. The player wins and returns' * '
               2.Computer wins return '#'
			   3.Draw return 'Q'
			   4. Continue to return to 'C'
Among them, 3 and 4 determine by judging whether the chessboard is full, and write a function to judge whether the chessboard is full
 If it is full, it returns 1, and if it is not full, it returns 0
*/
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;
			}
		}
	}
  //That means it's full
	return 1;
}
char Is_win(char board[ROW][COL], int row, int col)
{  //These cases are the same and are not spaces. Return one of the elements
	//Peer 00 01 02 find three lines
	int i = 0;
	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];
		}
	}
	//Same column 00 10 20 find three columns
	for (i = 0; i < row; ++i)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//Main diagonal
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//Sub diagonal  
	if (board[2][0] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//The implementation here will return to the situation of draw and continuation
	if (1 == Is_full(board, ROW, COL))
	{
		return 'Q';
	}
	else
	{
		return 'C';
	}
}

Next is the test part

Note: the left side of the constant is written to prevent the logical error caused by writing one less = for the = = sign (convert the logical error into a syntax error)

The complete code is as follows:

game.h

#pragma once
#include<stdio.h>
#include<stdlib.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);
//Player walk
void Player_move(char board[ROW][COL], int row, int col);
//Computer runner
void Computer_move(char board[ROW][COL], int row, int col);
//Judge the outcome
char Is_win(char board[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#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] = ' ';
		}
	}
}
//Print 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 space character space 
		for (j = 0; j < col; ++j)
		{
			printf(" %c ", board[i][j]);
			//Print|
			if (j < col - 1)
			{
				printf("|");
			}
		}
		//After processing one line, change another line
		printf("\n");
		//Print split lines
		for (j = 0; j < col; ++j)
		{
			printf("---");
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
	}

}
//Player walking -- player is next '*'
void Player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("Players go, please enter the coordinates : >");
		scanf("%d", &x);
		scanf("%d", &y);
		//Judge coordinate legality
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{  //Coordinates and methods, but may be occupied
			//Array subscripts start at 0
			if (' ' == board[x - 1][y - 1])
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("The coordinates are occupied, please re-enter\n");
			}
		}
		else
		{
			printf("Illegal coordinates\n");
		}
	}
}
//Computer walkers, using random numbers to generate coordinates, do not consider cross-border problems and legitimacy problems
//Similar to the design of player walking
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;
		}
	}
}
//Judge the outcome
/*
There are four situations in the game. 1. The player wins and returns' * '
               2.Computer wins return '#'
			   3.Draw return 'Q'
			   4. Continue to return to 'C'
Among them, 3 and 4 determine by judging whether the chessboard is full, and write a function to judge whether the chessboard is full
 If it is full, it returns 1, and if it is not full, it returns 0
*/
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;
			}
		}
	}
  //That means it's full
	return 1;
}
char Is_win(char board[ROW][COL], int row, int col)
{  //These cases are the same and are not spaces. Return one of the elements
	//Peer 00 01 02 find three lines
	int i = 0;
	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];
		}
	}
	//Same column 00 10 20 find three columns
	for (i = 0; i < row; ++i)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//Main diagonal
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//Sub diagonal  
	if (board[2][0] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//The implementation here will return to the situation of draw and continuation
	if (1 == Is_full(board, ROW, COL))
	{
		return 'Q';
	}
	else
	{
		return 'C';
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game()
{
	char board[ROW][COL] = { 0 };
	char ret = 0;
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		Player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//Judge whether the chessboard is full
		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;
		}
	}
//The execution here is to judge whether the player wins, the computer wins or the draw
	if ('*' == ret)
	{
		printf("The young man is very good, not bad\n");
	}
	else if ('#' == ret)
	{
		printf("I can't even beat the entry level. It's a real dish\n");
	}
	else
	{
		printf("it ends in a draw\n");
	}
}
void menu()
{
	printf("**********************\n");
	printf("****   1. play  *******\n");
	printf("****   0. exit  *******\n");
	printf("***********************\n");
}
void test()
{   
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("Please select: >\n");
		scanf("%d", &input);
		switch (input)
		{   
		case 1: 
			game();
			break;
		case 0:
			printf("Exit the game\n");
			break;
		default:
			printf("Selection error!\n");
			break;
		}

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

If there are mistakes, I hope you can correct them. I hope my blog can help you learn and make progress together

Tags: C Back-end

Posted on Tue, 09 Nov 2021 18:40:31 -0500 by Skipjackrick