defaultboardmodel.java

来自「java 开发的围棋打谱程序 可供大家做参考」· Java 代码 · 共 510 行

JAVA
510
字号
package org.nebula.goapplet;



import java.util.*;
import java.awt.*;

import org.nebula.cwt.grid.*;
import org.nebula.cutil.*;

/**
 * 
 * DefaultBoardModel
 * 
 * Description:
 * 
 * @author harry
 * 
 */
public class DefaultBoardModel implements GoBoardModel {

	private DefaultGridModel gridModel;

	private Vector moves_put;

	private int cur_col, cur_row;

	public DefaultBoardModel(int bsize) {
		if ((bsize < MIN_BOARD_SIZE) || (bsize > MAX_BOARD_SIZE)) {
			bsize = DEFAULT_BOARD_SIZE;
		}

		gridModel = new DefaultGridModel(bsize, bsize);

		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				gridModel.setObject(i, j, new GoPoint());
			}

		moves_put = new Vector();

		setCurrent(-1, -1);
	}

	public GridModel getGridModel() {
		return gridModel;
	}

	// ------------------ Board View Interface ------------------------------

	/**
	 * property get board size
	 */
	public int getBoardSize() {
		return gridModel.getRows();
	}

	public GoPoint getPoint(int col, int row) {
		return (GoPoint) gridModel.getObject(col, row);
	}

	public int getMovementCount() {
		return moves_put.size();
	}

	/*
	 * public Movement createMatchRecord() { Movement root = new Movement(-1,
	 * -1, GoPlayer.BLACK); Movement cur = root; for (int i = 0; i <
	 * moves_put.size(); i++) { Movement move = (Movement)
	 * moves_put.elementAt(i); Movement c = new Movement(move.col, move.row,
	 * move.player); cur.add(c); cur = c; } return root; }
	 */
	public Movement getLastMovement() {
		if (moves_put.size() == 0)
			return null;

		return (Movement) moves_put.lastElement();
	}

	/**
	 * clear all point
	 */
	public void reset() {
		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				getPoint(i, j).setState(GoPoint.EMPTY);
				getPoint(i, j).setNumber(GoPoint.NONE);
				getPoint(i, j).setHolder(GoPlayer.UNKNOWN);
				getPoint(i, j).setSigned(false);
				getPoint(i, j).setStyle(GoPoint.GENERAL);
			}
		moves_put.removeAllElements();
		gridModel.fireDataChanged();
	}

	/**
	 * clear all point
	 */
	public void reset(int bsize) {
		if ((bsize < MIN_BOARD_SIZE) || (bsize > MAX_BOARD_SIZE)) {
			bsize = DEFAULT_BOARD_SIZE;
		}

		gridModel.reset(bsize, bsize);

		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				gridModel.setObject(i, j, new GoPoint());
			}

		moves_put.removeAllElements();
	}

	/**
	 * clear domain mark so that no point show mark
	 */
	public void clearDomainMarks() {
		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				getPoint(i, j).setHolder(GoPlayer.UNKNOWN);
			}
	}

	public void setTip(int col, int row, int tip) {
		getPoint(col, row).setTip(tip);
	}

	public void setNumber(int col, int row, int number) {
		getPoint(col, row).setNumber(number);
	}

	public boolean isCurrent(int col, int row) {
		if ((col == cur_col) && (row == cur_row)) {
			return true;
		}

		return false;
	}

	// ------------------ Operation Interface ------------------------------

	public void undo() {
		Movement move = (Movement) moves_put.lastElement();
		if (move == null) {
			return;
		}

		for (int i = 0; i < move.captiveCount(); i++) {
			Movement.Captive p = move.captiveAt(i);
			System.out.println("restoring: [" + p.col + "," + p.row);
			getPoint(p.col, p.row).setState(p.color);
			getPoint(p.col, p.row).setNumber(p.number);
		}
		moves_put.removeElement(move);

		if (validatePoint(move.col, move.row)) {
			getPoint(move.col, move.row).setState(GoPoint.EMPTY);
		}

		if (moves_put.size() > 0) {
			move = (Movement) moves_put.lastElement();
			setCurrent(move.col, move.row);
		} else {
			setCurrent(-1, -1);
		}
	}

	/**
	 * divide domain to black side and white side empty body blong to it's
	 * closest neibor; if one empty body's neibor don't have same color, it's in
	 * neutrality
	 */
	public void divideDomain() {
		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				getPoint(i, j).setHolder(GoPlayer.UNKNOWN);
			}

		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				if (getPoint(i, j).getHolder() == GoPlayer.UNKNOWN) {
					if (getPoint(i, j).getState() == GoPoint.BLACK) {
						getPoint(i, j).setHolder(GoPlayer.BLACK);
					} else if (getPoint(i, j).getState() == GoPoint.WHITE) {
						getPoint(i, j).setHolder(GoPlayer.WHITE);
					} else {
						Vector v = getBody(i, j);
						findSpaceHolder(v);
					}
				}
			}
	}

	public void forceRemove(int x, int y) {
		if (!validatePoint(x, y)) {
			return;
		}

		if (getPoint(x, y).getState() == GoPoint.EMPTY) {
			return;
		}

		getPoint(x, y).setState(GoPoint.EMPTY);
	}

	public void performRemove(int x, int y) throws GoException {
		if (!validatePoint(x, y)) {
			throw new GoException("Invalid point");
		}

		if (getPoint(x, y).getState() == GoPoint.EMPTY) {
			throw new GoException("No chessman to remove");
		}

		Movement move = new Movement(-1, -1, GoPlayer.UNKNOWN);
		removeBody(x, y, move);
		moves_put.addElement(move);
	}

	public void forcePut(int x, int y, int state) {
		if (!validatePoint(x, y)) {
			return;
		}

		if (getPoint(x, y).getState() != GoPoint.EMPTY) {
			return;
		}

		getPoint(x, y).setState(state);
	}

	public void performPut(int x, int y, int player) throws GoException {
		Logger.debug("performPut [" + x + "," + y + "," + player + "]");
		if (!validatePoint(x, y)) {
			return;
		}
		if ((player != GoPlayer.BLACK) && (player != GoPlayer.WHITE)) {
			return;
		}

		if (getPoint(x, y).getState() != GoPoint.EMPTY) {
			throw new GoException("There is already one chessman");
		}

		// test put it and check it
		Movement move = new Movement(x, y, player);

		boolean maybeProhibited = false;
		if (moves_put.size() > 0) {
			Movement last = (Movement) moves_put.lastElement();
			if (last.captiveCount() == 1) {
				Movement.Captive cp = last.captiveAt(0);
				if ((cp.col == x) && (cp.row == y)) {
					maybeProhibited = true;
				}
			}
		}

		// 预先设置,若不成功再移去
		if (player == GoPlayer.BLACK) {
			getPoint(x, y).setState(GoPoint.BLACK);
		} else {
			getPoint(x, y).setState(GoPoint.WHITE);
		}

		// 判断邻近点情况
		// 初始时pHand.life=4,代表周围四个点为空点
		// 程序可根据pHand.life以及pHand.rub 设置劫的状态
		int a[] = { x - 1, x + 1, x, x };
		int b[] = { y, y, y - 1, y + 1 };

		int tmpLife = 0;
		for (int i = 0; i < 4; i++) {
			if (!validatePoint(a[i], b[i]))
				continue;
			else {
				int xx = a[i];
				int yy = b[i];
				if (getPoint(xx, yy).getState() == GoPoint.EMPTY) {
					// 周围若有空点,tmpLife!=0,允许落子
					tmpLife = tmpLife + 1;
				} else {
					// 如果敌方棋子已死,则提掉
					if (GoPoint.isEnemy(getPoint(x, y), getPoint(xx, yy))) {
						if (isDead(xx, yy)) {
							if (maybeProhibited) {
								if (isSingle(xx, yy)) {
									getPoint(x, y).setState(GoPoint.EMPTY);
									throw new GoException("Prohibited put");
								}
							}
							removeBody(xx, yy, move);
							tmpLife = tmpLife + 1;
						}
					}
				}
			}
		}

		// 如果不能提子,并且落子后为死子,则此处不能落子
		if (tmpLife == 0) {
			if (isDead(x, y)) { // 如果仍为死子,不许落子
				getPoint(x, y).setState(GoPoint.EMPTY);
				throw new GoException("Prohibited put");
			}
		}

		moves_put.addElement(move);
		getPoint(x, y).setNumber(moves_put.size());
		setCurrent(x, y);
	}

	protected void removeBody(int x, int y, Movement move) {
		int a[] = { x - 1, x + 1, x, x };
		int b[] = { y, y, y - 1, y + 1 };

		int curState = getPoint(x, y).getState();
		getPoint(x, y).setState(GoPoint.EMPTY);
		if (move != null)
			move.addCaptive(x, y, getPoint(x, y).getNumber(), curState);

		for (int i = 0; i < 4; i++) {
			if (!validatePoint(a[i], b[i]))
				continue;
			else {
				int xx = a[i];
				int yy = b[i];
				if (getPoint(xx, yy).getState() == curState) {
					removeBody(xx, yy, move);
				}
			}
		}
	}

	/**
	 * get owner of the body
	 * 
	 * @v: points in the body
	 */
	protected void findSpaceHolder(Vector v) {
		int holder = GoPlayer.UNKNOWN;

		for (int i = 0; i < v.size(); i++) {
			Point p = (Point) v.elementAt(i);
			int x = p.x;
			int y = p.y;
			int a[] = { x - 1, x + 1, x, x };
			int b[] = { y, y, y - 1, y + 1 };

			for (int j = 0; j < 4; j++) {
				if (!validatePoint(a[j], b[j]))
					continue;
				else {
					int xx = a[j];
					int yy = b[j];
					if (getPoint(xx, yy).getState() == GoPoint.BLACK) {
						if (holder == GoPlayer.UNKNOWN) {
							holder = GoPlayer.BLACK;
						} else if (holder == GoPlayer.WHITE) {
							holder = GoPlayer.BOTH;
							break;
						}
					}
					if (getPoint(xx, yy).getState() == GoPoint.WHITE) {
						if (holder == GoPlayer.UNKNOWN) {
							holder = GoPlayer.WHITE;
						} else if (holder == GoPlayer.BLACK) {
							holder = GoPlayer.BOTH;
							break;
						}
					}
				}
			}
		} // end for

		for (int i = 0; i < v.size(); i++) {
			Point p = (Point) v.elementAt(i);
			getPoint(p.x, p.y).setHolder(holder);
		}
	}

	/**
	 * get chessmen with same color and adjacent to each other
	 * 
	 * @v: points in the body
	 */
	protected Vector getBody(int x, int y) {
		clearAllSigns();
		Vector v = new Vector();
		createBody(x, y, v);
		return v;
	}

	/**
	 * get chessmen with same color and adjacent to each other
	 * 
	 * @v: points in the body
	 * 
	 * @see #getBody(int x, in y)#
	 */
	protected void createBody(int x, int y, Vector v) {
		int a[] = { x - 1, x + 1, x, x };
		int b[] = { y, y, y - 1, y + 1 };

		int curState = getPoint(x, y).getState();
		if (v != null)
			v.addElement(new Point(x, y));

		getPoint(x, y).setSigned(true);

		for (int i = 0; i < 4; i++) {
			if (!validatePoint(a[i], b[i]))
				continue;
			else {
				int xx = a[i];
				int yy = b[i];
				if (getPoint(xx, yy).isSigned())
					continue;
				if (getPoint(xx, yy).getState() == curState) {
					createBody(xx, yy, v);
				}
			}
		} // end for
	}

	/**
	 * check whether the chessman in position x,y have no neibor with the same
	 * color
	 */
	protected boolean isSingle(int x, int y) {
		int a[] = { x - 1, x + 1, x, x };
		int b[] = { y, y, y - 1, y + 1 };

		for (int i = 0; i < 4; i++) {
			if (!validatePoint(a[i], b[i]))
				continue;
			int xx = a[i];
			int yy = b[i];
			if (!GoPoint.isEnemy(getPoint(x, y), getPoint(xx, yy)))
				return false;
		}
		return true;
	}

	/**
	 * check whether the chessman in position x,y be in "dead" state
	 */
	protected boolean isDead(int x, int y) {
		clearAllSigns();
		return noLife(x, y);
	}

	/**
	 * recursively check whether the chessmen are in "dead" state
	 */
	protected boolean noLife(int x, int y) {
		int a[] = { x - 1, x + 1, x, x };
		int b[] = { y, y, y - 1, y + 1 };
		getPoint(x, y).setSigned(true);

		for (int i = 0; i < 4; i++) {
			if (!validatePoint(a[i], b[i]))
				continue;
			else {
				int xx = a[i];
				int yy = b[i];
				if (getPoint(xx, yy).isSigned())
					continue;
				if (getPoint(xx, yy).getState() == GoPoint.EMPTY) {
					return false;
				}
				if (getPoint(xx, yy).getState() == getPoint(x, y).getState())
					if (!noLife(a[i], b[i]))
						return false;
			}
		}
		return true;
	}

	private void setCurrent(int c, int r) {
		if ((cur_col > 0) && (cur_row > 0)) {
			getPoint(cur_col, cur_row).setStyle(GoPoint.GENERAL);
		}
		if ((c > 0) && (r > 0)) {
			getPoint(c, r).setStyle(GoPoint.HIGHLIGHT);
		}
		cur_col = c;
		cur_row = r;
	}

	/**
	 * clear signs
	 */
	private void clearAllSigns() {
		for (int i = 0; i < getBoardSize(); i++)
			for (int j = 0; j < getBoardSize(); j++) {
				getPoint(i, j).setSigned(false);
			}
	}

	private boolean validatePoint(int col, int row) {
		if ((col < 0) || (col >= getBoardSize()) || (row < 0)
				|| (row >= getBoardSize()))
			return false;
		else
			return true;
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?