woaidaima2016 发表于 2017-6-13 11:31:04

百人跑马+机器人+控制组件【源码】

http://img.woaidaima.com//upload/image/20170517/1494983920751031729.jpghttp://img.woaidaima.com//upload/image/20170517/1494983922745070496.jpg#include "Stdafx.h"
#include "AndroidUserItemSink.h"
#include "math.h"

//////////////////////////////////////////////////////////////////////////

//时间标识
#define IDI_PLACE_JETTON1            103                                    //下注定时
#define IDI_PLACE_JETTON2            104                                    //下注定时
#define IDI_PLACE_JETTON3            105                                    //下注定时
#define IDI_PLACE_JETTON4            106                                    //下注定时
#define IDI_PLACE_JETTON5            107                                    //下注定时
#define IDI_CHECK_BANKER            108                                    //检查上庄
#define IDI_REQUEST_BANKER            101                                    //申请定时
#define IDI_GIVEUP_BANKER            102                                    //下庄定时
#define IDI_PLACE_JETTON            110                                    //下注定义 (预留110-160)

//////////////////////////////////////////////////////////////////////////


//构造函数
CAndroidUserItemSink::CAndroidUserItemSink()
{
    //游戏变量
    m_lMaxChipUser = 0;
    m_wCurrentBanker = 0;
    m_nChipTime = 0;
    m_nChipTimeCount = 0;
    m_cbTimeLeave = 0;
    ZeroMemory(m_lAreaChip, sizeof(m_lAreaChip));
    ZeroMemory(m_nChipLimit, sizeof(m_nChipLimit));

    return;
}

//析构函数
CAndroidUserItemSink::~CAndroidUserItemSink()
{
}

//接口查询
VOID *CAndroidUserItemSink::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
{
    QUERYINTERFACE(IAndroidUserItemSink,Guid,dwQueryVer);
    QUERYINTERFACE_IUNKNOWNEX(IAndroidUserItemSink,Guid,dwQueryVer);
    return NULL;
}

//初始接口
boolCAndroidUserItemSink::Initialization(IUnknownEx * pIUnknownEx)
{
    //查询接口
    m_pIAndroidUserItem=QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx,IAndroidUserItem);
    if (m_pIAndroidUserItem==NULL) return false;

    return true;
}

//重置接口
boolCAndroidUserItemSink::RepositionSink()
{
    //游戏变量
    m_lMaxChipUser = 0;
    m_wCurrentBanker = 0;
    m_nChipTime = 0;
    m_nChipTimeCount = 0;
    m_cbTimeLeave = 0;
    ZeroMemory(m_lAreaChip, sizeof(m_lAreaChip));
    ZeroMemory(m_nChipLimit, sizeof(m_nChipLimit));

    return true;
}

//时间消息
boolCAndroidUserItemSink::OnEventTimer(UINT nTimerID)
{
    if (nTimerID >= IDI_PLACE_JETTON && nTimerID <= IDI_PLACE_JETTON+MAX_CHIP_TIME)
    {
      srand(GetTickCount());

      //变量定义
      int nRandNum = 0, nChipArea = 0, nCurChip = 0, nACTotal = 0, nCurJetLmt = {};
      LONGLONG lMaxChipLmt = m_lMaxChipUser;            //最大可下注值
      WORD wMyID = m_pIAndroidUserItem->GetChairID();
      for (int i = 0; i < AREA_ALL; i++)
            nACTotal += m_RobotInfo.nAreaChance;

      //统计次数
      m_nChipTimeCount++;

      //检测退出
      if (lMaxChipLmt < m_RobotInfo.nChip])    return false;
      for (int i = 0; i < AREA_ALL; i++)
      {
            if (m_lAreaChip >= m_RobotInfo.nChip])    break;
            if (i == AREA_ALL - 1)    return false;
      }

      //下注区域
      ASSERT(nACTotal>0);
      static int nStFluc = 1;                //随机辅助
      if (nACTotal <= 0)    return false;
      do {
            nRandNum = (rand()+wMyID+nStFluc*3) % nACTotal;
            for (int i = 0; i < AREA_ALL; i++)
            {
                nRandNum -= m_RobotInfo.nAreaChance;
                if (nRandNum < 0)
                {
                  nChipArea = i;
                  break;
                }
            }
      }
      while (m_lAreaChip < m_RobotInfo.nChip]);
      nStFluc = nStFluc%3 + 1;

      //下注大小
      if (m_nChipLimit == m_nChipLimit)
            nCurChip = m_nChipLimit;
      else
      {
            //设置变量
            lMaxChipLmt = __min(lMaxChipLmt, m_lAreaChip);
            nCurJetLmt = m_nChipLimit;
            nCurJetLmt = m_nChipLimit;

            //计算当前最大筹码
            for (int i = m_nChipLimit; i > m_nChipLimit; i--)
            {
                if (lMaxChipLmt > m_RobotInfo.nChip)
                {
                  nCurJetLmt = i;
                  break;
                }
            }
   
            //随机下注
            nRandNum = (rand()+wMyID) % (nCurJetLmt-nCurJetLmt+1);
            nCurChip = nCurJetLmt + nRandNum;

            //多下控制 (当庄家金币较少时会尽量保证下足次数)
            if (m_nChipTimeCount < m_nChipTime)
            {
                LONGLONG lLeftJetton = LONGLONG( (lMaxChipLmt-m_RobotInfo.nChip)/(m_nChipTime-m_nChipTimeCount) );

                //不够次数 (即全用最小限制筹码下注也少了)
                if (lLeftJetton < m_RobotInfo.nChip] && nCurChip > m_nChipLimit)
                  nCurChip--;
            }
      }

      LONGLONG Gold = m_pIAndroidUserItem->GetMeUserItem()->GetUserScore();      

      int nMaxIndex=0;            

      for (int i=0; i < CountArray(m_RobotInfo.nChip); i++)
            if (Gold>m_RobotInfo.nChip) nMaxIndex=i;//

      nCurChip=rand()%(nMaxIndex+1);
      //变量定义
      CMD_C_PlayerBet stPlayerBet;
      ZeroMemory(&stPlayerBet, sizeof(stPlayerBet));
      stPlayerBet.lBetScore = m_RobotInfo.nChip;

      //发送消息
      m_pIAndroidUserItem->SendSocketData(SUB_C_PLAYER_BET, &stPlayerBet, sizeof(stPlayerBet));
    }

    m_pIAndroidUserItem->KillGameTimer(nTimerID);
    return false;
}

//游戏消息
boolCAndroidUserItemSink::OnEventGameMessage(WORD wSubCmdID, VOID * pBuffer, WORD wDataSize)
{
    switch(wSubCmdID)
    {
    case SUB_S_BET_START:            //开始下注
      return OnSubBetStart(pBuffer, wDataSize);

    case SUB_S_BET_END:                //下注结束
      return true;

    case SUB_S_HORSES_START:      //跑马开始
      return true;

    case SUB_S_HORSES_END:            //跑马结束
      return true;

    case SUB_S_PLAYER_BET:            //用户下注
      return OnSubPlayerBet(pBuffer, wDataSize);

    case SUB_S_PLAYER_BET_FAIL:      //下注失败
      return true;

    case SUB_S_NAMED_HORSES:      //马屁冠名
      return true;

    case SUB_S_MANDATOY_END:      //强制结束
      return true;

    case SUB_S_ADMIN_COMMDN:      //设置
      return true;

    }
    //错误断言
    ASSERT(FALSE);
    return true;
}

//游戏消息
boolCAndroidUserItemSink::OnEventFrameMessage(WORD wSubCmdID, VOID * pData, WORD wDataSize)
{
    return true;
}

//场景消息
boolCAndroidUserItemSink::OnEventSceneMessage(BYTE cbGameStatus, bool bLookonOther, VOID * pData, WORD wDataSize)
{
    switch (cbGameStatus)
    {
    case GS_FREE:            //空闲状态
      {
            //效验数据
            ASSERT(wDataSize==sizeof(CMD_S_SceneFree));
            if (wDataSize!=sizeof(CMD_S_SceneFree)) return false;

            //消息处理
            CMD_S_SceneFree * pSceneFree=(CMD_S_SceneFree *)pData;

            m_lUserLimitScore = pSceneFree->lUserLimitScore;
            m_lAreaLimitScore = pSceneFree->lAreaLimitScore;

            memcpy(m_szRoomName, pSceneFree->szGameRoomName, sizeof(m_szRoomName));
            ReadConfigInformation(m_RobotInfo.szCfgFileName, m_szRoomName, true);
            return true;
      }
    case GS_BET:   
      {
            //效验数据
            ASSERT(wDataSize==sizeof(CMD_S_SceneBet));
            if (wDataSize!=sizeof(CMD_S_SceneBet)) return false;

            //消息处理
            CMD_S_SceneBet * pSceneBet=(CMD_S_SceneBet *)pData;

            m_lUserLimitScore = pSceneBet->lUserLimitScore;
            m_lAreaLimitScore = pSceneBet->lAreaLimitScore;
            memcpy(m_szRoomName, pSceneBet->szGameRoomName, sizeof(m_szRoomName));

            ReadConfigInformation(m_RobotInfo.szCfgFileName, m_szRoomName, true);
            return true;
      }
    case GS_BET_END:
      {
            //效验数据
            ASSERT(wDataSize==sizeof(CMD_S_SceneBetEnd));
            if (wDataSize!=sizeof(CMD_S_SceneBetEnd)) return false;

            //消息处理
            CMD_S_SceneBetEnd * pSceneBetEnd=(CMD_S_SceneBetEnd *)pData;

            m_lUserLimitScore = pSceneBetEnd->lUserLimitScore;
            m_lAreaLimitScore = pSceneBetEnd->lAreaLimitScore;
            memcpy(m_szRoomName, pSceneBetEnd->szGameRoomName, sizeof(m_szRoomName));

            ReadConfigInformation(m_RobotInfo.szCfgFileName, m_szRoomName, true);
            return true;
      }
    case GS_HORSES:   
      {
            //效验数据
            ASSERT(wDataSize==sizeof(CMD_S_SceneHorses));
            if (wDataSize!=sizeof(CMD_S_SceneHorses)) return false;

            //消息处理
            CMD_S_SceneHorses * pSceneHorses=(CMD_S_SceneHorses *)pData;

            m_lUserLimitScore = pSceneHorses->lUserLimitScore;
            m_lAreaLimitScore = pSceneHorses->lAreaLimitScore;
            memcpy(m_szRoomName, pSceneHorses->szGameRoomName, sizeof(m_szRoomName));

            ReadConfigInformation(m_RobotInfo.szCfgFileName, m_szRoomName, true);
            return true;
      }
    }

    return true;
}

//用户进入
VOIDCAndroidUserItemSink::OnEventUserEnter(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
{
    return;
}

//用户离开
VOIDCAndroidUserItemSink::OnEventUserLeave(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
{
    return;
}

//用户积分
VOIDCAndroidUserItemSink::OnEventUserScore(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
{
    return;
}

//用户状态
VOIDCAndroidUserItemSink::OnEventUserStatus(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
{
    return;
}


//开始下注
bool CAndroidUserItemSink::OnSubBetStart(const void * pBuffer, WORD wDataSize)
{   
    //效验数据
    ASSERT(wDataSize==sizeof(CMD_S_BetStart));
    if (wDataSize!=sizeof(CMD_S_BetStart)) return false;

    //消息处理
    CMD_S_BetStart * pGameStart=(CMD_S_BetStart *)pBuffer;

    srand(GetTickCount());

    //自己当庄或无下注机器人
    if ( pGameStart->nChipRobotCount <= 0 )
      return true;

    //设置变量
    m_lMaxChipUser = __min(m_lUserLimitScore, m_pIAndroidUserItem->GetMeUserItem()->GetUserScore());
    m_nChipTimeCount = 0;
    ZeroMemory(m_nChipLimit, sizeof(m_nChipLimit));
    for (int i = 0; i < AREA_ALL; i++)
      m_lAreaChip = m_lAreaLimitScore;

    //计算下注次数
    int nElapse = 0;                                                
    WORD wMyID = m_pIAndroidUserItem->GetChairID();

    if (m_nRobotBetTimeLimit == m_nRobotBetTimeLimit)
      m_nChipTime = m_nRobotBetTimeLimit;
    else
      m_nChipTime = (rand()+wMyID)%(m_nRobotBetTimeLimit-m_nRobotBetTimeLimit+1) + m_nRobotBetTimeLimit;
    ASSERT(m_nChipTime>=0);      
    if (m_nChipTime <= 0)    return false;                              //的确,2个都带等于
    if (m_nChipTime > MAX_CHIP_TIME)    m_nChipTime = MAX_CHIP_TIME;    //限定MAX_CHIP次下注

    //计算范围
    if (!CalcJettonRange(m_lMaxChipUser, m_lRobotJettonLimit, m_nChipTime, m_nChipLimit))
      return true;

    //设置时间
    int nTimeGrid = int(pGameStart->nTimeLeave-2)*800/m_nChipTime;      //时间格,前2秒不下注,所以-2,800表示机器人下注时间范围千分比
    for (int i = 0; i < m_nChipTime; i++)
    {
      int nRandRage = int( nTimeGrid * i / (1500*sqrt((double)m_nChipTime)) ) + 1;      //波动范围
      nElapse = 2 + (nTimeGrid*i)/1000 + ( (rand()+wMyID)%(nRandRage*2) - (nRandRage-1) );
      ASSERT(nElapse>=2&&nElapse<=pgamestart->nTimeLeave);
      if (nElapse < 2 || nElapse > pGameStart->nTimeLeave)    continue;
      
      m_pIAndroidUserItem->SetGameTimer(IDI_PLACE_JETTON+i+1, nElapse);
    }
    return true;
}

//用户加注
bool CAndroidUserItemSink::OnSubPlayerBet(const void * pBuffer, WORD wDataSize)
{
    //效验数据
    ASSERT(wDataSize==sizeof(CMD_S_PlayerBet));
    if (wDataSize!=sizeof(CMD_S_PlayerBet)) return false;

    //消息处理
    CMD_S_PlayerBet * pPlayerBet=(CMD_S_PlayerBet *)pBuffer;

    //设置变量
    for(int i = 0; i < AREA_ALL; ++i)
    {
      m_lAreaChip -= pPlayerBet->lBetScore;
    }
    if (pPlayerBet->wChairID == m_pIAndroidUserItem->GetChairID())
    {
      for(int i = 0; i < AREA_ALL; ++i)
      {
            m_lMaxChipUser -= pPlayerBet->lBetScore;
      }
    }

    return true;
}


//读取配置
void CAndroidUserItemSink::ReadConfigInformation(TCHAR szFileName[], TCHAR szRoomName[], bool bReadFresh)
{
    //设置文件名
    TCHAR szPath = TEXT("");
    TCHAR szConfigFileName = TEXT("");
    TCHAR OutBuf = TEXT("");
    GetCurrentDirectory(sizeof(szPath), szPath);
    _sntprintf(szConfigFileName, sizeof(szConfigFileName), _T("%s\\%s"), szPath, szFileName);

    //筹码限制
    ZeroMemory(OutBuf, sizeof(OutBuf));
    GetPrivateProfileString(szRoomName, TEXT("RobotMaxJetton"), _T("100000"), OutBuf, 255, szConfigFileName);
    _sntscanf(OutBuf, _tcslen(OutBuf), _T("%I64d"), &m_lRobotJettonLimit);

    ZeroMemory(OutBuf, sizeof(OutBuf));
    GetPrivateProfileString(szRoomName, TEXT("RobotMinJetton"), _T("100"), OutBuf, 255, szConfigFileName);
    _sntscanf(OutBuf, _tcslen(OutBuf), _T("%I64d"), &m_lRobotJettonLimit);

    if (m_lRobotJettonLimit > 5000000)                  m_lRobotJettonLimit = 5000000;
    if (m_lRobotJettonLimit < 1000)                        m_lRobotJettonLimit = 100;
    if (m_lRobotJettonLimit < m_lRobotJettonLimit)    m_lRobotJettonLimit = m_lRobotJettonLimit;

    //次数限制
    m_nRobotBetTimeLimit = GetPrivateProfileInt(szRoomName, _T("RobotMinBetTime"), 4, szConfigFileName);;
    m_nRobotBetTimeLimit = GetPrivateProfileInt(szRoomName, _T("RobotMaxBetTime"), 8, szConfigFileName);;

    if (m_nRobotBetTimeLimit < 0)                            m_nRobotBetTimeLimit = 0;
    if (m_nRobotBetTimeLimit < m_nRobotBetTimeLimit)      m_nRobotBetTimeLimit = m_nRobotBetTimeLimit;
}

//计算范围    (返回值表示是否可以通过下降下限达到下注)
bool CAndroidUserItemSink::CalcJettonRange(LONGLONG lMaxScore, LONGLONG lChipLmt[], int & nChipTime, int lJetLmt[])
{
    //定义变量
    bool bHaveSetMinChip = false;

    //不够一注
    if (lMaxScore < m_RobotInfo.nChip)    return false;

    //配置范围
    for (int i = 0; i < CountArray(m_RobotInfo.nChip); i++)
    {
      if (!bHaveSetMinChip && m_RobotInfo.nChip >= lChipLmt)
      {
            lJetLmt = i;
            bHaveSetMinChip = true;
      }
      if (m_RobotInfo.nChip <= lChipLmt)
            lJetLmt = i;
    }
    if (lJetLmt > lJetLmt)    lJetLmt = lJetLmt;

    return true;
}

//组件创建函数
DECLARE_CREATE_MODULE(AndroidUserItemSink);

//////////////////////////////////////////////////////////////////////////

页: [1]
查看完整版本: 百人跑马+机器人+控制组件【源码】