Step by step to achieve a complete go game

Posted by sunil_23413 on Tue, 04 Jan 2022 07:01:17 +0100

1, Draw a chessboard

 

It can be understood as simple character drawing skills: the first line, the middle line and the last line are different; For each row, the first column is different from the middle and last column.

There is a little skill in drawing star positions. Focus on understanding the meaning of this formula: ((I-4)% 6 = = 0 & & (j-4)% 6 = = 0)

#include<iostream>
using namespace std;
int main(){
	cout<<"●○"<< endl;
	// Line 1 
	cout << "┏ ";
	for (int i=2; i<=18; i++){
		cout << "┯ ";
	}
	cout << "┓ "<< endl;
	// Middle 17 lines 
	for (int i=1; i<=19; i++){
		cout << "┠ ";
		for (int j=2; j<=18; j++){
			if ((i-4)%6==0 && (j-4)%6==0){
				cout<<"╋ ";
			} else {
				cout<<"┼ ";
			} 
		}
		cout << "┨ ";
		cout << endl; 
	} 
	// Line 19 
	cout << "┗ ";
	for (int i=2; i<=18; i++){
		cout << "┷ ";
	}
	cout << "┛ "<< endl;
	return 0;
	//		cout<<"╝╗╔╚║═╧╢╟╤┼╋";
	//  ┯┷┠┨┗┏┓┛┼╋
}

2, Luozi

In order to make the effect better, first add some colors. In addition, in order to facilitate use, the support of mouse operation is added. The functions of these two parts of code are discussed in other articles, which are omitted here. So far, the basic framework is still being established.

At the beginning, we used a simple strategy that the left button is white and the right button is black.

#include<iostream>
#include "mousetool.cpp"
#include "tools.cpp"
using namespace std;
void drawBoard(){
	// Line 1 
	cout << "┏ ";
	for (int i=2; i<=18; i++){
		cout << "┯ ";
	}
	cout << "┓ "<< endl;
	// Middle 17 lines 
	for (int i=2; i<=18; i++){
		cout << "┠ ";
		for (int j=2; j<=18; j++){
			if ((i-4)%6==0 && (j-4)%6==0){
				cout<<"╋ ";
			} else {
				cout<<"┼ ";
			} 
		}
		cout << "┨ ";
		cout << endl; 
	} 
	// Line 19 
	cout << "┗ ";
	for (int i=2; i<=18; i++){
		cout << "┷ ";
	}
	cout << "┛ "<< endl;
}
void click(int a, int x, int y){
	x=x/2*2;
	if (y>=19 || x>=38){
		return;
	}
	gotoxy(x,y);
	if (a==1){
	    setColor(15,6);
		cout << "●";
	} else {
	    setColor(0,6);
		cout << "●";
	}
}
int main(){
    initMouse();
    hideCursor();
    addEvent(1, click);
    addEvent(2, click);
    setColor(1,6);
    drawBoard();
    listenMouse();
	//cout<<"●○"<< endl;
	return 0;
	//		cout<<"╝╗╔╚║═╧╢╟╤┼╋";
	//  ┯┷┠┨┗┏┓┛┼╋
}

III. single bond drop

Two button drop is very inconvenient to use. We hope to replace it with one button drop. Because go is played by one person, the color of the current drop side can be recorded to achieve single click drop. The idea of the algorithm is state setting.

Simple code, omitted (can be downloaded directly)

4, Add lift function

Because of the single bond drop, the other key is empty. Now left click the drop button, and we'll right click the lift function in advance.

Students who can play go know that lifting a piece can lift more than one piece at a time. Obviously, it is more convenient and reasonable to lift all connected pieces with one key.

Structurally, two-dimensional arrays are used to store drop information. From an algorithmic point of view, the focus is on simple recursion. Show only the key logic.

void pullStone(int a, int x, int y){
	if (x<0 || y<0 || x>18 || y>18){
		return;
	}
	//cout << a << " " << x << " " << y << endl;
	if (arr[x][y]==a){
		arr[x][y]=0;
		remove(x,y);
		pullStone(a, x-1, y);
		pullStone(a, x+1, y);
		pullStone(a, x, y-1);
		pullStone(a, x, y+1);
	}
}

5, Automatic lift

Manual lifting is similar to the physical state, but it should be more convenient on the computer. We try to realize the function of automatic lifting. The key of automatic lifting is to judge whether a group of connected pieces are angry.

After each drop, check the chess pieces in four directions around it to see if there is no air. If so, lift them.

The algorithm here focuses on depth first search. Function noQi to judge whether a chess piece at a certain position has "no gas". A landmark operation of deep search is to modify the state and restore the state.

bool noQi(int a, int x, int y){
	if (x<0 || y<0 || x>18 || y>18){
		return true;
	} 
	//cout << a << " " << x << " " << y << endl;
	if (arr[x][y]==0){
		return false;
	} 
	if (arr[x][y]==3-a){
		return true;
	} 
	if (arr[x][y]==a){
		arr[x][y]=-a;
		bool ret= true;
		for (int i=-1; i<=1; i++){
			for (int j=-1; j<=1; j++){
				if (i*j==0){
					int x1= x+i;
					int y1= y+j;
					ret= ret && noQi(a, x1, y1);
				}
			}
		} 
		arr[x][y]=a;
		return ret;
	} 
	return true;
}

6, No air entry

With the previous foundation, we can now realize a drop rule of go, and the position of the drop cannot be without Qi. This rule vetoed the way that the bamboo bumped into itself and sent the whole dragon directly in Tianlong Babu. Go is not allowed to fall like this.

Of course, it is allowed to drop in the place where there is no air, but it can be lifted directly. Therefore, we first judge whether it can be lifted. If it can be lifted, it is allowed to fall unconditionally. Otherwise, we will test whether the drop is "airless" to determine whether it is allowed to fall.

The core logic is as follows:

	// First, pre drop
	arr[x][y]=gSide;
	// Check whether there are no angry chess pieces around. If so, lift them 
	int c= 3-gSide, cnt=0;
	cnt+=pull(c, x-1, y);
	cnt+=pull(c, x+1, y);
	cnt+=pull(c, x, y-1);
	cnt+=pull(c, x, y+1);
	if (cnt>0){
		// If there is a lift, you can drop it unconditionally and continue the operation 
	} else {
		// If there is no lift, the book cannot fall in a state of no Qi 
		if (noQi(gSide, x, y)){
			// If there is no air, cancel the operation 
			arr[x][y]=0;
			return;	
		}
	}

7, The last step is to realize the judgment of robbery

The previous logic has been relatively perfect, except robbery. When robbing, although you can pick up the son when you are satisfied, you can't immediately mention the son just raised by the other party. However, the situation of playing two for one is allowed. So how should the robbery rule be implemented?

The idea of the algorithm is as follows: first, if the other party's drop just caused the lift, and the lift is a sub, record the position of the drop. Then at this time, if we still mention only one son, and the son mentioned happens to be this son, it is not allowed.

Based on the above, the algorithm logic is modified as follows:

	// First, pre drop
	arr[x][y]=gSide;
	// Check whether there are no angry chess pieces around. If so, lift them 
	int c= 3-gSide, cnt=0;
	cnt+=pull(c, x-1, y);
	cnt+=pull(c, x+1, y);
	cnt+=pull(c, x, y-1);
	cnt+=pull(c, x, y+1);
	if (cnt>1){
		// If there is a Titus, you can drop it unconditionally and continue the operation 
	} else if (cnt==1){
		// If you happen to pick up a child, first see if it has just fallen 
		if (arr[prex][prey]==0){
			// To pick up the newly fallen book, first restore the state, and then see if the book is lifeless 
			arr[prex][prey]=c;
			if (noQi(gSide, x, y)){
				// If there is no gas, it indicates that it is in the state of robbery, so it cannot be raised and the scene can be restored 
				putStone(c, prex, prey);
				arr[x][y]=0;
				return;
			} else {
				// If there is gas, it is allowed to restore again 
				arr[prex][prey]=0;				 
			}
		} 
	} else {
		// If there is no lift, the book cannot fall in a state of no Qi 
		if (noQi(gSide, x, y)){
			// If there is no air, cancel the operation 
			arr[x][y]=0;
			return;	
		}
	}

8, Unrealized functions

The realization of functions is endless. Our small software realizes the complete single machine hot seat game function. But there is no function of recording chess score, let alone reading chess score. The most heinous thing is that there is no automatic counting function after the end. Interested students can try it by themselves. This is not a very simple function.

Topics: C++