Thought and Realization of Judging Win or Lose in Java Gobang

Posted by JJohnsenDK on Sun, 01 Sep 2019 14:21:31 +0200

Thought and Realization of Judging Win or Lose in Java Gobang

Preface:

Self-taught Java has also been for some time, but there is no practical development experience, so I think about the development of Gobang game, the first problem encountered in the development process is the judgement of win or lose. In fact, in a sense, this is not a real problem, because it is easy to think of a "violence" algorithm "is to go through all directions of the chessboard after each fall until a five-piece connection is found, and then judge the win or lose. However, such a win-lose judgment will obviously cause unnecessary overhead to the system, and the time complexity of the algorithm will not be satisfactory if the chessboard is large enough (you may think that who has nothing to do to develop a chessboard to make a big chessboard, even so, the pursuit of the optimal solution is not a more manifestation of an open. Is there a spirit of excellence in the hair?
However, my plan is not perfect, compared with the "violence" solution, at least I think it has been improved, I want to use this as a starting point, if you have better suggestions, you are welcome to leave a message exchange.

Ideas:

In fact, the idea is very simple. First, the trigger of the winning or losing mechanism of the game is decided by the last chess piece on the current chessboard and the chess pieces around it (it seems to be nonsense, but it helps us to think), so we only need to care about the last chess piece and then go through the chess pieces around it and add the chess piece itself. Whether it can be connected into five pieces or not, remember, it's important to focus on this piece here, because it's easy for code implementation and easy for the following description. A total of eight directions, plus the central piece itself, traverse four times in each direction at most, because the most extreme case is that the number of central pieces from outside is just the fifth. After understanding the train of thought, it is not difficult to realize it.

Realization

/**
*	The Realization Class of the Judgment of Winning or Losing in Gobang
*	@author: L
*	Code description:
*		1.Parameters: A two-dimensional array of byte type is used to store all data of a chessboard.
*		The reason is that 0 represents the vacancy, 1 represents the player, and 2 represents the computer. The byte type is completely enough to save space.
*		The board represents the chessboard array, the row represents the row of the current chessboard, and the col represents the column of the current chessboard.
*		That is (row,col) the coordinates of the central chessboard
*		2.Readability: The code uses as many comments as possible, and as long as the principle is clear, it's actually very simple.
*		This class implements Gobang, which is mainly used for a constant in Gobang, i.e. the size of the chessboard BOARD_SIZE.
*		If you want to reuse code directly, your partner can directly replace BOARD_SIZE with your chessboard size.
*		Or replace it with board [0]. length (assuming your board is also square here)
*
*/
public class WinOrLose {
	/*
	*	Longitudinal Search Method
	*	It is divided into upper and lower parts.
	*	The same in other directions
	*/
	private static boolean winCol(byte[][] board, final int row, final int col) {
		int rowCount = 1;
		/*
		*	Look up
		*	col - i >= 0 In order to prevent the condition of crossing the boundary
		*	board[row][col - i] == board[row][col] Conditions for judging whether a chess piece is connected from the center outward
		*/
		for (int i = 1; i <= 4; i++) {
			if (col - i >= 0 && board[row][col - i] == board[row][col]) {
				rowCount++;	//If connected, add the number of pieces in that direction to one.
			} else {
				break;	//If you encounter the first vacancy or non-self chess piece exit the loop
			}
		}
		//Look down
		//Col + I < BOARD_SIZE also to prevent cross-border
		for (int i = 1; i <= 4; i++) {
			if (col + i < BOARD_SIZE && board[row][col + i]
				== board[row][col]) {
				rowCount++;
			} else {
				break;
			}
		}
		//If the number of pieces connected in the upper and lower directions is greater than or equal to 5, return true, otherwise return false.
		return rowCount >= 5 ? true : false;
	}
	private static boolean winRow(byte[][] board, final int row, final int col) {
		int colCount = 1;
		//Look left
		for (int i = 1; i <= 4; i++) {
			if (row - i >= 0 && board[row - i][col] == board[row][col]) {
				colCount++;
			} else {
				break;
			}
		}
		//Look to the right
		for (int i = 1; i <= 4; i++) {
			if (row + i < BOARD_SIZE &&
				board[row + i][col] == board[row][col]) {
				colCount++;
			} else {
				break;
			}
		}
		return colCount >= 5 ? true : false;
	}
	private static boolean winLeftLea(byte[][] board, final int row, final int col) {
		int leftLeaCount = 1;
		//Look up to the left
		for (int i = 1; i <= 4; i++) {
			if (row - i >= 0 && col - i >= 0 && board[row - i][col - i]
				== board[row][col]) {
				leftLeaCount++;	
			} else {
				break;
			}
		}
		//Look down to the right
		for (int i = 1; i <= 4; i++) {
			if (row + i < BOARD_SIZE && col + i < BOARD_SIZE &&
				board[row + i][col + i] == board[row][col]) {
				leftLeaCount++;
			} else {
				break;
			}
		}
		return leftLeaCount >= 5 ? true : false;
	}
	private static boolean winRightLea(byte[][] board, final int row, final int col) {
		int rightLeaCount = 1;
		//Look down to the left
		for (int i = 1; i <= 4; i++) {
			if (row + i < BOARD_SIZE && col - i >= 0 &&
				board[row + i][col - i] == board[row][col]) {
				rightLeaCount++;
			} else {
				break;
			}
		}
		//Look up to the right
		for (int i = 1; i <= 4; i++) {
			if (row - i >= 0 && col + i < BOARD_SIZE &&
				board[row - i][col + i] == board[row][col]) {
				rightLeaCount++;
			} else {
				break;
			}
		}
		return rightLeaCount >= 5 ? true : false;
	}
	/**
	*	This method calls other methods to judge four directions as judgment conditions.
	*	One of them satisfies when a chess game is won, returns true, or returns false.
	*
	*/
	public static boolean winOrLoseCheck(byte[][] board, final int row, final int col) {
		if (winCol(board, row, col) || winRow(board, row, col)
			|| winLeftLea(board, row, col) || winRightLea(board, row, col)) {
			return true;
		} else {
			return false;
		}
	}
}

Topics: Java