Human tame artificial mental retardation (Sanzi)

Keywords: C Back-end

catalogue

preface

Three gobang rules

code implementation

Code analysis

 

preface

Daga, today is the whole point of Sanzi chess. This Gobang does not add AI algorithm. Computer chess is purely random chess (big guys bypass), so the real way to play is to find a way to let the computer win! (bushi, the code of this little game is written in C language, involving multidimensional arrays, functions and some piecemeal knowledge points. In order to increase readability and deepen the understanding of functions, the code is composed of three files.
1.text.c (game test)
2.game.c (game implementation, main code)
3.game.h   (function declaration, header file)
The total code is 200 + lines. This article is long and needs to have a certain understanding of functions and arrays.

 

Three gobang rules

Sanzi is a traditional folk game, which is also called Jiugong chess, circle fork, one dragon, Jingzi chess, etc. connect the square diagonal and put three pieces of both sides on the opposite sides in turn. As long as you walk your three pieces into a line, the other party will lose. However, there are many times when there is a situation of peace chess. - from Baidu Encyclopedia, CSGO is given to the bandits in the small town for nothing Chess!!


It can be compared with the understanding of the rules of Gobang

code implementation

test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()//Print menu
{
	printf("******************\n");
	printf("******1.game******\n");
	printf("******0.exit******\n");
	printf("******************\n");
}
void game()
{
	//Initialize all checkerboard elements to 0
	char board[ROW][COL] = { 0 };
	//Change each element of the chessboard into a space
	InitBoard(board, ROW, COL);
	//Print chessboard
	DisplayBoard(board, ROW, COL);
	char win = 0;
	while (1)
	{
		//Players start playing chess
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		 win = IsWin(board, ROW, COL);
		if (win != 'C')
			break;
		//The computer began to play chess
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		 win = IsWin(board, ROW, COL);
		if (win != 'C')
			break;
		//Judge the winner or loser, return to * player wins, # computer wins, 'C' continues and 'E' draws
		//char win = IsWin(board, ROW, COL);
	}
	if (win == '#')
		printf("Unfortunately, you haven't even been artificially retarded\n");
	else if (win == '*')
		printf("Congratulations, you have lifted the artificial mental retardation hammer\n");
	else
		printf("I'm sorry, you and the artificial mentally retarded are 50-50\n");
}
void test_game()//Test game panel
{
	int input = 0;
	srand((unsigned int)time(NULL));//random number
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("Exit the game\n");
			break;
		default:
			printf("Input error, please re-enter\n");
			break;
		}
	} while (input);
}
int main()
{
	test_game();
	return 0;
}

game.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

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] = ' ';
		}
	}
}
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		if (i < row)//Print delimited lines
		{
			for (j = 0; j < row; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("+");
			}
		}
		printf("\n");  //Line feed
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");//Print space between squares
		}
		printf("\n");//Line feed
	}
	for (j = 0; j < row; j++)
	{
		printf("---");
		if (j < col - 1)
			printf("+");
	}
	printf("\n");
}
void player_move(char board[ROW][COL], int row, int col)
{
	printf("Players play chess, please enter coordinates->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && y >= 1 && x <= row && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] ='*';
				break;
			}
			else
			{
				printf("This coordinate already has chess pieces, please redraw\n");
			}
		}
		else
		{
			printf("This coordinate does not exist, please try again\n");
		}
	}
}
void computer_move(char board[ROW][COL], int row, int col)
{
	printf("Computer chess->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//x belongs to 0 to 2
		y = rand() % col;//y belongs to 0 to 2
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '#';
				break;
			}
	}
}
char IsWin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 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 whether there is a draw. If the chessboard is full and there is no winner, there is a draw
	if (IsFull(board, ROW, COL))
	{
		return 'E';
	}
	else
		return 'C';
}
int IsFull(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;//There are spaces. The chessboard is not full. Continue
			}
		}
	}
	return 1;//If no space is found, return 1 and draw
}

game.h:

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

void InitBoard(char board[ROW][COL],int row,int col);
void DisplayBoard(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 IsWin(char board[ROW][COL], int row, int col);

Operation results:

 

 

Code analysis

Header files are just some reference header files, definitions of constants and function declarations, which will not be explained.

The following explains all the codes involved in the two source files according to the thinking order of the game implementation. Note that the following ROW is 3 and COL is 3

  For simplicity, the test_game function is called in the main function.

  Here, let's first look at the contents of the do while statement. The first thing we see in the game must be the game panel. Otherwise, how to choose, so print the panel first, that is, the menu function.

Ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha

 

Looking back, does the Switch correspond to the result of entering 1 or 0 or other numbers one by one? Here, we enter 1 to start the game

  Now we enter the game. The first thing is to generate a chessboard. Otherwise, we first define a two-dimensional array and initialize all elements to 0 (the array summary will be explained again later)

OK, now enter the function of initializing the chessboard, that is, turn each element into a space

This step is relatively simple. Two for loops nest and traverse the binary array, and assign each element a space  

Back to the game function

The next step is to print the chessboard. We need to print the chessboard. Otherwise, how can players see it? Enter this function

  Everyone here has their own style of beautification. I like it better

  There are two spaces in each small grid, and the elements of the corresponding row and column are sandwiched between the two spaces (because the elements here are also spaces, it is not easy to distinguish, so you can go to the above to see the code running results)

Back to the game function

  Well, the preparations are finished. It's time to start playing chess. Note that it needs to be put into the cycle until the winner or draw (the chessboard is full) , regardless of how the code function is implemented, we first analyze the underlying logic. After the player plays chess, we need to print the chessboard that appears on the screen to indicate where the player has played, and then judge whether the player has won. If the player has won, the computer does not need to play. If not, the computer continues to play. Similarly, we also need to judge whether the player has won, so as to cycle.

 

Let's look at the code of players playing chess

  Here, x and y are entered. x and Y belong to 1 to 3, so it is necessary to judge. Only when the entered x and Y meet the standards, can we play chess. However, we know that the subscript of the array starts from 0 (as will be explained in the summary of the array later) Therefore, the if inside the external if statement should be - 1. Here, it is also necessary to judge. If there is no chess in this place, that is, when the elements corresponding to x and y are spaces, the chess played by the player is marked as *. If there is chess, it needs to be played again.

Let's look at the logic of computer chess:

  It can be optimized here, but because I'm too delicious to write relevant AI algorithms, I can only randomly generate x and y. here, rand function (randomly generated number) is used, which needs to be combined with the definition of rand function

You can refer to the definition on MSDN for details  

After playing chess, of course, you should judge whether you win or lose, and then look at the function of judging whether you win or lose

  Judge whether the elements of each row, column and two diagonals are all * or # respectively. If so, return * or #. Another case is a draw, that is, the chessboard is full. Here's how to judge whether the chessboard is full

Just like here, traverse the two-dimensional array to see if you can find the space. If you can find it, it means that you haven't finished. Continue. If you finish, you can't find the space. It's a draw.  

Note here that if there is a draw, the IsFull function will return   1. Execute the if statement, return the character E, continue without a draw, IsFull returns 0, and execute the else statement, return the character C

The main thing is not to continue the cycle until there is a winner or a draw and jump out of the cycle

 

Then print the corresponding results respectively

So far, all the codes are complete

In fact, I found that as long as the idea is clear and step by step, the code is still very easy to understand and write. The focus is patience and debugging. If you win the blog, you will continue to clear the mine next time.

Posted by pagod on Tue, 09 Nov 2021 10:50:12 -0800