游戏中设计的结构体有:
//棋盘中每个格子的信息
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部分,所以
这些函数都不是很复杂,我就不解释了。