基于网狐架构台州四张游戏的开发

台州四张是浙江台州地区流行的一种简单玩法的扑克游戏,以牌九为基础,对牌九进行了扩展,使玩法变得更有趣味性和竞技性。

    游戏玩家为4人,牌数:32张牌,不包括大、小王,由2张红Q、2张黑J、4张10、2张红9、4张7、4张6、2张红5、4张4、2张2、黑桃A、黑桃3组成

每家各分4张牌

由玩家自由组合,把4张牌组合成2对2张牌,再分别对比这两对牌,都赢者为赢家。

比牌时先比小牌,再比大牌

比牌大小按牌九的规则

 点数大小:  9点>8点>7点>6点>5点>4点>3点>2点>1点>0点提示:同样点数,取里面最大的一张牌比大小,(大小按对子出现的顺序,A和3按最小的计算)0点没有大小之分,都一样大,同样大的对子或点数,上家赢。  没有对牌,则以二牌之和的个位数分胜负。若没有以上的对牌,则以二牌之和的个位数分胜负.最大是9,最小是0 

牌点一样大的话,算上家胜出。


基于网狐架构台州四张游戏的开发-游戏设计这个游戏的设计比较简单,按客户的要求,没有下注,加注等按扭,只需要每局规定固定的底分,赢家赢,输家输就可以了。

    服务器要处理的是发牌,自动分牌,比牌。

    客户端要处理的是分牌,比牌,显示结果。

    先说说客户端的设计,游戏设计成2-4人都可以玩,可以分牌,客户端需要两个按扭,一个分牌,一个比牌,需要12个扑克控件,每人3个,一个显示4张扑克,其它两个显示分牌后的两张扑克。还要有一个积分控件,用于显示游戏结果。

 服务器部分很简单,只需要一个游戏逻辑类,用于处理发牌,分牌,比牌,需要处理两个网络事件,一个是分牌事件,一个是比牌事件,还有一个是游戏结束事件,再有一个就是定时器事件,处理客户端超时没有分牌,没有比牌的事件。


游戏开始每人发4张牌,由玩家自己组合成两组牌,每组2张,所以在客户端设计一个分牌按扭,按下按扭后4张扑克分为两组

 

//分牌按钮LRESULT CGameClientDlg::OnFenPai(WPARAM wParam, LPARAM lParam){

 //获取扑克 //用户分牌

 CMD_S_FenPai                    myfenpai; BYTE bTiCount,bNoChuCount; BYTE   NoTiCardData[4];bNoChuCount=m_GameClientView.m_CardControl[SwitchViewChairID(GetMeChairID())].GetNoShootCard(NoTiCardData,2);

if (bNoChuCount==2){  bTiCount=m_GameClientView.m_CardControl[SwitchViewChairID(GetMeChairID())].GetShootCard(myfenpai.bfCardData,2);bNoChuCount=m_GameClientView.m_CardControl[SwitchViewChairID(GetMeChairID())].GetNoShootCard(myfenpai.bnCardData,2);

 if (m_GameLogic.CompareCard(myfenpai.bfCardData,myfenpai.bnCardData,2)==true) {  BYTE tempcarddata[2];  memcpy(tempcarddata,myfenpai.bfCardData,sizeof(tempcarddata));  memcpy(myfenpai.bfCardData,myfenpai.bnCardData,sizeof(tempcarddata));  memcpy(myfenpai.bnCardData,tempcarddata,sizeof(tempcarddata)); 

 }

m_GameClientView.m_FenCardControl[SwitchViewChairID(GetMeChairID())][0].SetCardData(myfenpai.bfCardData,2);m_GameClientView.m_FenCardControl[SwitchViewChairID(GetMeChairID())][1].SetCardData(myfenpai.bnCardData,2);

m_GameClientView.m_FenCardControl[SwitchViewChairID(GetMeChairID())][0].SetDisplayFlag(true);m_GameClientView.m_FenCardControl[SwitchViewChairID(GetMeChairID())][1].SetDisplayFlag(true);

m_GameClientView.m_CardControl[SwitchViewChairID(GetMeChairID())].ShowWindow(false);

 SendData(SUB_C_FENPAI,&myfenpai,sizeof(myfenpai)); m_GameClientView.m_btFenpai.ShowWindow(SW_HIDE); //m_GameClientView.m_btAddGold.ShowWindow(SW_SHOW);KillGameTimer(IDI_FENPAI_TIME);

}

 return 0;

}

 

分牌后发送SUB_C_FENPAI给服务器

服务器收到SUB_C_FENPAI消息后进行如下处理

//分牌事件bool CTableFrameSink::OnUserFenPai(BYTE  bfCardData[2],BYTE  bnCardData[2],WORD wChairID){memcpy(m_bTableCardFenArray[wChairID][0],bfCardData,2);memcpy(m_bTableCardFenArray[wChairID][1],bnCardData,2);bBoolfen[wChairID]=true;bool fenover=true;

 for (WORD i=0;i<m_wPlayerCount;i++) {   if (m_pITableFrame->GetServerUserItem(i)!=NULL)  {   if (bBoolfen==false)              fenover=false;       }

 }

if (fenover){ m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_XIA_ZHU);}return true;

}收到消息后,把分牌扑克数据保存到服务器数组,然后循环判断是不是都已经分牌了,如果都分牌了,就发送SUB_S_XIA_ZHU消息给客户端,客户端收到后进行下注处理,下一编讲下注处理部


首先计算最大下注,在游戏开始计算玩家中最少积分的玩家积分数

//发送开始 CMD_S_GameStart GameStart; memset(&GameStart,0,sizeof(GameStart)); //计算下注 bool bCalculateGold=false; for (WORD i=0;i<m_wPlayerCount;i++) {  pIServerUserItem=m_pITableFrame->GetServerUserItem(i);  if (pIServerUserItem!=NULL)  {   m_bPlayStatus=true;   m_lTableGold[i*2+1]=m_pGameServiceOption->lCellScore;   if (bCalculateGold==false)   {    bCalculateGold=true;    pUserScore=pIServerUserItem->GetUserScore();    ASSERT(pUserScore->lScore>m_pGameServiceOption->lCellScore);    m_lMaxGold=pUserScore->lScore;   }   else   {    pUserScore=pIServerUserItem->GetUserScore();    ASSERT(pUserScore->lScore>1L);    m_lMaxGold=__min(m_lMaxGold,pUserScore->lScore);   }  } }

 GameStart.lMaxGold=m_lMaxGold; GameStart.lTurnMaxGold=m_lMaxGold/4L; GameStart.lTurnBasicGold=m_lTurnBasicGold;

计算出最少积分玩家的积分除4为最大下注数,游戏开始时发送给玩家

客户端在游戏到游戏开始时

   m_GameClientView.SetUserGoldInfo(wViewChairID,true,lBaseGold);

//用户筹码void CGameClientView::SetUserGoldInfo(WORD wViewChairID, bool bTableGold, DWORD dwGold){ //参数判断 WORD wGoldPos=wViewChairID*2+((bTableGold==true)?1:0); if (wGoldPos>=CountArray(m_GoldStation)) return;

 //设置变量 DWORD m_dwAllGold=0L; m_GoldView[wGoldPos].SetGold(dwGold); for (int i=0;i<CountArray(m_GoldStation);i++) m_dwAllGold+=m_GoldView.GetGold();

 //更新视图 UpdateGameView(NULL);

 return;}

  设置加注按扭的值,此处是根据客户的要求设定的方法。只有4个值可以下注

第一次为庄家下注,然后下家下注,下家下注只能大于等于上家


当所有玩家下注结束进行比牌处理:

服务器端

//比牌事件bool CTableFrameSink::OnBiPaiCard(BYTE bitwince){

 for (WORD i=0;i<m_wPlayerCount;i++) {   //没分牌自动分牌  if (m_bTableCardFenArray[0][0]==0)  {

   memcpy(m_bTableCardFenArray[0],&m_bTableCardArray[0],2);   memcpy(m_bTableCardFenArray[1],&m_bTableCardArray[2],2);     }

 } WORD wWinerUser=DeduceWiner(0,1,bitwince); for (WORD i=0;i<m_wPlayerCount;i++) {  if (i==wWinerUser)   bBoolWin[bitwince]=true;  else   bBoolWin[bitwince]=false;

 

 }    CMD_S_GAMEBI gamebi; memset(&gamebi,0,sizeof(CMD_S_GAMEBI)); for (WORD i=0;i<m_wPlayerCount;i++) {  memcpy(gamebi.bfCardData,m_bTableCardFenArray[0],sizeof(m_bTableCardFenArray[0])); memcpy(gamebi.bnCardData,m_bTableCardFenArray[1],sizeof(m_bTableCardFenArray[1])); memcpy(gamebi.bBoolWin,bBoolWin,sizeof(bBoolWin));

 }

 gamebi.bCardTwice=bitwince;

 m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_BI_CARD,&gamebi,sizeof(gamebi));    m_firstwinder=wWinerUser; bicount=1; //设置定时器 m_pITableFrame->SetGameTimer(IDI_BIPAITIME,1000L,1,NULL);

 return true;}

//二次比牌事件bool CTableFrameSink::OnBiPaiTwoCard(BYTE bitwince){

 for (WORD i=0;i<m_wPlayerCount;i++) {   if (m_pITableFrame->GetServerUserItem(i)!=NULL)   {  if (i!=m_firstwinder)  {  if (m_GameLogic.CompareCard(m_bTableCardFenArray[1],m_bTableCardFenArray[m_firstwinder][1],2)==true)     bBoolWin[bitwince]=true;  else     bBoolWin[bitwince]=false;  }   } }     CMD_S_GAMEBI gamebi;memset(&gamebi,0,sizeof(CMD_S_GAMEBI)); for (WORD i=0;i<m_wPlayerCount;i++) {  memcpy(gamebi.bfCardData,m_bTableCardFenArray[0],sizeof(m_bTableCardFenArray[0])); memcpy(gamebi.bnCardData,m_bTableCardFenArray[1],sizeof(m_bTableCardFenArray[1])); memcpy(gamebi.bBoolWin,bBoolWin,sizeof(bBoolWin));

 }

 gamebi.bCardTwice=bitwince;

 m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_BI_CARD,&gamebi,sizeof(gamebi));

  m_pITableFrame->SetGameTimer(IDI_GAMEEND,3000L,1,NULL);  return true;}

 

 

比牌进行两次,先对比小牌,小牌中的赢家再和其它3家对比大牌,两次都赢才为赢,否则为合//对比扑克bool CGameLogic::CompareCard(BYTE bFirstList[], BYTE bNextList[], BYTE bCardCount){ //获取类型 BYTE bNextType=GetCardType(bNextList,bCardCount); BYTE bFirstType=GetCardType(bFirstList,bCardCount); //两手牌的最大值 BYTE FirstMaxValue=GetMaxValue(bFirstList); BYTE NextMaxValue=GetMaxValue(bNextList); //两手牌的最小值 BYTE FirstMinValue=GetMinValue(bFirstList); BYTE NextMinValue=GetMinValue(bNextList); //最大牌的花色// BYTE FirstColor=GetMaxColor(bFirstList);// BYTE NextColor=GetMaxColor(bNextList);

 stCardType sFirstCard,sNextCard; sFirstCard=GetCardLevel(bFirstList); sNextCard=GetCardLevel(bNextList); if(sFirstCard.nLevel==sNextCard.nLevel) {  if(sFirstCard.nCardType==CT_SINGLE && sNextCard.nCardType==CT_SINGLE)  {   BYTE FirstTotalValue=(GetCardLogicValue(bFirstList[0])+GetCardLogicValue(bFirstList[1]))%10;   BYTE NextTotalValue=(GetCardLogicValue(bNextList[0])+GetCardLogicValue(bNextList[1]))%10;   if(FirstTotalValue==NextTotalValue)   {       return true;   }   else   {    return FirstTotalValue>NextTotalValue;   }  }  else  {   return sFirstCard.nCardType>sNextCard.nCardType;//对   } } else {  return sFirstCard.nLevel<sNextCard.nLevel ? true: false; }

 return false;

}比牌之后游戏结束

  {   //定义变量   CMD_S_GameEnd GameEnd;   memset(&GameEnd,0,sizeof(GameEnd));   tagScoreInfo ScoreInfo[m_wPlayerCount];   memset(&ScoreInfo,0,sizeof(ScoreInfo));   LONG lTax=0L;

 

    for (WORD i=0;i<m_wPlayerCount;i++)   {     pIServerUserItem=m_pITableFrame->GetServerUserItem(i);  if (pIServerUserItem!=NULL && bBoolgiveup==false)  {    //积分信息    if (i!=m_firstwinder)    {     if (bBoolWin[0]==false && bBoolWin[1]==false)     {     Bankuser=m_firstwinder; GameEnd.lGameGold-=(m_lTableGold[i*2]+m_pGameServiceOption->lCellScore);GameEnd.lGameGold[m_firstwinder]=GameEnd.lGameGold[m_firstwinder]-GameEnd.lGameGold+GameEnd.lGameGold*m_pITableFrame->GetTableShuilv()/100L;lTax=lTax-GameEnd.lGameGold*m_pITableFrame->GetTableShuilv()/100L;     }     else     {

     }    }

  }         }

      for (WORD i=0;i<m_wPlayerCount;i++)   {     pIServerUserItem=m_pITableFrame->GetServerUserItem(i);  if (pIServerUserItem!=NULL && bBoolgiveup==true)  {  GameEnd.lGameGold-=m_pGameServiceOption->lCellScore;if (GameEnd.lGameGold[m_firstwinder]!=0){ GameEnd.lGameGold[m_firstwinder]+=(m_pGameServiceOption->lCellScore-m_pGameServiceOption->lCellScore*m_pITableFrame->GetTableShuilv()/100L); lTax=lTax+m_pGameServiceOption->lCellScore*m_pITableFrame->GetTableShuilv()/100L;}

  }         }

                   GameEnd.lTax=lTax;      ScoreInfo[m_firstwinder].lRevenue=lTax;    //发送信息   m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_GAME_END,&GameEnd,sizeof(GameEnd));   m_pITableFrame->SendLookonData(INVALID_CHAIR,SUB_S_GAME_END,&GameEnd,sizeof(GameEnd));

   //修改用户分数

   for (WORD i=0;i<m_wPlayerCount;i++)   {     pIServerUserItem=m_pITableFrame->GetServerUserItem(i);  if (pIServerUserItem!=NULL)  {    if (m_bPlayStatus==TRUE)    {     ScoreInfo.lScore=GameEnd.lGameGold;     ScoreInfo.ScoreKind=(GameEnd.lGameGold>0L)?enScoreKind_Win:enScoreKind_Lost;     m_pITableFrame->WriteUserScore(i,ScoreInfo.lScore ,ScoreInfo.lRevenue ,ScoreInfo.ScoreKind);    }  }    } 

   //结束游戏   m_pITableFrame->ConcludeGame();

   return true;

 

 

 

客户端收到游戏结束消息后进行如下处理

 

//游戏结束bool CGameClientDlg::OnSubGameEnd(const void * pBuffer, WORD wDataSize){ //效验参数 if (wDataSize!=sizeof(CMD_S_GameEnd)) return false; CMD_S_GameEnd * pGameEnd=(CMD_S_GameEnd *)pBuffer;

 //播放声音 if (IsLookonMode()==false) {  if (pGameEnd->lGameGold[GetMeChairID()]>0L) PlayGameSound(AfxGetInstanceHandle(),TEXT("GAME_WIN"));  else PlayGameSound(AfxGetInstanceHandle(),TEXT("GAME_LOST")); } else PlayGameSound(GetModuleHandle(NULL),TEXT("GAME_END"));

 //游戏正常结束 BYTE bCardData[5]; m_GameClientView.m_ScoreView.ResetScore(); for (WORD i=0;i<GAME_PLAYER;i++) {  //设置信息  const tagUserData * pUserData=GetUserData(i);   if (pUserData!=NULL)  m_GameClientView.m_ScoreView.SetGameScore(pUserData->wChairID,pUserData->szName,pGameEnd->lGameGold);

 } m_GameClientView.m_ScoreView.SetTax(pGameEnd->lTax); m_GameClientView.m_ScoreView.ShowWindow(SW_SHOW);

 //设置控件 KillGameTimer(IDI_GIVE_UP);

 

 //设置状态 SetGameStatus(GS_FREE);

 //游戏变量 m_lTurnMaxGold=0L; m_lTurnBasicGold=0L; memset(m_bPlayStatus,0,sizeof(m_bPlayStatus));

 //辅助变量 m_lGoldShow=0L; m_bShowHand=false; m_bMeAddGold=false; memset(m_szName,0,sizeof(m_szName));

 //设置界面 if (IsLookonMode()==false) {  m_GameClientView.m_btStart.ShowWindow(SW_SHOW);  m_GameClientView.m_btStart.SetFocus();  //SetGameTimer(GetMeChairID(),IDI_START_GAME,30); }

 return true;}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • 不支持上传文件,所以就复制过来了。作者信息什么的都没删。对前端基本属于一窍不通,所以没有任何修改,反正用着没问题就...
    全栈在路上阅读 1,950评论 0 2
  • 英孚家长: 您好! 孩子今天学习了U8L3: 1.学习身体部位arms, legs, hands, feet, h...
    EmilyJia阅读 171评论 0 0
  • 正视自己
    烽火杨州璐阅读 98评论 0 1
  • 凉风起,秋意浓。 回泸州的那天晚上也是这般天气,你在我下车的地方来回走动,张望我会从哪辆车上下来,我在你的正对面看...
    御sen阅读 209评论 0 0