自己写的控制台下的斗地主~
本来是分好几个源文件的,为了方便查看,特意合在一起了~程序代码:
#include <iostream> #include <ctime> using namespace std; #define NULL 0 typedef struct tagNODE { bool bOut; //默认为false int iSize;//牌的大小 int iValue;//牌的值 1-54 char cPai[20]; //棋牌字符 tagNODE * pNext;//后驱指针 }T_NODE; class CPaiList { protected: T_NODE * m_pHead; //头节点 T_NODE * m_pTail; public: CPaiList(); ~CPaiList(); bool ADDNODE(char * pszPai , int iSize , int iValue);//创建棋牌 bool DELNODE(int iSequence);//删除已出棋牌 void ShowList(); T_NODE * GETNODE(); }; class CPaiShow : public CPaiList { public: void ADDpai();//随机抽取13颗牌(不算大小花) bool DELpai(int iValue , char * szOut);//出牌即删牌 bool Choose(int iValue);//选择牌 bool Cancel(int iValue);//取消选择牌 int ShowPai();//出牌 }; CPaiList::CPaiList() { m_pHead = NULL; m_pTail = NULL; } CPaiList::~CPaiList()//释放空间 { T_NODE * pCulNode = m_pHead; T_NODE * pPreNode; while (pCulNode) { pPreNode = pCulNode->pNext; delete pCulNode; pCulNode = pPreNode; } } bool CPaiList::ADDNODE(char * pszPai , int iSize , int iValue)//创建牌 { T_NODE * pNew = new T_NODE; if (pNew == NULL) { return false; } strcpy(pNew->cPai , pszPai); pNew->iSize = iSize; pNew->iValue = iValue; pNew->pNext = NULL; pNew->bOut = false; if (m_pHead == NULL) { m_pHead = pNew; } else { m_pTail->pNext = pNew; } m_pTail = pNew; return true; } bool CPaiList::DELNODE(int iValue)//删除牌 { T_NODE * pCulNode = m_pHead; T_NODE * pPreNode = m_pHead; while (pCulNode) { if (pCulNode->iValue == iValue) { if (pCulNode == m_pHead)//当前节点等于头节点 { m_pHead = pCulNode->pNext; } else { pPreNode->pNext = pCulNode->pNext; } delete pCulNode; return true; } pPreNode = pCulNode; pCulNode = pCulNode->pNext; } return false; } void CPaiList::ShowList() { T_NODE * pCulNode = m_pHead; while(pCulNode) { cout << pCulNode->cPai << "(" << pCulNode->iValue << ")" << '\t' ; pCulNode = pCulNode->pNext; } } T_NODE * CPaiList::GETNODE() { return m_pHead; } #define ROW 4 #define COL 15 void CPaiShow::ADDpai() { char * pszPaiA[ROW] = {"红桃","黑桃","方块","草花"}; char * pszPaiB[COL] = {"3","4","5","6","7","8","9","10","J","Q","K","A","2","小头","大头"}; char szTmp[10]; unsigned iPaiA = 0, iPaiB = 0; srand( time(0) ); int iValue; int iSize = 13;//随机抽取13颗牌 int iFlag = 1;//判断是否重复 while(iSize) { iPaiA = rand() % ROW; iPaiB = rand() % COL; if (iPaiB != 13 && iPaiB != 14)//求扑克牌的值1-52 { int iTmp = 0; for (int i = 1; i <= 4; ++i) { for (int j = 1; j <= 13; ++j) { ++iTmp; if ((iPaiA + 1) == i && (iPaiB + 1) == j) { iValue = iTmp; } } } strcpy(szTmp , pszPaiA[iPaiA]); strcat(szTmp , pszPaiB[iPaiB]); } else { iValue = iPaiB + 40; strcpy(szTmp , pszPaiB[iPaiB]); } //-------------判断各节点中有无重复的数据,无则继续----------------------------- T_NODE * pCulNode = m_pHead; if (pCulNode == NULL) { if (iPaiB != 13 && iPaiB != 14) { --iSize; } ADDNODE(szTmp , iPaiB , iValue); continue; } while (pCulNode != NULL) { if (strcmp(pCulNode->cPai , szTmp) == 0)//如果有重复的牌 { iFlag = 0; } pCulNode = pCulNode->pNext; } if (iFlag==1) { if (iPaiB != 13 && iPaiB != 14) { --iSize; } ADDNODE(szTmp , iPaiB , iValue);//添加牌 //--------------------------------------------------------------- T_NODE * pPreNode = m_pHead;//此处将牌按从大到小的顺序排列起来 char szPaiTmp[10]; int iSizeTmp; int iValueTmp; while (pPreNode) { T_NODE * pCulNode = m_pHead; while (pCulNode) { if (pPreNode->iSize > pCulNode->iSize)//如果有前一张牌比后一张牌大,就替换掉 { strcpy(szPaiTmp , pCulNode->cPai); iSizeTmp = pCulNode->iSize; iValueTmp = pCulNode->iValue; //-------------------- strcpy(pCulNode->cPai , pPreNode->cPai); pCulNode->iSize = pPreNode->iSize; pCulNode->iValue = pPreNode->iValue; //-------------------- strcpy(pPreNode->cPai , szPaiTmp); pPreNode->iSize = iSizeTmp; pPreNode->iValue = iValueTmp; } pCulNode = pCulNode->pNext; } pPreNode = pPreNode->pNext; } //----------------------------------------- } iFlag=1;//如果有重复的牌此处重设为1 } } //----------------水平分割线--------------------------------- bool CPaiShow::Choose(int iValue)//选牌 { T_NODE * pCulNode = m_pHead; while (pCulNode)//把选中的牌做记号 { if (pCulNode->iValue == iValue) { pCulNode->bOut = true; return true; } pCulNode = pCulNode->pNext; } return false; } bool CPaiShow::Cancel(int iValue) { T_NODE * pCulNode = m_pHead; while (pCulNode)//取消选中的牌 { if (pCulNode->iValue == iValue && pCulNode->bOut == true) { pCulNode->bOut = false; return true; } pCulNode = pCulNode->pNext; } return false; } int CPaiShow::ShowPai()//判断选中的牌是否符合标准 { T_NODE * pCulNode = m_pHead; T_NODE * pTwoNode = m_pHead; int iTmpA = 0 , iTmpB = 0 , iTmpC = 0 , iCount = 0; while (pCulNode)//用每张牌来判断 { if (pCulNode->bOut == true) { ++iCount;//选中的牌数 T_NODE * pPreNode = pCulNode; while (pPreNode) { if (pPreNode->bOut == true && pPreNode != pCulNode) { if (pCulNode->iSize == pPreNode->iSize )//判断选中的牌中有几个对子 { ++iTmpA; } if (pCulNode->iSize - pPreNode->iSize == 1)//前一张比后一张小1,判断单顺子 { ++iTmpB; } if (pTwoNode->iSize != pCulNode->iSize && pCulNode->iSize - pPreNode->iSize == 1)//判断双顺子 { ++iTmpC; } } pPreNode = pPreNode->pNext; } } pTwoNode = pCulNode; pCulNode = pCulNode->pNext; } //----------------------------------------------- int iTmp = 0; if (iCount == 1)//单颗 { iTmp = 1; } if (iCount == 2 && iTmpA == 1)//两张一对 { iTmp = 2; } if (iCount == 4 && iTmpA == 3)//三带一 { iTmp = 3; } if (iCount == 4 && iTmpA == 6)//四颗一样的是炸弹 { iTmp = 4; } if (iCount >= 5 && iTmpB + 1 == iCount)//单顺子必须大等于五颗牌 { iTmp = 5; } if (iCount >= 4 && iTmpC + 2 == iCount)//双顺子必须大等于四颗牌 { iTmp = 6; } return iTmp; } int main() { int iValue; char szCancel[2]; char szOut[2]; CPaiShow obj; obj.ADDpai(); obj.ShowList(); while (1) { cout << endl; cout << "按括号内的数字输入您要选择的牌:"; cin >> iValue; if (obj.Choose(iValue)) { cout << "选择成功" << endl; } else { cout << "对不起,没有此牌" << endl; } cout << "是否要取消已选择的牌?是按Y,否则请按其他键:"; cin >> szCancel; if (strcmp(szCancel , "Y") == 0 || strcmp(szCancel , "y") == 0) { cout << "请输入您要取消的牌:"; cin >> iValue; if (obj.Cancel(iValue)) { cout << "已取消" << endl; } else { cout << "对不起,您未选择此牌" << endl; } } T_NODE * pCulNode = obj.GETNODE();//显示 while (pCulNode) { if (pCulNode->bOut == true) { cout << "选中的牌有:" << pCulNode->cPai << endl; } pCulNode = pCulNode->pNext; } cout << "按Y键确认出牌,否则请按其他键:"; cin >> szOut; if (strcmp(szOut , "Y") == 0 || strcmp(szOut , "y") == 0) { int iTmp = obj.ShowPai(); if (iTmp) { cout << "出牌成功" << endl; switch (iTmp) { case 1 : cout << "您出的是单张" << endl; break; case 2 : cout << "您出的是对子" << endl; break; case 3 : cout << "您出的是三带一" << endl; break; case 4 : cout << "您出的是炸弹" << endl; break; case 5 : cout << "您出的是单顺子" << endl; break; case 6 : cout << "您出的是双顺子" << endl; break; } } else { cout << "选牌不对,请重选~" << endl; } //---------------------这里用不用单独写个函数?----------------------------------------- T_NODE * pCulNode = obj.GETNODE(); T_NODE * pPreNode; while (pCulNode) { pPreNode = pCulNode->pNext; if (pCulNode->bOut) { obj.DELNODE(pCulNode->iValue); } pCulNode = pPreNode; } //---------------------------------------------------------------------------------- } if (obj.GETNODE() == NULL)//如果牌都出光了,就退出游戏 { cout << "游戏结束" << endl; break; } obj.ShowList(); } return 0; }