C language to achieve a simple Gobang game

Posted by hijack on Sat, 05 Mar 2022 16:21:16 +0100

catalogue

Game ideas:

1. Print menu

2. Define chessboard ---- define a two-dimensional array

3. Initialize chessboard ------ initialize to space

4. Printing chessboard ----- first, you need to see the chessboard horn

5. Players play chess

6. Computer chess

7. Judge the end of the game

8. The main body of the total function of the game

 9. Complete code

test.c

 game.h

game.c

First, let's take a look at the effect:

First, we set up two c file and one h file

test.c --- used to test game logic

game.c --- used to realize game functions

game.h ---- contains various header files and macro definitions

game.h contains all the function declarations, header files, and rows and columns defined by define

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

//Declare initialization checkerboard function
void InitBoard(char board[ROW][COL], int row, int col);
//Declare initialization checkerboard function

void DisplayBoard(char board[ROW][COL], int row, int col);

// Declare player's chess function

void player_move(char board[ROW][COL], int row, int col);

//Declare computer chess

void computer_move(char board[ROW][COL], int row, int col);


//Win or lose function declaration
char is_win(char board[ROW][COL], int row, int col);

test.c and game C only needs to include game H this header file can contain everything it contains
Since it is a self-defined header file, use quotation marks "" instead of < >

#include"game.h"

Game ideas:

1. Print menu

/* Print menu function */
void menu()
{
	printf("*********************************\n");
	printf("******** 1.play   ***************\n");
	printf("******** 0.exit   ***************\n");
	printf("*********************************\n");
}
/* Main function part  */
int main()
{

	srand((unsigned)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("Please select:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//Call game function
			break;
		case 0:
			printf("Exit the game\n");
			break;
		default:
			printf("Input error,Please re-enter:");
			break;
		}

	} while (input);
	return 0;
}

For convenience, we use functions to realize specific game functions

2. Define chessboard ---- define a two-dimensional array

The definition of chessboard is implemented in the total game function

char board[ROW][COL] = { 0 };

3. Initialize chessboard ------ initialize to space

//Define initialization checkerboard function 

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] = ' ';//Initialize each coordinate position as a space
		}
	}
}

4. Printing chessboard ----- first, you need to see the chessboard horn

First, let's look at the structure of the chessboard

Here is the specific code -- pay attention to the details (what is not printed in the first few lines)

//Define print checkerboard function
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)//The chessboard layout is regarded as three lines 
	{
		int j = 0;
		for (j = 0; j < col; j++)//Internal control by column
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)//The third column does not print vertical lines
				printf("|");
				
		}
		printf("\n");//Print a line wrap
		//Print split line - the number of lines printed is - 1
		if (i < col - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

Here we can test whether the chessboard can be printed normally

5. Players play chess

It should be noted that:

1. When players enter a coordinate x and y, they must first judge the legitimacy of x and y

2. Considering that if the little white player doesn't know that the array coordinates start from 0, we specify that x and y start from 1

3. Then judge whether the X and Y coordinates are occupied. If not, enter "*" to indicate that the player is playing chess

4. Players should play chess in a cycle. If the coordinate input is inappropriate, they should lose again. If they play chess successfully, they will jump out of the cycle

code:

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	//x y must meet the range!
	while (1)
	{
		printf("Players play chess:\n");
		printf("Please enter coordinates\n");
		scanf("%d%d", &x, &y);//x and y should be in the loop, because you may need to re-enter the coordinates!
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//First judge whether there is chess in this position
			if (board[x-1][y-1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;//After playing chess, jump out of the loop
			}
			else
			{
				printf("This coordinate already has chess, please re-enter\n");
			}
		}
		else {
			printf("Illegal coordinates,Please re-enter\n");
		}
	}
}

6. Computer chess

1. First, the computer needs to generate a coordinate randomly when playing chess, which uses the random number rand()

2. Judge whether there are any randomly generated coordinates

//Define computer random chess
void computer_move(char board[ROW][COL], int row, int col)
{
	printf("Computer chess:\n");
	//Judge whether there is chess in this position
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	
}

7. Judge the end of the game

Every time a player or computer finishes playing chess, they have to judge whether they win or lose

Then there will be four situations:

1. Players win - we stipulate return *

2. Computer wins ---- we stipulate return#

3. Draw (i.e. the chessboard is full) --- we stipulate to return q

4. There is no end - we stipulate to return to c

So when do you win?

When three pieces of the same piece are connected, you win!  

This includes a diagonal line, a diagonal line, and a sub diagonal line

To determine whether the market is full, we use an is_full() function , this function is for is_ The win() function defines

You can modify it with static, and so on c file cannot use this function! (private!)

char is_win(char board[ROW][COL], int row, int col)
{
	//Check line 
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//Check column
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 1][j] == board[i + 2][j] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//Check the main diagonal
	for (int i = 0; i <= row-2; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i][i] != ' ')
		{
			return board[i][i];
		}
	}
	//Check the sub diagonal
	 // Start at the lower left corner
	for (int i = row - 1; i >= 2; i--)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//Check whether the disk is full
	if (is_full(board, row, col))
	{
		//If true - full
		return 'q';
	}
	return 'c';
}

Then we according to is_ The return value of win() function can judge who won!

8. The main body of the total function of the game

void game()
{
	char ret = 0;
	//Define chessboard
	char board[ROW][COL] = { 0 };
	//Initialize chessboard
	InitBoard(board, ROW, COL);
	//Print chessboard
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		// Players play chess
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//Judge whether to win or lose
		ret = is_win(board, ROW, COL);
		if (ret != 'c')//If the return value is c, it means to continue. If the return value is not c, it means that the game is over
		{
			break;
		}
		// Computer chess
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//Judge whether to win or lose
		ret = is_win(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
		// Judging whether ret is equal to c is to reduce code redundancy. If it has jumped out of the loop, it can be judged separately
	}

	if (ret == '*')
	{
		printf("Player wins\n");
	}
	else if (ret == '#')
	{
		printf("Computer win\n");
	}
	else 
	{
		printf("it ends in a draw\n");
	}
	//Print the board after the game
	DisplayBoard(board, ROW, COL); 
}
	//When does the game end
	// Player wins -- return*
	// Computer win - return#
	// Draw -- the chessboard is full -- return to q
	//    Not over -- return to c

 9. Complete code

test.c

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include"game.h"
void menu()
{
	printf("*********************************\n");
	printf("******** 1.play   ***************\n");
	printf("******** 0.exit   ***************\n");
	printf("*********************************\n");
}
void game()
{
	char ret = 0;
	//Define chessboard
	char board[ROW][COL] = { 0 };
	//Initialize chessboard
	InitBoard(board, ROW, COL);
	//Print chessboard
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		// Players play chess
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//Judge whether to win or lose
		ret = is_win(board, ROW, COL);
		if (ret != 'c')//If the return value is c, it means to continue. If the return value is not c, it means that the game is over
		{
			break;
		}
		// Computer chess
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//Judge whether to win or lose
		ret = is_win(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
		// Judging whether ret is equal to c is to reduce code redundancy. If it has jumped out of the loop, it can be judged separately
	}

	if (ret == '*')
	{
		printf("Player wins\n");
	}
	else if (ret == '#')
	{
		printf("Computer win\n");
	}
	else 
	{
		printf("it ends in a draw\n");
	}
	//Print the board after the game
	DisplayBoard(board, ROW, COL); 
}
	//When does the game end
	// Player wins -- return*
	// Computer win - return#
	// Draw -- the chessboard is full -- return to q
	//    Not over -- return to c


int main()
{

	srand((unsigned)time(NULL));
	int input = 0;
	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:");
			break;
		}

	} while (input);
	return 0;
}

 game.h

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

//Chessboard initialization function declaration
void InitBoard(char board[ROW][COL], int row, int col);
//Declare initialization checkerboard function

void DisplayBoard(char board[ROW][COL], int row, int col);

// Declare player's chess function

void player_move(char board[ROW][COL], int row, int col);

//Declare computer chess

void computer_move(char board[ROW][COL], int row, int col);


//Win or lose function declaration
char is_win(char board[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)

#include"game.h"

//Define initialization checkerboard function 

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

//Define print checkerboard function
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)//The chessboard layout is regarded as three lines 
	{
		int j = 0;
		for (j = 0; j < col; j++)//Internal control by column
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)//The third column does not print vertical lines
				printf("|");
				
		}
		printf("\n");//Print a line wrap
		//Print split line - the number of lines printed is - 1
		if (i < col - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}


//Define players to play chess
void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	//x y must meet the range!
	while (1)
	{
		printf("Players play chess:\n");
		printf("Please enter coordinates\n");
		scanf("%d%d", &x, &y);//x and y should be in the loop, because you may need to re-enter the coordinates!
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//First judge whether there is chess in this position
			if (board[x-1][y-1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;//After playing chess, jump out of the loop
			}
			else
			{
				printf("This coordinate already has chess, please re-enter\n");
			}
		}
		else {
			printf("Illegal coordinates,Please re-enter\n");
		}
	}
}


//Define computer random chess
void computer_move(char board[ROW][COL], int row, int col)
{
	printf("Computer chess:\n");
	//Judge whether there is chess in this position
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	
}

//Define the function to judge the full disk
static 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;
}

//Define win / lose function

char is_win(char board[ROW][COL], int row, int col)
{
	//Check line 
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//Check column
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 1][j] == board[i + 2][j] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//Check the main diagonal
	for (int i = 0; i <= row-2; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i][i] != ' ')
		{
			return board[i][i];
		}
	}
	//Check the sub diagonal
	 // Start at the lower left corner
	for (int i = row - 1; i >= 2; i--)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//Check whether the disk is full
	if (is_full(board, row, col))
	{
		//If true - full
		return 'q';
	}
	return 'c';
}

Topics: C Back-end