十三张/十三水 最优组合

十三张/十三水 最优组合十三水规则 二到四人对局 一副牌 除去大王 小王 剩下总共 52 张牌 游戏中每人获得 13 张牌 游戏规则每位玩家需将手上的 13 张牌分成头 中 尾三墩牌 头墩三张 中尾墩各五张

大家好,欢迎来到IT知识分享网。

十三水规则: 二到四人对局,,一副牌,除去大王,小王,剩下总共52张牌;游戏中每人获得13张牌; 游戏规则 每位玩家需将手上的13张牌分成头、中、尾三墩牌,头墩三张,中尾墩各五张。 2) 普通牌型(3、5张牌) 同花顺:同门花色中之五张连续牌。若别家也有同花顺时,比顺子大小如牌型全部相同,则平局。 在底墩,按5道计;在中墩,则记10道; 铁支(四条):4张相同的牌。在底墩,按4道计;在中墩,则记8道; 葫芦:由三条加一对组成。若别家也有此牌型,则比三张数字大小。 放中墩,则计3道; 同花:同门花色中之五张杂牌。若遇相同则先比这副牌中最大的一支,如又相同再比第二支、依此类推。如牌型全部相同则平局; 顺子:五张牌都是连续的组合,2、3、4、5、6为最小牌。 10、J、Q、K、A为最大牌,若巧遇别家也有则平局。道:第二大的牌不是9、10、J、Q、K(此为第三大)而是A、2、3、4、5; 三条:三张相同的牌。若遇相同,则比三条部分的数字大小。 在头墩,以三尖刀计; 三尖刀:头墩为三条。 按3道计。 二对:牌型中五张牌由两组两张相同数字的牌所组成。若遇相同则先比这副牌中最大的一对,如又相同再比第二对、如又相同再比单张牌大小。如牌型全部相同则平局。 对子:由两张相同数字的牌组成。若别家也相同则比剩下牌的数字大小,如牌型全部相同则平局。 第一墩是两张带一张,后面是两张带三张; 乌龙(散牌):组不出任何牌型。只比数字大小,其比法与同花相同。若两家从大到小都一样,则平局; 

后台逻辑实现思路:
一手牌是13张,要组成头墩、中墩、尾墩,每墩可能分别是同花顺、铁枝……对子、乌龙等,要保证尾墩 >= 中墩 > 头墩。可以通过遍历所有类型,获取指定的尾墩组合后,对剩余的牌再进行组合,优先使用递归。
伪代码:

// CCombinateCards 组合类 // ST_ONE_HAND_COMBINATION 一手牌组合 // ST_CARD_SENTENCE 一墩牌,三张或五张 typedef std::vector<ST_ONE_HAND_COMBINATION> COneHandArray; bool CCombinateCards::CombinateSpecifiedStyle(COneHandArray &arrTraverseArray,BYTE byType) { CCombinateCards clsGroup = *this; if (clsGroup.m_nCount == 0) { return true; } int iStcTypeCount = 0; int iSentence = 0; int iPos = clsGroup.m_nCount / MAX_SENTENCE_LENGTH; // 头、中、尾 int iLength = iPos == EN_LOCALTION_HEAD? MIN_SENTENCE_LENGTH : MAX_SENTENCE_LENGTH; bool bTail = clsGroup.m_nCount == MAX_CARDS_EVERYONE; std::vector<ST_CARD_SENTENCE> arrSentence; if (byType >= EN_ST_TONGHUASHUN && m_nCount >= MAX_SENTENCE_LENGTH) { int iTonghuashunCount = NormalTonghuashun(arrSentence); if (byType == EN_ST_TONGHUASHUN && bTail && iTonghuashunCount == 0) { return false; } for (;iSentence < iTonghuashunCount;++iSentence) // 如果有同花顺,则将该顺子从手牌中删除,拼凑头和中 { CCombinateCards clsGroupTmp = clsGroup; if (!clsGroupTmp.DeleteSentence(arrSentence[iSentence],iLength)) // 删除该句子,获得剩余的牌 { return false; } if (bTail) // 如果是尾墩,应该新建一个 ST_ONE_HAND_CARD ,如果是中或头,则往 arrTraverseArray 的最后一个 ST_ONE_HAND_CARD 中添加 { ST_ONE_HAND_COMBINATION stOneHand; stOneHand.SetLocationCard(EN_LOCALTION_TAIL,arrSentence[iSentence]); arrTraverseArray.push_back(stOneHand); } else { // 如果是取中墩,且已经有一个中墩了,再新建一个 ST_ONE_HAND_COMBINATION ,尾墩不需要新建。如果是尾墩则直接往 arrTraverseArray 里面设置 if (iPos == EN_LOCALTION_MID && arrTraverseArray[arrTraverseArray.size() - 1].m_astSentence[EN_LOCALTION_MID].IsValidSentence()) { ST_ONE_HAND_COMBINATION stOneHand; stOneHand.m_astSentence[EN_LOCALTION_TAIL] = arrTraverseArray[arrTraverseArray.size() - 1].m_astSentence[EN_LOCALTION_TAIL]; arrTraverseArray.push_back(stOneHand); } arrTraverseArray[arrTraverseArray.size() - 1].SetLocationCard(iPos,arrSentence[iSentence]); } clsGroupTmp.CombinateSpecifiedStyle(arrTraverseArray,EN_ST_TONGHUASHUN); // 此处获得的是以同花顺为尾墩的组合 } if (iTonghuashunCount > 0 && bTail) { return true; } } if (byType >= EN_ST_TIEZHI) { int iTiezhiCount = NormalTiezhi(arrSentence); // 到这里肯定没有同花顺了,此时从剩余的单牌中找一个放入 arrSentence 中 if (byType == EN_ST_TIEZHI && bTail && iTiezhiCount == 0) { return false; } for (iSentence = 0;iSentence < iTiezhiCount;++iSentence) // 如果有铁枝,则将该铁枝从手牌中删除,拼凑头和中 { CCombinateCards clsGroupTmp = clsGroup; if (!clsGroupTmp.DeleteSentence(arrSentence[iSentence],arrSentence[iSentence].m_iSentenceLen)) // 删除该句子,获得剩余的牌 { return false; } if (bTail) // 如果是尾墩,应该新建一个 ST_ONE_HAND_CARD ,如果是中或头,则往 arrTraverseArray 的最后一个 ST_ONE_HAND_CARD 中添加 { ST_ONE_HAND_COMBINATION stOneHand; stOneHand.SetLocationCard(EN_LOCALTION_TAIL,arrSentence[iSentence]); arrTraverseArray.push_back(stOneHand); } else { // 如果是取中墩,且已经有一个中墩了,再新建一个 ST_ONE_HAND_COMBINATION ,尾墩不需要新建。如果是尾墩则直接往 arrTraverseArray 里面设置 if (iPos == EN_LOCALTION_MID && arrTraverseArray[arrTraverseArray.size() - 1].m_astSentence[EN_LOCALTION_MID].IsValidSentence()) { ST_ONE_HAND_COMBINATION stOneHand; stOneHand.m_astSentence[EN_LOCALTION_TAIL] = arrTraverseArray[arrTraverseArray.size() - 1].m_astSentence[EN_LOCALTION_TAIL]; arrTraverseArray.push_back(stOneHand); } arrTraverseArray[arrTraverseArray.size() - 1].SetLocationCard(iPos,arrSentence[iSentence]); } clsGroupTmp.CombinateSpecifiedStyle(arrTraverseArray,EN_ST_TIEZHI); // 此处是以铁枝为尾墩的组合 } if (iTiezhiCount > 0 && bTail) { return true; } } // 中间其他类型省略 ... int iWulongCount = NormalWulong(arrSentence); //if (byType == EN_ST_WULONG/* && bTail */&& iWulongCount == 0) // 乌龙不会出现在尾墩 //{ 
    // return false; //} for (iSentence = 0;iSentence < iWulongCount;++iSentence) // 如果有葫芦,则将该葫芦从手牌中删除,拼凑头和中 { CCombinateCards clsGroupTmp = clsGroup; if (!clsGroupTmp.DeleteSentence(arrSentence[iSentence],iLength)) // 删除该句子,获得剩余的牌 { return false; } if (bTail) // 如果是尾墩,应该新建一个 ST_ONE_HAND_CARD ,如果是中或头,则往 arrTraverseArray 的最后一个 ST_ONE_HAND_CARD 中添加 { ST_ONE_HAND_COMBINATION stOneHand; stOneHand.SetLocationCard(EN_LOCALTION_TAIL,arrSentence[iSentence]); arrTraverseArray.push_back(stOneHand); } else { // 如果是取中墩,且已经有一个中墩了,再新建一个 ST_ONE_HAND_COMBINATION ,尾墩不需要新建。如果是尾墩则直接往 arrTraverseArray 里面设置 if (iPos == EN_LOCALTION_MID && arrTraverseArray[arrTraverseArray.size() - 1].m_astSentence[EN_LOCALTION_MID].IsValidSentence()) { ST_ONE_HAND_COMBINATION stOneHand; stOneHand.m_astSentence[EN_LOCALTION_TAIL] = arrTraverseArray[arrTraverseArray.size() - 1].m_astSentence[EN_LOCALTION_TAIL]; arrTraverseArray.push_back(stOneHand); } arrTraverseArray[arrTraverseArray.size() - 1].SetLocationCard(iPos,arrSentence[iSentence]); } clsGroupTmp.CombinateSpecifiedStyle(arrTraverseArray,EN_ST_WULONG); //  } return true; } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/147614.html

(0)
上一篇 2025-04-06 14:10
下一篇 2025-04-06 14:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信