现在的位置: 首页 > 综合 > 正文

五子棋游戏中判断胜负的C++源代码

2018年01月11日 ⁄ 综合 ⁄ 共 1672字 ⁄ 字号 评论关闭

        今天在看《精通Windows Sockets 网络开发——基于Visual C++》(孙海民 编著,人民邮电出版社出版)这本书的时候,有一个网络五子棋游戏的实例,个人觉得除了服务器和客户端通信、管理用户列表之外,在每一步中判断黑方和白方哪一方获胜是这个游戏程序的关键。所以将源代码贴在这里,供大家学习参考:

        说明:这个程序不能直接运行,只是说明判断胜负的算法

#include <iostream>
#include <math.h>
#define MAX 30 //五子棋棋盘大小是30×30的正方形,每个单元格是边长为1的正方形
using namespace std;
int color[MAX][MAX];//存储棋子的颜色
bool IsWin(int x,int y)
{
	int xMin = max(0,x - 4);//水平位置最小值
	int xMax = min(x + 4,MAX - 1);//水平位置最大值
	int yMin = max(0,y - 4);//垂直位置最小值
	int yMax = min(y + 4,MAX - 1);//垂直位置最大值

	int i,j,p,q;
	int sum;
	//初始化棋子颜色
	for(i = 0;i < MAX;i++)
		for(j = 0;j < MAX;j++)
			color[i][j] = 0;

	//在水平方向遍历,看是否有连续5颗相同颜色的棋子
	for(i = xMin;i <= xMax - 4;i++)
	{
		sum = 0;
		for(j = i;j < i + 5;j++)
		{
			if(color[j][y] == color[x][y])
				sum++;
			else
				break;
		}
		if(sum == 5)
			return true;
	}

	//在垂直方向遍历,看是否有连续5颗相同颜色的棋子
	for(i = yMin;i <= yMax - 4;i++)
	{
		sum = 0;
		for(j = i;j < i + 5;j++)
		{
			if(color[x][i] == color[x][y])
				sum++;
			else
				break;
		}
		if(sum == 5)
			return true;
	}

	//左上角位置,从(x,y)开始沿左上方寻找,找到一个满足条件的最大正方形,则从正方形的左上顶点开始沿对角线遍历
	for(i = x,j = y;i > xMin && j > yMin;i--,j--);
	//从左上角向右下角遍历,看是否有连续5颗相同颜色的棋子
	for(;i <= xMax - 4 && j <= yMax - 4;i++,j++)
	{
		sum = 0;
		for(p = i,q = j;p < i + 5;p++,q++)
		{
			if (color[p][q] == color[x][y])
				sum++;
			else
				break;
		}
		if(sum == 5)
			return true;
	}

	//左下角位置,从(x,y)开始沿左下方寻找,找到一个满足条件的最大正方形,则从正方形的左下顶点开始沿对角线遍历
	for(i = x,j = y;i > xMin && j < yMax;i--,j++);
	//从左下角向右上角遍历,看是否有连续5颗相同颜色的棋子
	for(;i <= xMax - 4 && j >= yMin + 4;i++,j--)
	{
		sum = 0;
		for(p = i,q = j;p < i + 5;p++,q--)
		{
			if (color[p][q] == color[x][y])
				sum++;
			else
				break;
		}
		if(sum == 5)
			return true;
	}
	return false;
}

     后来发现这样不对,比如 xMin = yMin = 0但(x , y) = (5 , 3)时,要从(2 ,0)开始向右下方遍历,而不是从(0 ,0)开始。所以要用 for(i = x,j = y;i > xMin && j > yMin;i--,j--)循环从(x,y)开始沿左上方寻找,找到一个满足条件的最大正方形,则从正方形的左上顶点 (2 ,0)开始沿对角线遍历。

     此外,我觉得这个算法还可以优化。例如:当前在(5 , 3)位置放了一颗黑色的棋子,第一次遍历的路径为 :A(2, 0)(黑色)——B(3 ,1)(黑色)——C(4,2)(白色),到C点时内层循环退出,继续从B3 ,1)开始遍历,其实因为C(4,2)是白色,所以内层循环没必要再遍历检查A到C之间的点,直接从下一个点D(5,3)开始遍历。

抱歉!评论已关闭.