C + + programming practice - Gobang game (continuously updated)

Posted by skypilot on Thu, 23 Dec 2021 18:27:33 +0100

Basic rules

(1) Both sides of the game hold the same chess pieces.
(2) An empty chessboard opens.
(3) Black first, white later, alternating, only one at a time.
(4) The chess piece is placed on the blank point of the chessboard. After the chess piece is set, it shall not move to other points, or take it off the chessboard or pick it up and fall elsewhere.
(5) The first piece of the black side can be placed at any intersection of the chessboard.
(6) It is the right of both parties to take turns, but either party is allowed to waive the sub right (i.e. PASS right)
//For Gobang matches, the black side shall specify the opening, three hands can be exchanged, and five hands can be played two times. In the whole game, the black side has a ban and the white side has no ban.
//There are three kinds of black ban hands, four kinds of ban hands and long company ban hands.

a key

  1. First make a chessboard and decide to use a string array.
  2. A function for drop
  3. A function that displays the current status of the chessboard
  4. A function to judge whether to win or lose
  5. A structure that can be repeated. We intend to use while here. Later, it will be changed to do while due to the need to judge whether to win or lose

Basic preparation

#include<iostream>
#include<stdlib.h>
using namespace std;
#Define x 15 / / chessboard size
string qizi_1 = "X";//Black Square
string qizi_2 = "O";//Bai Fang
string qipan[X*2+4][X*2+4];
int i = 0;//Cyclic variable
int j = 0;//Cyclic variable

checkerboard

void xian_shi_qi_pan()//Display chessboard
{
	for (j = 1; j <= X*2+2; j++)
	{
		for (i = 1; i <= X*2+2; i++)
		{
			cout << qipan[i][j];
		}
		cout << endl;
	}
}
void fang_ge_qi_pang()//Put a chessboard
{
	for (j = 1; j <= X * 2 + 2; j++)
	{
		for (i = 1; i <= X * 2 + 2; i++)
		{
			qipan[i][j] = "  ";
		}
	}
	for (j = 1; j <= X * 2 + 2; j++)//Chessboard initialization
	{
		for (i = 1; i <= X * 2 + 2; i++)
		{
			if (j % 2 == 1&&j<=X*2+2&&i<=X*2) qipan[i][j] = "—";
			if (i % 2 == 1 && j % 2 == 0&&i<=X*2+2&&j<=X*2+1) qipan[i][j] = "| ";
			
		}
	}
	xian_shi_qi_pan();
}

Here, the chessboard should not have only pieces, but should have a grid. I used "|" and "-" to simulate with Excel. It should be like this:
![(https://img-blog.csdnimg.cn/9ca24d27062845bcbf1f617dc10a0e33.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA56CB5Luj56CB5L2_5oiR5b-r5LmQ,size_20,color_FFFFFF,t_70,g_se,x_16)


For the upper grid, light blue should be "-" and dark blue should be "|", and the gray grid should be two spaces at first. At the same time, there is no seal on the right and lower sides of the figure. When writing a function, you should pay attention to adding an if statement.

Final effect in black box:

Luozi

void fang_ge_qi_zi(int x0,int y0,string& qizi)//Place chess pieces
{
	if (x0 == 0 && y0 == 0) return;//Enter 0 according to the prompt, that is, this round of waiver, no drop
	qipan[x0][y0] = qizi + " ";
}

Because there are two spaces in the grid, only the pieces appear to be biased to one side, so I fine tuned the previous empty chessboard, changed "|" to "|", and then added a space behind the pieces to ensure that the pieces are in the middle of the grid.
The effect is shown in the figure:

Judge whether to win or lose

bool pan_duan_shu_yin(string& qizi)//Enter a chess piece to judge whether the chess piece holder has won
{
	for (i = 2; i <= X * 2; i += 2)
	{
		for (j = 2; j <= X * 2; j += 2)
		{
			if (qipan[i][j] == qipan[i + 2][j] &&
				qipan[i][j] == qipan[i + 4][j] &&
				qipan[i][j] == qipan[i + 6][j] &&
				qipan[i][j] == qipan[i + 8][j] &&
				qipan[i][j] == qizi+" ")
				return true;
			if (qipan[i][j] == qipan[i + 2][j] &&
				qipan[i][j] == qipan[i + 4][j] &&
				qipan[i][j] == qipan[i + 6][j] &&
				qipan[i][j] == qipan[i + 8][j] &&
				qipan[i][j] == qizi + " ")
				return true;
			if (qipan[i][j] == qipan[i + 2][j+2] &&
				qipan[i][j] == qipan[i + 4][j+4] &&
				qipan[i][j] == qipan[i + 6][j+6] &&
				qipan[i][j] == qipan[i + 8][j+8] &&
				qipan[i][j] == qizi + " ")
				return true;
		}
	}
	return false;
}

I haven't come up with a better way for the time being. If you want to traverse the array in this way, it will be slow if the chessboard is large. Now it's 15 * 15. Don't worry for the time being. This method should also be further streamlined. For example, if the grid is empty, skip it directly.

Judge whether the drop is effective

bool shi_fou_you_xiao(int x, int y)//Check whether the drop is effective, whether there is overlap and whether it falls outside the chessboard
{
	if (qipan[x][y] != "  "&& !(x==0&&y==0))//To exclude 0 waivers
	{
		cout << "Your fall is invalid" << endl;
		return false;
	}
	if (x > X * 2+1 || x < 0 || y>X * 2+1 || y < 0)
	{
		cout << "Your fall is outside the chessboard" << endl;
		return false;
	}
	return true;
}

Main function

int main()
{
	int change = 1;
	while (change)
	{
		cout << "****************************************************************" << endl;
		cout << "**************Please select a game****************************************" << endl;
		cout << "**************0.sign out********************************************" << endl;
		cout << "**************1.computer vs game player**************************************" << endl;
		cout << "**************2.game player vs game player**************************************" << endl;
		cin >> change;
		switch (change)
		{
			case 1:break;
			case 2:
			{
				int x1, x2, y1, y2;
				fang_ge_qi_pang();
				cout << "The game begins!" << endl;
				do
				{
					cout << "Please player 1(Sunspot square)Enter chess coordinates:(If you enter 0, there will be no drop for this round of waiver)" << endl;
					cin >> x1 >> y1;//This coordinate is row x1 and column y1, so the subscript of the corresponding two-dimensional array below should be reversed
					while (!shi_fou_you_xiao(y1 * 2, x1 * 2))//Judge whether the drop is effective
					{
						cout << "Please re-enter the coordinates:" << endl;
						cin >> x1 >> y1;
					}
					system("cls");
					fang_ge_qi_zi(y1 * 2, x1 * 2, qizi_1);
					xian_shi_qi_pan();
					if (pan_duan_shu_yin(qizi_1))
					{
						cout << "The game is over. The black side wins" << endl;
						break;//Judge after the next. If the outcome is decided, you don't need to continue
					}
					cout << "Please player 2(Bai Zifang)Enter chess coordinates:(If you enter 0, there will be no drop for this round of waiver)" << endl;
					cin >> x2 >> y2;//This coordinate is row x2 and column y2, so the subscript of the corresponding two-dimensional array below should be reversed
					while (!shi_fou_you_xiao(y2 * 2, x2 * 2))
					{
						cout << "Please re-enter the coordinates:" << endl;
						cin >> x2 >> y2;
					}
					system("cls");
					fang_ge_qi_zi(y2 * 2, x2 * 2, qizi_2);
					xian_shi_qi_pan();
					if (pan_duan_shu_yin(qizi_2))
					{
						cout << "The game is over, Bai Fangsheng" << endl;
						break;//Judge after the next. If the outcome is decided, you don't need to continue
					}
				} while ((!pan_duan_shu_yin(qizi_1) == 1 || !pan_duan_shu_yin(qizi_2)));
			}
			case 0: break;
		}
	}
	
	system("pause");
	return 0;
}

There are only players vs players here. I haven't figured out how to use the computer yet

The first version only has players vs players, with clear screen and black box

All codes are as follows:

//(1) Both sides of the game hold the same chess pieces.
//(2) An empty chessboard opens.
//(3) Black first, white later, alternating, only one at a time.
//(4) The chess piece is placed on the blank point of the chessboard. After the chess piece is set, it shall not move to other points, or take it off the chessboard or pick it up and fall elsewhere.
//(5) The first piece of the black side can be placed at any intersection of the chessboard.
//(6) It is the right of both parties to take turns, but either party is allowed to waive the sub right (i.e. PASS right)
//For Gobang matches, the black side shall specify the opening, three hands can be exchanged, and five hands can be played two times. In the whole game, the black side has a ban and the white side has no ban.
//There are three kinds of black ban hands, four kinds of ban hands and long company ban hands.
#include<iostream>
#include<stdlib.h>
using namespace std;
#define X  16
string qizi_1 = "X";//Black Square
string qizi_2 = "O";//Bai Fang
string qipan[X*2+4][X*2+4];
int i = 0;
int j = 0;
void xian_shi_qi_pan()
{
	for (j = 1; j <= X*2+2; j++)
	{
		for (i = 1; i <= X*2+2; i++)
		{
			cout << qipan[i][j];
		}
		cout << endl;
	}
}
void fang_ge_qi_pang()//Put a chessboard
{
	for (j = 1; j <= X * 2 + 2; j++)
	{
		for (i = 1; i <= X * 2 + 2; i++)
		{
			qipan[i][j] = "  ";
		}
	}
	for (j = 1; j <= X * 2 + 2; j++)//Chessboard initialization
	{
		for (i = 1; i <= X * 2 + 2; i++)
		{
			if (j % 2 == 1&&j<=X*2+2&&i<=X*2) qipan[i][j] = "—";
			if (i % 2 == 1 && j % 2 == 0&&i<=X*2+2&&j<=X*2+1) qipan[i][j] = "| ";
			
		}
	}
	xian_shi_qi_pan();
}
void fang_ge_qi_zi(int x0,int y0,string& qizi)//Place chess pieces
{
	if (x0 == 0 && y0 == 0) return;//Enter 0 according to the prompt, that is, this round of waiver, no drop
	qipan[x0][y0] = qizi + " ";
}
bool pan_duan_shu_yin(string& qizi)//Enter a chess piece to judge whether the chess piece holder has won
{
	for (i = 2; i <= X * 2; i += 2)
	{
		for (j = 2; j <= X * 2; j += 2)
		{
			if (qipan[i][j] == qipan[i + 2][j] &&
				qipan[i][j] == qipan[i + 4][j] &&
				qipan[i][j] == qipan[i + 6][j] &&
				qipan[i][j] == qipan[i + 8][j] &&
				qipan[i][j] == qizi+" ")
				return true;
			if (qipan[i][j] == qipan[i + 2][j] &&
				qipan[i][j] == qipan[i + 4][j] &&
				qipan[i][j] == qipan[i + 6][j] &&
				qipan[i][j] == qipan[i + 8][j] &&
				qipan[i][j] == qizi + " ")
				return true;
			if (qipan[i][j] == qipan[i + 2][j+2] &&
				qipan[i][j] == qipan[i + 4][j+4] &&
				qipan[i][j] == qipan[i + 6][j+6] &&
				qipan[i][j] == qipan[i + 8][j+8] &&
				qipan[i][j] == qizi + " ")
				return true;
		}
	}
	return false;
}
bool shi_fou_you_xiao(int x, int y)//Check whether the drop is effective, whether there is overlap and whether it falls outside the chessboard
{
	if (qipan[x][y] != "  "&& !(x==0&&y==0))
	{
		cout << "Your fall is invalid" << endl;
		return false;
	}
	if (x > X * 2+1 || x < 0 || y>X * 2+1 || y < 0)
	{
		cout << "Your fall is outside the chessboard" << endl;
		return false;
	}
	return true;
}
int main()
{
	int change = 1;
	while (change)
	{
		cout << "****************************************************************" << endl;
		cout << "**************Please select a game****************************************" << endl;
		cout << "**************0.sign out********************************************" << endl;
		cout << "**************1.computer vs game player**************************************" << endl;
		cout << "**************2.game player vs game player**************************************" << endl;
		cin >> change;
		switch (change)
		{
			case 1:break;
			case 2:
			{
				int x1, x2, y1, y2;
				fang_ge_qi_pang();
				cout << "The game begins!" << endl;
				do
				{
					cout << "Please player 1(Sunspot square)Enter chess coordinates:(If you enter 0, there will be no drop for this round of waiver)" << endl;
					cin >> x1 >> y1;//This coordinate is row x1 and column y1, so the subscript of the corresponding two-dimensional array below should be reversed
					while (!shi_fou_you_xiao(y1 * 2, x1 * 2))//Judge whether the drop is effective
					{
						cout << "Please re-enter the coordinates:" << endl;
						cin >> x1 >> y1;
					}
					system("cls");
					fang_ge_qi_zi(y1 * 2, x1 * 2, qizi_1);
					xian_shi_qi_pan();
					if (pan_duan_shu_yin(qizi_1))
					{
						cout << "The game is over. The black side wins" << endl;
						break;//Judge after the next. If the outcome is decided, you don't need to continue
					}
					cout << "Please player 2(Bai Zifang)Enter chess coordinates:(If you enter 0, there will be no drop for this round of waiver)" << endl;
					cin >> x2 >> y2;//This coordinate is row x2 and column y2, so the subscript of the corresponding two-dimensional array below should be reversed
					while (!shi_fou_you_xiao(y2 * 2, x2 * 2))
					{
						cout << "Please re-enter the coordinates:" << endl;
						cin >> x2 >> y2;
					}
					system("cls");
					fang_ge_qi_zi(y2 * 2, x2 * 2, qizi_2);
					xian_shi_qi_pan();
					if (pan_duan_shu_yin(qizi_2))
					{
						cout << "The game is over, Bai Fangsheng" << endl;
						break;//Judge after the next. If the outcome is decided, you don't need to continue
					}
				} while ((!pan_duan_shu_yin(qizi_1) == 1 || !pan_duan_shu_yin(qizi_2)));
			}
			case 0: break;
		}
	}
	
	system("pause");
	return 0;
}


Topics: C++