C language to achieve three word chess ~ step explanation and code

Posted by samsbox on Sun, 06 Feb 2022 19:20:56 +0100

What is Sanzi?

Sanzi chess is a very ancient folk traditional game, which is also very convenient to play. Sanzi chess is also called OOXX chess, Jingzi chess, etc. it is divided into 3 with the word "Jingzi" × In the grid of 3, both sides take turns to lay chess pieces (which can be distinguished by O or X). As long as their chess pieces are connected in a straight line, they will win.

Specific ideas for the realization of Sanzi chess

1. Create a game menu and let the player choose to start or end the game
2. Create a chessboard and initialize it
3. Print the initialized chessboard
4. Players fall

Specific steps of game implementation

πŸ‘ Menu interface

There are two options in the menu interface:
1. Play games
0. Exit the game

code implementation πŸ“

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

}

πŸ‘ Construction of main function

When we finish the game, we still want to continue playing, that is, we need to use the cycle (● - ●)

code implementation πŸ“

int main()
{
	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("Selection error\n");
			break;
		}
	} while (input);
	return 0;
}

πŸ‘ Implementation of Sanzi chess

We put the code in three files, test c,game.c,game.h
test.c ---- test the logic of the game
game.c ---- the realization of the game
game.h ---- function declaration and symbol definition

πŸ… Create chessboard

Chessboard: it is represented by a two-dimensional array with 3 rows and 3 columns. The element type is char.

void game()
{
	//Store chess data
	char board[ROW][COL]= {0};
}

πŸ… Initialize chessboard

The macro definition used here has the following advantages:
1. If you want to modify the size of the chessboard, it will be convenient to modify the code
2. Improve the readability of the code

In game The initialization function is declared in the H header file

#define ROW 3
#define COL 3

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

Then in game C function

void initBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

ps: the same is true for the functions created later, first in game H, and then to game Implementation in C function

πŸ… Print chessboard

1) Print according to the above code and the menu interface pops up again. It should be noted that the chessboard here is not printed, but we use "" to represent the blank, so what we see is a black. Next, we try to beautify it. Turn into the picture below ↓

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//print data
		int j = 0;
		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 drop

1. Of course, we know that in a two-dimensional array, the subscript of the array starts from 0, but as a small white player, they don't know the subscript of the array. So for players, rows and columns start with 1.
2. Judge whether the coordinates entered by the player are legal (i.e. whether they exceed the range of the chessboard)
3. Players should judge whether the coordinate is empty before falling.

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("Players play chess\n");
	while (1)
	{
		printf("Please enter coordinates");
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
		{
			//play chess
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = 'X';
				break;
			}
			else
			{
				printf("This coordinate is occupied, please re-enter\n");
			}
		}
		else
		{
			printf("The coordinates entered are illegal. Please re-enter\n");
		}
	}
	
}

πŸ… Computer drop

We choose to use timestamp to generate a random number, and control the range of random number within 0 ~ 3,
Generating random numbers has been discussed in detail in this blog. You can see here Generate random number ~ detailed analysis After reading, I have a deeper understanding of the following~

srand((unsigned)time(NULL));
void computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("Computer chess:>\n");
	while (1)
	{
		x = rand() % row;//0~2
		y = rand() % col;//0~2
		if (board[x][y] == ' ')
		{
			board[x][y] = 'O';
			break;
		}
	}

} 

πŸ… Judge whether to win or lose

When the player or computer plays each move of chess, we define a function is_win, judge who won;
Β·
When both sides win, there is no draw;
Β·
1. Player wins - > returns X
.
2. Computer win ---- > return O
.
3. Draw ----- > return Q
.
4. Continue ----- > return to C
So how do you win? Let's take an example

When three rows or three columns and two diagonals are filled with the same pieces, you win;

As shown in the figure, if the slash is filled with the same pieces, we can return the value of the red box in the middle

If the value is X, then the player wins;
If the value is O, then the computer wins;

int if_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++) 
		{
			if (board[i][j] == ' ')
				return 0;//Not full
		}
	}
	return 1;//Full
}



char is_win(char board[ROW][COL], int row, int col)
{
	int i =0;
	//Judgment line
	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];
		}
	}
	//Judgment 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];
		}
	}
	//Judge diagonal
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//Judge the draw
	if (if_full(board, row, col) == 1)
	{
		return'Q';
	}
	//The game continues
	return'C';
}

πŸ… The main function determines whether to win or lose

The idea of players playing chess with computers can be understood this way
When players play each move of chess, they will judge whether they win or lose;
When the computer plays every move of chess, it also judges whether to win or lose;
However, players and computers must play chess through circulation;
When ret is not equal to C, it jumps out of the loop;
After jumping out of the loop, the is_ The return value of win is compared

int ret = 0;
	//Store chess data
	char board[ROW][COL]= {0};
	//Initialize the chessboard to be full of spaces
	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')
		{
			break;
		}
		//Computer chess
		computer_move(board, ROW, COL);//Play chess at random
		DisplayBoard(board, ROW, COL);
		//Judge whether to win or lose
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == 'X')
	{
		printf("You won\n");
	}
	else if (ret == 'O')
	{
		printf("No, no, no one will lose to the computer\n");
	}
	else 
	{
		printf("It's a draw\n");
	}

🌟 summary

It may not be possible to watch it again, but it must be useful to play it by yourself. Let's fight the world together!

I'm Scott. I just know I don't know anything. See you next time!

Topics: C