您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x游戏实例 《简单棋》入门尝试(六) 棋子吃子情况判定

2013-02-13 04:02 375 查看
在下完一步棋后,自然要判断这步棋所产生的吃对方棋子情况。为了便于接下来处理玩家下完棋之后电脑判断怎么下,先将我写的有关棋子被吃掉的函数写出来。有点被其搞晕了。呜呼!废话不多说,直接思路。如果逻辑有错误,请助我改正下。嘿嘿。

一:实现思路

现假设刚蓝方下了一步棋,正检测红棋是否有棋子会被吃掉。(里面涉及一些数组名字,如果不懂意思以及作用,可先跳到后面看看)

1、按顺序取出红方其中一颗棋子redLocation(最多6颗);

2、redLocation加入到数组connectedChessmans中;

3、获取棋子redLocation的邻结点nearPoint(可能有多个邻结点);

4、判断nearPoint的类型:

(1)判断redLocation是否在notNeedEated中,如果在显然不需要再验证,回到(1)。(此步骤是防止当连着的棋子重复被加入到notNeedEated数组中)

(2)判断nearPoint是否在数组notNeedEated中,如果在,说明nearPoint为己方棋子,并且不应该被吃掉,则其邻结点(亦当前需要检测的点redLocation)不需要被吃掉,将其加入到数组notNeedEated,并继续取出下一颗红棋,即回到(1);

(3)如果该点(nearPoint)为空,说明redLocation以及这次检测与其相连的点(即connectedChessmans中),不应该被吃掉,将其加入到数组notNeedEated中,继续取出下一颗红棋,即回到(1);

(4)如果该点(nearPoint)在数组connectedChessmans中,则是此次已经在检测的点,如本来检测红点1,然后点2也是红的,其根据该流程,会去检测点2,而点1也会是点2的邻结点,为了防止又回到点1去检测,则此处只要在connectedChessmans中则又回到(3);

(5)如果该点为蓝方棋子,说明棋子redLocation的一方已经被包围,现需要验证其余邻结点是否也包围了redLocation这个点。所以回到(3);

(6)如果该点为己方(红方)棋子,则将该邻结点nearPoint当做当前的redLocation回到(1)进行处理;

二:具体实现

1、在头文件MoveController.h中,定义了结构体_BothChessmansLocation存储当前红、蓝棋子在棋盘的位置。当棋子不满6颗时(被吃掉),赋值为-1。

/*存储当前棋盘*/
typedef struct _BothChessmansLocation
{
int redPlayerLocation[6];
int bluePlayerLocation[6];

_BothChessmansLocation()
{
for (int i = 0; i < 6; i++)
{
redPlayerLocation[i] = -1;
bluePlayerLocation[i] = -1;
}
}
}*_pBothChessmansLocation;


2、在头文件MoveController.h中,定义如下私有变量存储相关检测信息:

private:
int needEated[6];			//当前一步需要被吃掉的棋子
int needEatedCount;			//当前一步需要被吃掉的棋子的数量
int notNeedEated[6];			//当前不需要被吃掉的点
int notNeedEatedCount;
int connectedChessmans[6];		//该次检测相连的点(便于检测连在一起的点,只要判断其中一个不会被吃掉,则这些点都不会被吃掉)
int connectedChessmansCount;


3、在头文件MoveController.h中,声明了如下函数实现这个功能:
/*
**	功能:			根据当前棋盘,即pChessmansLocation变量获取需要被吃掉的棋子信息
**	pChessmansLocation:	当前棋盘布局
**	isRedNeedEated:	是否是红棋一方需要被吃掉(即刚是蓝方下的棋)
*/
void GetNeedEated(_pBothChessmansLocation pChessmansLocation, bool isRedNeedEated);

/*
**	 功能:			检测一个棋子是否应该被吃掉
**	 isRedNeedEated:	是否是红方会被吃掉(即刚落子的是蓝方)
** 	chessmanLocation:	检测的点的位置下表(1 - 21)
** 	nowChessmansLocation:	21个坐标点的信息
*/
void CheckOneChessmanIsNeedEated(bool isRedNeedEated, int chessmanLocation, _pBothChessmansLocation nowChessmansLocation);

/*
**	功能:	检测数组nums中是否包含num
**	count:	nums的个数
*/
bool IsContainNum(int num, int nums[], int count);


4、在MoveController.cpp中,实现声明了的函数:

void MoveController::GetNeedEated(_pBothChessmansLocation pChessmansLocation, bool isRedNeedEated)
{
needEatedCount = 0;
connectedChessmansCount = 0;
notNeedEatedCount = 0;
for(int i = 0; i < 6; i++)
{
needEated[i] = -1;
connectedChessmans[i] = -1;
notNeedEated[i] = -1;
}

for (int i = 0; i < 6; i++)
{
int dectingLocation;
if(isRedNeedEated == true)//如果是红棋需要被吃掉
{
dectingLocation = pChessmansLocation->redPlayerLocation[i];		//获取当前准备检测的点
}
else
{
dectingLocation = pChessmansLocation->bluePlayerLocation[i];	//当前准备检测的点
}
if(dectingLocation > 0)												//该点存在
{
CheckOneChessmanIsNeedEated(isRedNeedEated,dectingLocation, pChessmansLocation);
}
}
}

void MoveController::CheckOneChessmanIsNeedEated(bool isRedNeedEated, int checkingLocation, _pBothChessmansLocation nowChessmansLocation)
{
connectedChessmans[connectedChessmansCount] = checkingLocation;
connectedChessmansCount++;

for (int i = 0; i < 4; i++)
{
int nearPoint = pointsInfo[checkingLocation - 1].nearLocations[i];			//获取棋子的邻结点下表
if(nearPoint > 0)									//说明该邻结点存在
{
if(IsContainNum(checkingLocation, notNeedEated, 6))
{
for (int j = 0; j < connectedChessmansCount; j++)
{
connectedChessmans[j] = -1;					//并清空connectedChessmans
}
connectedChessmansCount = 0;					//清空connectedChessmans
return;
}
/*
1、如果nearPoint在数组notNeedEated中,说明nearPoint为己方棋子,并且不应该被吃掉,
则其邻结点(亦当前需要检测的点redLocation)不需要被吃掉,将其加入到数组notNeedEated。
2、如果该点(nearPoint)为空,说明redLocation以及这次检测与其相连的点(即connectedChessmans中),
不应该被吃掉,将其加入到数组notNeedEated中。
*/
if(IsContainNum(nearPoint, notNeedEated,6) == true ||
(IsContainNum(nearPoint, nowChessmansLocation->bluePlayerLocation, 6) == false &&
IsContainNum(nearPoint, nowChessmansLocation->redPlayerLocation, 6) == false))
{
for (int j = 0; j < connectedChessmansCount; j++)
{
notNeedEated[notNeedEatedCount] = connectedChessmans[j];
notNeedEatedCount++;
//并清空connectedChessmans
connectedChessmans[j] = -1;
}
//清空connectedChessmans
connectedChessmansCount = 0;
return;
}
else if(IsContainNum(nearPoint, connectedChessmans, 6) == true)
{
continue;
}
else
{
if (IsContainNum(nearPoint, nowChessmansLocation->bluePlayerLocation, 6) == isRedNeedEated)//判断nearPoint是不是对方棋子
{
/*如果该点为蓝方棋子,说明棋子redLocation的一方已经被包围,现需要验证其余邻结点是否也包围了redLocation这个点。*/
continue;
}
else
{
/*如果该点为己方(红方)棋子,则将该邻结点nearPoint当做当前的redLocation回到(1)进行处理*/
CheckOneChessmanIsNeedEated(isRedNeedEated, nearPoint, nowChessmansLocation);
}
}
}
}
}

bool MoveController::IsContainNum(int num, int nums[], int count)
{
for(int i = 0; i < count; i++)
{
if(num == nums[i])
return true;
}
return false;
}


5、调用函数,则只需要调用GetNeedEated,然后查看needEated数组里面的值就可以知道哪些棋子需要被吃掉罗。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: