本文深入解析鬥地主最複雜的核心邏輯:根據出牌張數識別牌型、處理複雜組合 (順子、連對、飛機)、牌組標準化排序、以及大小比較運算子重載。
IsRule(PokerGroup pg) 方法根據 pg.Count 分派判斷邏輯:
排序後檢查點數連續性且無 2、大小王:
bool IsStraight(List cards) {
if (cards.Any(c => c.Point >= 15)) return false; // 2(15)、小王(16)、大王(17) 不能進順子
for (int i = 1; i < cards.Count; i++)
if (cards[i].Point != cards[i-1].Point + 1) return false;
return true;
}
飛機 = 連續三張 + 同數量附帶牌 (單張或對子)。難點在於「帶牌點數可能大於飛機主體」,導致排序後主體不連續。
解法:牌組標準化排序
public static bool operator >(PokerGroup L, PokerGroup R) {
// 類型不同且非炸彈/雙王 → 不可比較
if (L.Type != R.Type && L.Type != PokerGroupType.Bomb && L.Type != PokerGroupType.JokerBomb)
return false;
// 同為炸彈:比較點數
if (L.Type == PokerGroupType.Bomb && R.Type == PokerGroupType.Bomb)
return L[0] > R[0];
// 炸彈大於一切 (除雙王)
if (L.Type == PokerGroupType.Bomb) return true;
if (R.Type == PokerGroupType.Bomb) return false;
// 雙王最大
if (L.Type == PokerGroupType.JokerBomb) return true;
if (R.Type == PokerGroupType.JokerBomb) return false;
// 普通牌型:比較首張牌點數 (已標準化排序)
return L[0] > R[0];
}
IHandValidator,便於擴充 (如加入「四帶二」)。PokerGroup 實例化後不可修改,比較運算回傳新實例。int[18],避免重複 LINQ 查詢。原文提供下載連結已失效,建議參考上述邏輯自行實作或搜尋開源專案 (如 DouDizhuRuleEngine)。