⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servermanage.cpp

📁 添七,棋牌游戏源代码,功能齐全,稳定,适合用于棋牌游戏开发
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				if (m_pUserInfo[i]!=NULL) 
					m_pUserInfo[i]->m_UserData.bUserState=USER_SITTING;
			}
			GameCutStruct CutEnd;
			CutEnd.bDeskStation=bDeskStation;
			if(bCloseFlag==GF_SALE)
			{
				CutEnd.iTurePoint[bDeskStation]=0;
				CutEnd.iTurePoint[(bDeskStation+1)%4]=0;
				CutEnd.iTurePoint[(bDeskStation+2)%4]=0;
				CutEnd.iTurePoint[(bDeskStation+3)%4]=0;
			}
			else
			{
				//设置分数
				if (iTurePoint>0) m_iUpGradePeople=(m_iUpGradePeople+2)%4;
				else m_iUpGradePeople=(m_iUpGradePeople+1)%4;

				if(iTurePoint>-1)
				{
					CutEnd.iTurePoint[bDeskStation]=-15;
					CutEnd.iTurePoint[(bDeskStation+1)%4]=0;
					CutEnd.iTurePoint[(bDeskStation+2)%4]=0;
					CutEnd.iTurePoint[(bDeskStation+3)%4]=0;
				}
				else
				{
					if(bDeskStation==m_iUpGradePeople || bDeskStation==(m_iUpGradePeople+2)%4)//如果将能升级,逃跑者不得分,他对家得分
					{
						CutEnd.iTurePoint[m_iUpGradePeople%4]=CutEnd.iTurePoint[(m_iUpGradePeople+2)%4]=abs(iTurePoint*3);
						CutEnd.iTurePoint[bDeskStation]=0;
						CutEnd.iTurePoint[(m_iUpGradePeople+1)%4]=CutEnd.iTurePoint[(m_iUpGradePeople+3)%4]=-abs(iTurePoint*3);
					}
					else
					{
						CutEnd.iTurePoint[bDeskStation]=-15;
						CutEnd.iTurePoint[(bDeskStation+1)%4]=0;
						CutEnd.iTurePoint[(bDeskStation+2)%4]=0;
						CutEnd.iTurePoint[(bDeskStation+3)%4]=0;
					}
				}
			}

			//发送信息
			if (bCloseFlag==GF_SALE)
			{
				for (int i=0;i<m_bMaxPeople;i++) SendGameData(i,&CutEnd,sizeof(CutEnd),MDM_GM_GAME_NOTIFY,ASS_SALE_END,0);
				SendWatchData(m_bMaxPeople,&CutEnd,sizeof(CutEnd),MDM_GM_GAME_NOTIFY,ASS_SALE_END,0);
			}
			else
			{
				//计算金币类和比赛类的实得分
				if (m_pDataManage->m_InitData.uComType!=TY_NORMAL_GAME)
				{
					CutEnd.iTurePoint[0]*=iBasePoint;
					CutEnd.iTurePoint[1]*=iBasePoint;
					CutEnd.iTurePoint[2]*=iBasePoint;
					CutEnd.iTurePoint[3]*=iBasePoint;
					for (BYTE i=0;i<m_bMaxPeople;i++)
					{ 
						if(CutEnd.iTurePoint[i]<0)
							CutEnd.iTurePoint[i]=__max(-m_dwMaxPoint,CutEnd.iTurePoint[i]);
						if (CutEnd.iTurePoint[i]>0)
						{
							CutEnd.iTurePoint[i]=__min(m_dwMaxPoint,CutEnd.iTurePoint[i]);
							//if(m_pDataManage->m_InitData.uComType!=SUP_MATCH_GAME)
								CutEnd.iTurePoint[i]=CutEnd.iTurePoint[i]*19L/20L;
						}
					}
				}
				
				for (int i=0;i<4;i++)
					ChangeUserPoint(m_pUserInfo[i],CutEnd.iTurePoint[i],CutEnd.iTurePoint[i]>0,CutEnd.iTurePoint[i]<0,CutEnd.iTurePoint[i]==0,(bDeskStation==i && CutEnd.iTurePoint[i]<0));

				for (int i=0;i<m_bMaxPeople;i++) SendGameData(i,&CutEnd,sizeof(CutEnd),MDM_GM_GAME_NOTIFY,ASS_CUT_END,0);
				SendWatchData(m_bMaxPeople,&CutEnd,sizeof(CutEnd),MDM_GM_GAME_NOTIFY,ASS_CUT_END,0);
			}

			bCloseFlag=GFF_FORCE_FINISH;

			ReSetGameState(bCloseFlag);
			__super::GameFinish(bDeskStation,bCloseFlag);
			return true;
		}
	}

	//重置数据
	ReSetGameState(bCloseFlag);
	__super::GameFinish(bDeskStation,bCloseFlag);

	return true;
}

//判断是否正在游戏
bool CServerGameDesk::IsPlayGame(BYTE bDeskStation)
{
	return __super::IsPlayGame(bDeskStation);
}

//用户离开游戏桌
BYTE CServerGameDesk::UserLeftDesk(BYTE bDeskStation, CGameUserInfo * pUserInfo)
{
	if ((m_pUserInfo[bDeskStation]!=NULL)&&(m_bGameStation==GS_WAIT_ARGEE)&&(bDeskStation==0))
	{
		//更改数据
		m_bGameStation=GS_WAIT_SETGAME;
		for (int i=0;i<m_bMaxPeople;i++)
		{
			if (m_pUserInfo[i]!=NULL) m_pUserInfo[i]->m_UserData.bUserState=USER_SITTING;
		}
	}
	else if(m_bGameStation==GS_WAIT_SETGAME && (m_pUserInfo[bDeskStation]!=NULL) && m_iBeenPlayGame>0)
	{
		GameFinish(0,GF_SALE);
	}
	return __super::UserLeftDesk(bDeskStation,pUserInfo);
}

//游戏数据包处理函数
bool CServerGameDesk::HandleNotifyMessage(BYTE bDeskStation, NetMessageHead * pNetHead, void * pData, UINT uSize, UINT uSocketID, bool bWatchUser)
{
	switch (pNetHead->bAssistantID)
	{
	case ASS_GM_AGREE_GAME:		//用户同意游戏
		{
			if (bWatchUser) return FALSE;
			if ((bDeskStation==0)&&(m_bGameStation==GS_WAIT_SETGAME))	//东家设置
			{
				if (uSize!=sizeof(UserArgeeGame)) return FALSE;
				UserArgeeGame * pGameSet=(UserArgeeGame *)pData;
				if (!UserSetGame(pGameSet)) return FALSE;
				__super::HandleNotifyMessage(bDeskStation,pNetHead,pData,uSize,uSocketID,bWatchUser);
				return TRUE;
			}
			//其他玩家
			if ((m_bGameStation!=GS_WAIT_ARGEE)&&(m_bGameStation!=GS_WAIT_NEXT)) 
				return TRUE;
			return __super::HandleNotifyMessage(bDeskStation,pNetHead,pData,uSize,uSocketID,bWatchUser);
		}
	
	case ASS_OUT_CARD:		//用户出牌
		{
			if(bWatchUser)
				return false;
			if(m_bGameStation==GS_WAIT_NEXT || m_bGameStation==GS_WAIT_ARGEE || m_bGameStation==GS_WAIT_SETGAME)
				return true;
			OutCardStruct * pOutCard=(OutCardStruct *)pData;
			if ((uSize<=(sizeof(OutCardStruct)-sizeof(pOutCard->iCardList)))
				||(uSize>sizeof(OutCardStruct))||bWatchUser) return FALSE;
			if (uSize!=(sizeof(OutCardStruct)-sizeof(pOutCard->iCardList)+sizeof(BYTE)*pOutCard->iCardCount)) return FALSE;
			
			m_iKouCardFalg = pNetHead->bHandleCode;
			ModifyPlayInfo(bDeskStation,pOutCard->iCardCount);
			return UserOutCard(bDeskStation,pOutCard->iCardList,pOutCard->iCardCount);
		}
	case ASS_HAVE_THING:	//有事请求离开
		{
			if(bWatchUser)
				return false;
			HaveThingStruct * pThing=(HaveThingStruct *)pData;
			return UserHaveThing(bDeskStation,pThing->szMessage);
		}
	case ASS_LEFT_RESULT: //同意用户离开
		{
			if(bWatchUser)
				return false;
			LeaveResultStruct * pLeave=(LeaveResultStruct *)pData;
			return ArgeeUserLeft(bDeskStation,pLeave->bArgeeLeave);
		}
	case ASS_STOP_THING:
		{
			if(bWatchUser)
				return false;
			SendGameData((bDeskStation+2)%4,MDM_GM_GAME_NOTIFY,ASS_STOP_THING,0);
			return true;
		}
	case ASS_AGREE_STOP:
		{
			if(bWatchUser)
				return false;
			StopResultStruct * pStop=(StopResultStruct *)pData;
			if(pStop->bArgee==1)
			{
				//同意
				StopResultStruct stop;
				stop.bArgee=true;
				SendGameData((bDeskStation+2)%4,&stop,sizeof(stop),MDM_GM_GAME_NOTIFY,ASS_AGREE_STOP,0);

				MessageStruct Mess;
				memset(&Mess,0,sizeof(Mess));
				strcpy(Mess.Message,"敌家经过商量,提前结束了本局!");
				SendGameData((bDeskStation+1)%4,&Mess,sizeof(Mess),MDM_GM_GAME_NOTIFY,ASS_MESSAGE,0);
				SendGameData((bDeskStation+3)%4,&Mess,sizeof(Mess),MDM_GM_GAME_NOTIFY,ASS_MESSAGE,0);

				memset(&Mess,0,sizeof(Mess));
				strcpy(Mess.Message,"拣分的双方经过商量,提前结束了本局!");
				SendWatchData(m_bMaxPeople,&Mess,sizeof(Mess),MDM_GM_GAME_NOTIFY,ASS_MESSAGE,0);
				//结束游戏
				if (m_bGameStation==GS_PLAY_GAME) 
					GameFinish(0,GF_NORMAL);
			}
			else
			{
				StopResultStruct stop;
				stop.bArgee=false;
				SendGameData((bDeskStation+2)%4,&stop,sizeof(stop),MDM_GM_GAME_NOTIFY,ASS_AGREE_STOP,0);
			}
			return true;
		}

	case ASS_PASS://不出
		{
			if (bWatchUser) return false;
			if(m_bGameStation==GS_WAIT_NEXT || m_bGameStation==GS_WAIT_ARGEE || m_bGameStation==GS_WAIT_SETGAME)
				return true;
			
			
			NewPlayTurn(bDeskStation);
			if (!IsNewTurn)
			{
				for (int i=0;i<m_bMaxPeople;i++) 
					SendGameData(i,MDM_GM_GAME_NOTIFY,ASS_PASS,m_iOutCardPeople);
				SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_PASS,m_iOutCardPeople);
			}

			return true;
		}

		
	}
	return __super::HandleNotifyMessage(bDeskStation,pNetHead,pData,uSize,uSocketID,bWatchUser);
}



/*
  名词解释:
   扣牌分:按扣牌张点数计算的分数,K为13分,Q为12分,J为11分,10为10分,
      依此类推,A为1分;每位玩家扣牌分为其扣下的牌张分值总和;
  “通”或“走通”:游戏结束时当一名玩家把手中所有的牌都跟出,
          面前无扣牌时,这种状态称为”通”或”走通”;
		  如有两名玩家”走通”则称为”双通”,三名玩家”走通”则称为”三通”。
  “独头七”:当有一位玩家”走通”并且所跟出的最后一张牌为任意一张7时,
          这张7称为”独头七”。

 积分说明:
1.得分计算:
  假设A、B、C、D四个玩家在一局游戏结束后,手中扣牌分分别为:
  A:5分  B:8分  C:1分  D:12分
  按下面的公式计算最后得分:
  A的得分=(B扣牌分-A扣牌分)+(C扣牌分-A扣牌分)+(D扣牌分-A扣牌分)
  B的得分=(A扣牌分-B扣牌分)+(C扣牌分-B扣牌分)+(D扣牌分-B扣牌分)
  C的得分=(A扣牌分-C扣牌分)+(B扣牌分-C扣牌分)+(D扣牌分-C扣牌分)
  D的得分=(A扣牌分-D扣牌分)+(B扣牌分-D扣牌分)+(C扣牌分-D扣牌分)
  按上述公式计算得到ABCD的实际得分为:
  A: (8 - 5) + (1 - 5) + (12 - 5) = 3 - 5 +7 = 6分
  B: (5 - 8) + (1 - 8) + (12 - 8) = -3 -8 + 4 = -6分 
  C: (5 - 1) + (8 - 1) + (12 - 1) = 5 + 8 + 12 = 22
  D: (5 - 12) + (8 - 12) + (1 - 12) = -7 -4 -12 = -22
  四位玩家的分数相加的总和为零
2.当有一位玩家”走通”时,其他三位玩家的扣牌分都要加倍;当发生”双通”时,
   另两位玩家的扣牌分都要乘以4;当发生”三通”时,未通的一位玩家扣牌分要乘以8;

3.当有一位玩家”走通”并且其所跟出的最后一张牌为任意一张7时,这张7称为”独头七”。
   每出现一张”独头七”,则未通的每位玩家的扣牌分要乘以8。

*/
//计算得分
int	CServerGameDesk::GetUpGrade(int iGamePoint, int iPlayCardCount)
{
	int scores[4] = {0,0,0,0};
	int totScore = 0;
	bool bZouTong[4] = {false,false,false,false};
	for (int i = 0;i < 4;i++)
	{
		int tot = 0;
		for (int j = 0;j < m_iKouCardCount[i];j++)
		{	
			int pd = m_Logic.GetCardNum(m_iKouCard[i][j]);
			if ( pd== 14) tot += 1;
			else tot += pd;
		}
		totScore += tot;
		scores[i] += tot;
		if (tot <= 0) bZouTong[i] = true;
	}
	
	for (int i = 0;i < 4;i++)
	{
		if (!bZouTong[i]) continue;
		int ff = 2;
		if (m_Logic.GetCardNum(m_iLastOneCard[i]) == 7) ff = 8;
		for (int j = 0;j < 4;j++) scores[j] *= ff;
	}
	for (int i = 0;i < 4;i++) m_iTurePoint[i] = totScore - 4 * scores[i];

	return 0;
}

//用户设置游戏
BOOL CServerGameDesk::UserSetGame(UserArgeeGame * pGameSet)
{
	//效验数据
	if (m_bGameStation!=GS_WAIT_SETGAME) return FALSE;

	//效验数据
	if (((pGameSet->iPlayCount<=0)||(pGameSet->iPlayCount>99))||
		(pGameSet->iBeginStation<2)||(pGameSet->iEndStation>14)||
		(pGameSet->iBeginStation>pGameSet->iEndStation)) 
		return FALSE;
	if ((m_CardCount & pGameSet->iCardCount)==0) return FALSE;

	//设置数据
	m_iLessCount=pGameSet->iPlayCount;
	m_iPlayCardCount=(pGameSet->iCardCount&1)?2:3;
	m_iBeginStation=pGameSet->iBeginStation;
	m_iEndStation=pGameSet->iEndStation;
	m_iBeenPlayGame=0;

	
	m_bGameStation=GS_WAIT_ARGEE;
	m_Logic.SetNTCardNum(pGameSet->iBeginStation);
	m_Logic.SetNTHuaKind(UG_ERROR_HUA);
	m_iPlayNTNum[0]=pGameSet->iBeginStation;
	m_iPlayNTNum[1]=pGameSet->iBeginStation;

	//发送消息
	UserArgeeGame Agree;
	Agree.iBeginStation=m_iBeginStation;
	Agree.iEndStation=m_iEndStation;
	Agree.iPlayCount=m_iLessCount;
	Agree.iCardCount=m_iPlayCardCount;
	for (int i=0;i<4;i++) SendGameData(i,&Agree,sizeof(Agree),MDM_GM_GAME_NOTIFY,ASS_UG_USER_SET,0);
	SendWatchData(m_bMaxPeople,&Agree,sizeof(Agree),MDM_GM_GAME_NOTIFY,ASS_UG_USER_SET,0);

	return TRUE;
}

//发送扑克给用户
BOOL CServerGameDesk::SendCard()
{
	if (m_iSendCardPos==52)//((m_iPlayCardCount==2)?100:156)) //发牌完成
	{
		KillTimer(TIME_SEND_CARD);

		NetMessageHead SendFinish;			
		for (int i=0;i<m_bMaxPeople;i++) SendGameData(i,&SendFinish,sizeof(SendFinish),MDM_GM_GAME_NOTIFY,ASS_SEND_FINISH,15);
		SendWatchData(m_bMaxPeople,&SendFinish,sizeof(SendFinish),MDM_GM_GAME_NOTIFY,ASS_SEND_FINISH,0);
	
		
		if (m_iBeenPlayGame >= 1)	///每局由拿到黑桃7先出
		{	
			bool flag = false;
			for (int i = 0;i < 4;i++)
			{
				for (int j = 0;j < 13;j++)
				{
					if (m_iUserCard[i][j] == 0x36) 
					{
						m_iUpGradePeople = i;
						flag = true;
						break;
					}
				}
				if (flag) break;
			}
		}
		
		
		BeginPlayUpGrade();
	

		return TRUE;
	}

	//继续发送扑克(1次发两张)
	for(int i=0;i<13;i++)
	{
		SendCardStruct SendCard;
		SendCard.iCard=m_iUserCard[m_iSendCardPos%4][m_iSendCardPos/m_bMaxPeople];
		SendGameData(m_iSendCardPos%4,&SendCard,sizeof(SendCard),MDM_GM_GAME_NOTIFY,ASS_SEND_CARD,0);
		SendWatchData(m_iSendCardPos%4,&SendCard,sizeof(SendCard),MDM_GM_GAME_NOTIFY,ASS_SEND_CARD,0);
		m_iUserCardCount[m_iSendCardPos%4]++;
		m_iSendCardPos++;
	}

	return TRUE;
}

//用户反牌
bool CServerGameDesk::UserNtCard(BYTE bDeskStation, int iHuaKind, int iCardCount)
{
	
	return FALSE;
}

//发送底牌
BOOL CServerGameDesk::SendBackCard()
{
	
	return TRUE;
}

//用户上交底牌
bool CServerGameDesk::UserGiveBackCard(BYTE bDeskStation, BYTE iBackCard[], int iCardCount)
{
	
	return TRUE;
}

//游戏开始
BOOL CServerGameDesk::BeginPlayUpGrade()
{
	//设置数据
	m_bGameStation=GS_PLAY_GAME;
	m_iBaseOutCount=0;
	m_iOutCardPeople=m_iUpGradePeople;
	m_iFirstOutPeople=m_iUpGradePeople;
	m_iGamePoint=0;

	m_iLastOutPeople = -1;
	IsNewTurn = false;
			
	::memset(m_iTurePoint,0,sizeof(m_iTurePoint));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -