用C++写的基于MFC界面的斗地主小游戏源码,内含详细注释,附带了简单的AI出牌规则,放出来供大家参考交流。vs2010编写,vs2015测试可用,理论上vs05及以上都可正常编译运行。
void Judge::MainFlow()
{
switch(DataCenter::Instance().GetPlayState())
{
case EM_LandHolderBorn_PlayState:
{
//先检查是否已经问完了
//遍历玩家检查是否已经询问过了,如果已经都问过了,则设置叫分最高的为地主
BOOL bAllAsked = TRUE;//是否已经询问完了
vector
& vecPlayer = DataCenter::Instance().GetPlayerList();
for (UINT i = 0; i < vecPlayer.size(); i++)
{
//统计当前最高分
if (vecPlayer[i].GetLandOwerScore() > m_nCurHighstScore)
{
m_nCurHighstScore = vecPlayer[i].GetLandOwerScore();
m_pToBeLandOwer = &vecPlayer;[i];
}
if (vecPlayer[i].GetLandOwerScore() < 0)
{
bAllAsked = FALSE;
}
}
//如果已经全部问过了,则设置当前最高分的为地主
if (bAllAsked)
{
m_pToBeLandOwer->SetLandOwer(TRUE);
}
//然后根据情况执行询问流程
//如果地主已经产生,则跳入下一阶段
if (NULL != DataCenter::Instance().GetLandOwner())
{
m_pCurPlayer = NULL;
DataCenter::Instance().SetPlayState(EM_WaitPlayer_PlayState);
MainFlow();
return;
}
//如果当前player为空,设置当前player为地主牌得主
if (m_pCurPlayer == NULL)
{
m_pCurPlayer = DataCenter::Instance().GetLandOwnerCardHolder();
}
//对当前玩家执行地主问询
ASSERT(m_pCurPlayer);
m_pCurPlayer->ExcuteCallLandOwer();
}
break;
case EM_WaitPlayer_PlayState:
{
//如果游戏已经结束,则执行结束逻辑
BOOL bLandOwerWin = FALSE;
if (DataCenter::Instance().IsOver(bLandOwerWin))
{
if (bLandOwerWin)
{
AfxMessageBox(_T("地主赢了!"));
}
else
{
AfxMessageBox(_T("佃户赢了!"));
}
DataCenter::Instance().SetPlayState(EM_WaitToStart_PlayState);
//将所有玩家明牌
DataCenter::Instance().ShowAllPlayerCard();
RefreshView();
return;
}
//如果是出牌阶段而当前player为空,设置当前player为地主,并发予底牌
if (m_pCurPlayer == NULL)
{
m_pCurPlayer = DataCenter::Instance().GetLandOwner();
DataCenter::Instance().SendOutBottomCard();
RefreshView();
}
ASSERT(m_pCurPlayer);
m_pCurPlayer->ExcuteCallCardPlay();
}
break;
}
}
void Judge::CurPlayerCallScore(int nScore)
{
if (m_pCurPlayer == NULL)
{
ASSERT(FALSE);
return;
}
//将玩家选择的分数设置给玩家
m_pCurPlayer->SetLandOwerScore(nScore);
//如果当前玩家为空,直接返回
if(m_pCurPlayer == NULL)
{
return;
}
if (nScore == 3)
{
//如果玩家叫了三分,直接设为地主
m_pCurPlayer->SetLandOwer(TRUE);
}
else
{
//玩家叫的不是三分,则记下玩家叫的分数
m_pCurPlayer->SetLandOwerScore(nScore);
}
if (nScore == 0)
{
CString strWord;
strWord.Format(_T("不叫"));
m_pCurPlayer->Say(strWord);
}
else
{
CString strWord;
strWord.Format(_T("%d分"), nScore);
m_pCurPlayer->Say(strWord);
}
//玩家叫分后隐藏叫地主按钮
Judge::Instance().ShowCallLandOwerBtn(FALSE);
//切换到下一个玩家,流程继续
SwitchToNextPlayer();
MainFlow();
}
1