您的位置:首页 > 其它

网狐游戏6603_德州扑克_机器人玩家功能开发浅谈

2013-05-28 16:34 225 查看
写在前面(由于本人对知识产权法律常识的欠缺,不知道写类型的开发经验与原理是否侵权):

如果涉及到侵犯网狐公司权益,请CSDN删帖,请勿公开,谢谢。

德州扑克机器人功能,我介绍的有点零散,只是开发时代经验。

一.文件介绍

下面几个文件主要添加机器人功能时用到

AndroidUserItemSink.h

AndroidUserItemSink.cpp

---------------类CAndroidUserItemSink

(文件名望文生义:机器人用户条目陷阱)

作用:与机器人相关的事件会落到该陷阱中,该陷阱内设有响应机制,触发相应的动作,发送传递消息等。

GameLogic.h

GameLogic.cpp

---------------类CGameLogic

(游戏逻辑文件)

作用:定义游戏的扑克数量、游戏玩法规则、牌型比较、牌值大小等功能

TableFrameSink.h

TableFrameSink.cpp

----------------类CTableFrameSink

(桌子框架陷阱)

作用:游戏桌面相关的事件都逃不出这个陷阱,该陷阱内设有响应机制,触发相应的动作,发送传递消息等。

CMD_DZShowHand.h

(消息定义文件)

作用:定义客户端与服务端通讯格式预订,常量定义等

下面第四条,类CAndroidUserItemSink与CTableFrameSink 数据传送做了举例说明。

二.机器人实现原理

CAndroidUserItemSink类,获取游戏场景消息。

包括游戏开始、用户加注、用户放弃、发牌消息、游戏结束等。

捕获此类消息后,

一种通过调用定时器处理函数实现相应动作。

另一种在捕获消息后,通过相应动作函数实现预期动作,在该动作函数中调用了定时器处理函数。

我们的机器人实现是通过后一种实现的。动作处理函数要获取许多预知的数据条件。

动作处理函数需要逻辑类CGameLogic的支持,逻辑类里在CAndroidUserItemSink类中被实例化了为m_GameLogic,即逻辑接口。

具体实现:

策划提出的机器人实现方案,主要是对牌型的判断决定机器人动作。现实中人的出牌出了对牌型的判断外,还有对对手玩家性格与局势的观察、一些细节等综合决定下注等动作,需要玩几轮积累经验。

但机器人不可能做到人的经验积累。

把机器人动作触发事件主要有:

1)游戏开始

首轮开始,机器人判断是否为当前玩家,如果是,机器人根据手牌牌型与牌值,决定下注或放弃情况。下注值的参考的几个基本数据与牌值。类CTableFrameSink会传来。

2)用户加注

前一人下注后,机器人判断是否是当前玩家,如果是,机器人同样按牌型与牌值,并参考桌面上是否有公牌存在,如果公牌没发,即按游戏开始的情况一致下注。

如果有公牌,判断公牌是3 、4 、5几张?

通过手牌与公牌的组合,选出最佳牌型,参考牌值、桌面注额,进行下注。

3)发牌消息

发公牌后机器判断自己是否为当前玩家,如果是,判断公牌数量,组合出最佳牌型,参考桌面注额与当前第几轮发牌决定下注。

三.机器人实现代码添加说明,以下是我的代码实现代码构架片段,大家如果感兴趣就看看,不能公布详细代码很抱歉。

1. AndroidUserItemSink.h

主要在机器人类中添加了需要获知的数据变量 与 实现具体功能的函数

//机器人类

class CAndroidUserItemSink

//游戏变量

protected:

BYTE m_cbHandCard[MAX_COUNT];
//用户手牌

BYTE m_cbCardType;
//牌类型

BYTE cbFirstValue;
//手牌值

BYTE cbSecondValue;
//手牌值

//机器人动作

protected:

bool PreFlopAction();
//底牌权/前翻牌圈

bool FlopRoundAction();
//翻牌圈

bool TurnRoundAction();
//转牌圈

函数定义详细见AndroidUserItemSink.cpp

2. AndroidUserItemSink.cpp

主要增加了需要添加动作的定时器(如下),以及在OnEventTimer()函数中定义动作定时器的消息发送细节。以及对AndroidUserItemSink.h中 机器人动作函数的实现。

#define IDI_USER_ADD1_GOLD
//加倍注定时器

#define IDI_USER_ADD2_GOLD //加倍注定时器

#define IDI_USER_FOLLOW_GOLD //跟注定时器

#define IDI_USER_PASS
//过牌定时器

#define IDI_USER_SHOW_HAND
//梭哈定时器

//时间消息

bool __cdecl CAndroidUserItemSink::OnEventTimer(UINT nTimerID)

3. GameLogic.h

增加所要用的扑克类型:

//扑克类型

#define HCT_SINGLE 11
//手牌单类型

#define HCT_PAIR 12
//手牌对类型

#define HCT_WILL_STRAIGHT 13
//手牌小顺类型

#define CT_LESS_STRAIGHT 14
//差一张顺子类型

增加函数:

//获取手牌类型

BYTE GetHandCardType();

//获取手牌+翻牌圈牌类型

BYTE GetFlopRoundCardType( );

//6返 获取手牌+转牌圈牌类型中最大牌型 BYTE FiveFromSix();

4. GameLogic.cpp

主要添加了对GameLogic.h文件中 添加函数的定义。

5. TableFrameSink.cpp

未增加新代码。

四.类CAndroidUserItemSink 与 类CTableFrameSink 通讯 简述

两个类之间是紧密联系,相互通讯。可以把类CAndroidUserItemSink看做是一个没有显示功能的游戏客户端。

下面只写文件名,相应的类名同过看文件名也能了解。

以开始游戏时代数据传输为例介绍:

TableFrameSink.cpp

//游戏开始

TableFrame.cpp

//发送数据

AttemperEngineSink.cpp

//发送数据

AndroidUserManager.cpp

//发送数据

AndroidUserItem.cpp

//网络消息

//游戏消息

AndroidUserItemSink.cpp

//游戏消息

//游戏开始

以下为详细代码片段:

TableFrameSink.cpp

//游戏开始

bool __cdecl CTableFrameSink::OnEventGameStart()

m_pITableFrame->SendTableData(i,SUB_S_GAME_START,&GameStart,sizeof(GameStart));

TableFrame.cpp

//发送数据

bool __cdecl CTableFrame::SendTableData(WORD wChairID, WORD wSubCmdID, void * pData, WORD wDataSize)

m_pIGameServiceFrame->SendData(m_pIUserItem[wChairID],MDM_GF_GAME,wSubCmdID,pData,wDataSize);

AttemperEngineSink.cpp

//发送数据

bool __cdecl CAttemperEngineSink::SendData(IServerUserItem * pIServerUserItem, WORD wMainCmdID, WORD wSubCmdID, void * pData, WORD wDataSize)

m_AndroidUserManager.SendDataToClient(dwID,wMainCmdID,wSubCmdID,pData,wDataSize);

AndroidUserManager.cpp

//发送数据

bool __cdecl CAndroidUserManager::SendDataToClient(DWORD dwAndroidID, WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)

if (pAndroidUserItem->OnSocketRead(wMainCmdID,wSubCmdID,pData,wDataSize)==false)

AndroidUserItem.cpp

//网络消息

bool CAndroidUserItem::OnSocketRead(WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)

//游戏消息

if ((wMainCmdID==MDM_GF_GAME)||(wMainCmdID==MDM_GF_FRAME))

{

return OnSocketGameMessage(wMainCmdID,wSubCmdID,pData,wDataSize);

}

//游戏消息

bool CAndroidUserItem::OnSocketGameMessage(WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)

return m_pIAndroidUserItemSink->OnEventGameMessage(wSubCmdID,pData,wDataSize);

AndroidUserItemSink.cpp

//游戏消息

bool __cdecl CAndroidUserItemSink::OnEventGameMessage(WORD wSubCmdID, void * pData, WORD wDataSize)

switch (wSubCmdID)

{

case SUB_S_GAME_START:
//游戏开始

{

return OnSubGameStart(pData,wDataSize);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐