MFC设计局域网对战五子棋游戏(五)游戏中的数据结构和算法

7 篇文章 0 订阅
6 篇文章 0 订阅

游戏中设计的结构体有:

 

//棋盘中每个格子的信息
typedef struct dot{
	UINT used	:1;//是否已经被占用
	UINT uid	:7;//占用者的id号
	UINT lt		:3;//左上角有几个相同id号的棋子
	UINT t		:3;//上方有几个相同id号的棋子
	UINT rt		:3;//以下根据方向不同表示意思类似
	UINT l		:3;//字段名称后的“:3”表示这个字段
	UINT r		:3;//只占用多少位,而不占用整个UInt
	UINT lb		:3;//空间,可以节省不少的内存空间
	UINT b		:3;
	UINT rb		:3;
	dot(){
		//C++中结构体也可以有构造函数
		//这里我把结构体全部置0
		ZeroMemory(this,sizeof(Dot));
	}
}Dot;

//用来保存当前所有棋子位置和id号
typedef struct piece{
	BYTE uid;
	BYTE x;
	BYTE y;
}Piece;

enum {
	SEARCH_HOST,//搜索游戏主机
	HOST_RESPONSE,//游戏主机回应
	ALLOT_ID,//分配给客户端id号
	JOIN_GAME,//加入游戏
	QUIT_GAME,//退出游戏
	MOVE//下棋走子
};


//网络通信的结构体,想当于自定义游戏协议
typedef struct MsgPack{
	BYTE type;//消息的类型,
	union data{
		struct ServerResponse{
			CHAR server[19];
			BYTE uesrNum;
		}SR;//如果类型是主机回应,则采用这个结构体
		CHAR gamer[20];//如果是加入游戏信息,则表示客户端名称
		BYTE uid;//如果是分配id号,则表示分配给的id号
		struct PlaceDot{
			BYTE uid;
			BYTE x;
			BYTE y;
		}PD;//如果是下棋走子,则表示棋子的信息
	}data;
	MsgPack(){
		//默认构造函数,所有字段置0
		ZeroMemory(this,sizeof(MsgPack));
	}
}MsgPack;


游戏中设计的算法是为了判断是否有输赢,主要函数为:

 

// 更新棋盘所有节点的值
UINT CWZQDlg::SetDotValue(BYTE x, BYTE y, BYTE UID, BYTE dir)
{
	if (dir == 0)
	{
		for (int i = 1; i <= 8; i++)
		{
			if ((*DirLocDot(x,y,i)).uid == UID)
			{
				DirSetDotValue(x,y,i,DirGetDotValue((*DirLocDot(x,y,i)),i)+1);
				BYTE a,b;
				DirModify(x,y,i,a,b);
				SetDotValue(a,b,UID,i);
			}
		}
		if(
			grid[x][y].t	+	grid[x][y].b	>=4||
			grid[x][y].l	+	grid[x][y].r	>=4||
			grid[x][y].lt	+	grid[x][y].rb	>=4||
			grid[x][y].rt	+	grid[x][y].lb	>=4
			)
			return grid[x][y].uid;
	}
	else
	{
		BYTE from_dir;
		if(dir%2 == 0)
		{
			from_dir = dir - 1;
		}
		else
		{
			from_dir = dir + 1;
		}
		DirSetDotValue(x,y,from_dir,DirGetDotValue((*DirLocDot(x,y,from_dir)),from_dir)+1);
		if ((*DirLocDot(x,y,dir)).uid == UID)
		{
			BYTE a,b;
			DirModify(x,y,dir,a,b);
			SetDotValue(a,b,UID,dir);
		}
	}	
	return 0;
}


/*
 *	规定方向代码
 *	1  3  5
 *	8  ×  7
 *	6  4  2
 */

// 定位不同方向的棋盘格点
Dot* CWZQDlg::DirLocDot(BYTE x, BYTE y, BYTE dir)
{
	switch (dir)
	{
	case 1:
		return &grid[x-1][y-1];
		break;
	case 2:
		return &grid[x+1][y+1];
		break;
	case 3:
		return &grid[x][y-1];
		break;
	case 4:
		return &grid[x][y+1];
		break;
	case 5:
		return &grid[x+1][y-1];
		break;
	case 6:
		return &grid[x-1][y+1];
		break;
	case 7:
		return &grid[x+1][y];
		break;
	case 8:
		return &grid[x-1][y];
		break;
	default:
		return NULL;
		break;
	}
}


// 获取节点不同方向的值
BYTE CWZQDlg::DirGetDotValue(Dot dot, BYTE dir)
{
	switch (dir)
	{
	case 1:
		return dot.lt;
		break;
	case 2:
		return dot.rb;
		break;
	case 3:
		return dot.t;
		break;
	case 4:
		return dot.b;
		break;
	case 5:
		return dot.rt;
		break;
	case 6:
		return dot.lb;
		break;
	case 7:
		return dot.r;
		break;
	case 8:
		return dot.l;
		break;
	default:
		return 0;
		break;
	}
}


// 设置节点不同方向的值
void CWZQDlg::DirSetDotValue(BYTE x, BYTE y, BYTE dir, BYTE value)
{
	switch (dir)
	{
	case 1:
		grid[x][y].lt = value;
		break;
	case 2:
		grid[x][y].rb = value;
		break;
	case 3:
		grid[x][y].t = value;
		break;
	case 4:
		grid[x][y].b = value;
		break;
	case 5:
		grid[x][y].rt = value;
		break;
	case 6:
		grid[x][y].lb = value;
		break;
	case 7:
		grid[x][y].r = value;
		break;
	case 8:
		grid[x][y].l = value;
		break;
	default:
		break;
	}
}


// 根据方向设置新的x,y坐标值
void CWZQDlg::DirModify(BYTE ori_x,BYTE ori_y,BYTE dir,BYTE& to_x, BYTE& to_y)
{
	if (dir == 1||dir == 6||dir == 8)
			{
				to_x = ori_x-1;
			}
			else if (dir == 3||dir == 4)
			{
				to_x = ori_x;
			}
			else
			{
				to_x = ori_x+1;
			}
			if (dir == 1||dir == 3||dir == 5)
			{
				to_y = ori_y-1;
			}
			else if (dir == 7||dir == 8)
			{
				to_y = ori_y;
			}
			else
			{
				to_y = ori_y+1;
			}
}

因为是局域网对战游戏,所以只需要判断输赢而没有AI部分,所以
这些函数都不是很复杂,我就不解释了。

 

源代码下载: http://download.csdn.net/download/jokers_i/4223218

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值