偶然在硬盘的角落里发现了一个以前学习MFC时写的五子棋游戏,其中有一个关于判断获胜的算法自认为写的还凑合。一般的做法是遍历整个棋盘,判断是否获胜,这样的效率比较低。我认为下棋获胜与否只与当前落子后的局面有关,所以设计了如下算法:
/***********************************************
函数名称:IsWin()
参数说明:x,y 最新一步棋的行列号
chess 最新一步棋颜色
函数功能:由于一方获胜只可能是最近一步导致,
所以只需判断最新一步棋是否使下棋方获胜
************************************************/
BOOL CMyDoc::IsWin(int x,int y,int chess)
{
int i=x,j=y;
int count=0; //棋子计数器
/*计算水平方向连续棋子个数*/
while(i>-1 && this->board[i][j]==chess)
{
i--;
count++; //累加左侧
}
i=x+1;
while(i<15 && this->board[i][j]==chess)
{
i++;
count++; //累加右侧
}
if(count>=5)
return TRUE; //获胜
/*计算竖直方向连续棋子个数*/
i=x;
count=0;
while(j>-1 && this->board[i][j]==chess)
{
j--;
count++; //累加上方
}
j=y+1;
while(j<15 && this->board[i][j]==chess)
{
j++;
count++; //累加下方
}
if(count>=5)
return TRUE; //获胜
/*计算左上右下方向连续棋子个数*/
j=y;
count=0;
while(i>-1 && j>-1 && this->board[i][j]==chess)
{
i--;
j--;
count++; //累加左上
}
i=x+1;
j=y+1;
while(i<15 && j<15 && this->board[i][j]==chess)
{
i++;
j++;
count++; //累加右下
}
if(count>=5)
return TRUE; //获胜
/*计算右上左下方向连续棋子个数*/
i=x;
j=y;
count=0;
while(i<15 && j>-1 && this->board[i][j]==chess)
{
i++;
j--;
count++; //累加右上
}
i=x-1;
j=y+1;
while(i>-1 && j<15 && this->board[i][j]==chess)
{
i--;
j++;
count++; //累加左下
}
if(count>=5)
return TRUE; //获胜
return FALSE; //该步没有取胜
}
ps:board[15][15]储存棋盘落子信息的结构