五子棋落子游戏 (一)

2014-11-24 11:10:37 · 作者: · 浏览: 8

题目要求:

假设已有15*15的五子棋棋盘(0-14),黑白子对下,现要求能够实现落子接口:

1)落子成功时,如果当前颜色的棋子胜利(有5子连成一条线),黑子胜利返回2,白子胜利返回3,没有人胜利时,返回落子成功1;

2)黑白子顺序混乱、或者重复落子等异常返回-1;

分析:

1、需要实现保存所下所有棋子的数据;

2、在1前提下,能够判定所下棋子是否有5个子在一条直线上(2条直线、2条对角线),即实现胜利的判定算法;

3、需要保存黑子、白子落子的顺序,处理落子失败等异常;


感觉5子的直线判定算法应该是其中比较麻烦的,我的初步想法是黑子或者白子落子后,遍历其所有下过的棋子,分别遍历2条直线和2条对角线上的棋子是否有5个;

如判定水平线上是否有5子成线:

1)取一点A,判断其右边的点是否在下过的棋子中,是就把水平线上棋子的统计数量加1,继续向右遍历;

2)如果棋子的统计数量加等于5则返回胜利;否则如果右边已经没有下一点在所下棋子中,同时统计数量小于5,则从A点向左遍历,统计继续累加,等于5时返回胜利;

其它三个方向类似;


仔细想想发现没必要遍历每个点,只对最后落的子B进行如上遍历即可。因为如果存在5个点,不与B相邻且是相邻节点,且在一条直线上,那么在B棋子落下之前就已经胜利了;

算法就说这么多;


说说面向对象设计思路:

1、定义1个棋盘类,保存棋盘大小,可对棋子做是否越界判定;

2、定义棋手类,能够保存所下棋子的位置,并在落子后,判定最后的落子是否能够与其它位置的棋子形成5子一线;

3、定义棋子枚举,规定是黑子还是白子,被棋手类引用;

4、定义位置类,点坐标;

5、定义游戏类:拥有一个棋盘和2个棋手,定义了落子参数的入口。


这个问题比较简单:

直接上代码

[java]
/**
*
* 类名称:ChessConstants 类描述: 创建人:dobuy
*
*/
public interface ChessConstants
{
/**
* 落子成功
*/
int SUCCESS = 1;

/**
* 落子失败:顺序不对、位置非法、指定棋手非法
*/
int FAIL = -1;

/**
* 黑子赢
*/
int BLACK_WIN = 2;

/**
* 白子赢
*/
int WHITE_WIN = 3;

/**
* 黑子
*/
int BLACK = 0;

/**
* 白子
*/
int WHITE = 1;

/**
* 错误的棋手编号
*/
int ERROR = -1;

/**
* 赢时一条线上的棋子数量
*/
int WIN_OF_LINE_CHESSES = 5;

int DEFAULT_TURN = -2;
}

/**
*
* 类名称:ChessConstants 类描述: 创建人:dobuy
*
*/
public interface ChessConstants
{
/**
* 落子成功
*/
int SUCCESS = 1;

/**
* 落子失败:顺序不对、位置非法、指定棋手非法
*/
int FAIL = -1;

/**
* 黑子赢
*/
int BLACK_WIN = 2;

/**
* 白子赢
*/
int WHITE_WIN = 3;

/**
* 黑子
*/
int BLACK = 0;

/**
* 白子
*/
int WHITE = 1;

/**
* 错误的棋手编号
*/
int ERROR = -1;

/**
* 赢时一条线上的棋子数量
*/
int WIN_OF_LINE_CHESSES = 5;

int DEFAULT_TURN = -2;
}

[java]
/**
* 棋盘(棋子的地图)
*
* @author dobuy
* @time 2013-5-12
*/
public class Chessboard
{
/**
* 棋盘的最小边界点(原点)
*/
private Position origonPosition;

/**
* 棋盘的最大边界点
*/
private Position edgePosition;

public Chessboard()
{
this.origonPosition = new Position(0, 0);
this.edgePosition = new Position(14, 14);
}

/**
* 当前位置在棋盘中是否越界
*
* @return
*/
public boolean isOverEdge(Position currentPosition)
{
if (currentPosition.getX() < getOrigonPosition().getX()
|| currentPosition.getY() < getOrigonPosition().getY()
|| currentPosition.getX() > getEdgePosition().getX()
|| currentPosition.getY() > getEdgePosition().getY())
{
return true;
}
return false;
}

private Position getEdgePosition()
{
return edgePosition;
}

private Position getOrigonPosition()
{
return origonPosition;
}
}

/**
* 棋盘(棋子的地图)
*
* @author dobuy
* @time 2013-5-12
*/
public class Chessboard
{
/**
* 棋盘的最小边界点(原点)
*/
private Position origonPosition;

/**
* 棋盘的最大边界点
*/
private Position edgePosition;

public Chessboard()
{
this.origonPosition = new Position(0, 0);
this.edgePosition = new Position(14, 14);
}

/**
* 当前位置在棋盘中是否越界
*
* @return
*/
public boolean isOverEdge(Position currentPosition)
{
if (currentPosition.getX() < getOrigonPosition().getX()
|| currentPosition.getY() < getOrigonPosition().getY()
|| currentPosition.getX() > getEdgePosition().getX()
|| currentPosition.getY() > getEdgePosition().getY())
{
return true;
}
return false;
}

private Position getEdgePositio