【演算法】用c#實現德州撲克卡牌游戲規則

来源:https://www.cnblogs.com/lan80/archive/2023/08/07/17610735.html
-Advertisement-
Play Games

# Unity IUnityLinkerProcessor Unity IUnityLinkerProcessor是Unity引擎中的一個介面,它允許開發者在Unity項目構建時對代碼進行鏈接處理。這個介面可以用來優化項目構建大小,減少不必要的代碼和資源,提高項目的性能和載入速度。 ## 介面定義 ...


德州撲克是一種牌類游戲,可多人參與,它的玩法是,玩家每人發兩張底牌,桌面依次發5張公共牌,玩家用自己的兩張底牌和5張公共牌自由組合,按大小決定勝負。

使用c#完成功能Hand()以返回手牌類型和按重要性遞減順序排列的等級列表,用於與同類型的其他手牌進行比較,即最佳手牌。

可能的手牌按價值降序排列:

同花順(同一套衣服的連續五個等級)。級別越高越好。

四張(四張等級相同的牌)。平局決勝先是等級,然後是剩餘牌的等級。

滿座(三張等級相同的牌,兩張等級相同)。決勝局首先是三張牌的等級,然後是一對牌的等級。

同花順(五張同花色的牌)。從高到低,級別越高越好。

直(連續五個等級)。級別越高越好。

三張牌(三張等級相同的牌)。決勝局是三張牌中排名第一的,然後是其他排名最高的,然後才是其他排名第二的。

兩對(兩張相同等級的牌,兩張不同等級的牌)。決勝局首先是高牌對的等級,然後是低牌對的級別,然後是剩餘牌的等級。

配對(兩張等級相同的牌)。平局決勝是先是兩張牌的等級,然後是其他三張牌的級別。


演算法實現:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 public static class Edm
  7     {
  8         public static (string type, string[] ranks) Hand(string[] holeCards, string[] communityCards)
  9         {
 10             Card[] allCards = holeCards.Concat(communityCards).Select( x=> new Card(x)).OrderByDescending(card =>card.value).ToArray();
 11             
 12             var rulesChain = createChainOfCommand();
 13             var powerhands = rulesChain.Execute(allCards);
 14             return (powerhands.Item1, getReturnlist(allCards, powerhands.Item2));
 15 
 16         }
 17         public static string[] getReturnlist(Card[] cards, Card[] powerhand)
 18         {
 19             var remainderHand = cards.Where(x => !powerhand.Any(y => y.Equals(x))).Take(5-powerhand.Length);
 20             var result = powerhand.Select(x =>x.number).Distinct().Concat(remainderHand.Select(x=>x.number)).Take(5).Select(x => x.ToString()).ToArray();
 21             return result;
 22         }
 23 
 24         public static Rule createChainOfCommand()
 25         {
 26             Rule straightFlush = new StraightFlushRule();
 27             Rule fourOfAKind = new FourOfAKindRule();
 28             Rule fullHouse = new FullHouseRule();
 29             Rule flush = new FlushRule();
 30             Rule straight = new StraightRule();
 31             Rule threeOfAKind = new ThreeOfAKindRule();
 32             Rule pairTwoPair = new PairTwoPairRule();
 33             straightFlush.SetSuccessor(fourOfAKind);
 34             fourOfAKind.SetSuccessor(fullHouse);
 35             fullHouse.SetSuccessor(flush);
 36             flush.SetSuccessor(straight);
 37             straight.SetSuccessor(threeOfAKind);
 38             threeOfAKind.SetSuccessor(pairTwoPair);
 39             return straightFlush;
 40         }
 41     }
 42     public abstract class Rule
 43     {
 44         private Rule nextRule;
 45         public void SetSuccessor(Rule next)
 46         {
 47             nextRule = next;
 48         }
 49         public virtual (string, Card[]) Execute(Card[] cards)
 50         {
 51             if (nextRule != null)
 52             {
 53                 return nextRule.Execute(cards);
 54             }
 55             return ("nothing", cards.Take(5).ToArray());
 56         }
 57     }
 58 
 59     public class PairTwoPairRule : Rule
 60     {
 61         public override (string, Card[]) Execute(Card[] cards)
 62         {
 63             var pairs = cards.GroupBy(x => x.number).Where(g => g.Count() >= 2).SelectMany(card => card).ToList();
 64             if (pairs.Any())
 65             {
 66                 if(pairs.Count() >= 4)
 67                 {
 68                     return ("two pair", pairs.Take(4).ToArray());
 69                 }
 70                 return ("pair", pairs.Take(2).ToArray());
 71             }
 72             return base.Execute(cards);
 73         }
 74     }
 75     public class ThreeOfAKindRule : Rule
 76     {
 77         public override (string, Card[]) Execute(Card[] cards)
 78         {
 79             var triple = cards.GroupBy(x => x.number).Where(g => g.Count() >= 3).SelectMany(card => card).ToList();
 80             if (triple.Any())
 81             {
 82                 return ("three-of-a-kind", triple.Take(3).ToArray());
 83             }
 84             return base.Execute(cards);
 85         }
 86     }
 87     public class StraightRule : Rule
 88     {
 89         public override (string, Card[]) Execute(Card[] cards)
 90         {
 91             for (int i = 0; i < cards.Length - 4; i++)
 92             {
 93                 List<Card> rtnList = new List<Card>() { cards[i] }; //  "A♥","J♦","10♥" "9♠", "9♥", "8♠", "7♣"
 94                 int counter = 4; 
 95                 int j = i; 
 96                 while (counter >= 0 && j < cards.Length - 1)
 97                 {
 98                     if (cards[j].value - cards[j + 1].value == 1)
 99                     {
100                         rtnList.Add(cards[j + 1]);
101 
102                         if (rtnList.Count() == 5)
103                         {
104                             return ("straight", rtnList.ToArray());
105                         }
106                         counter--;
107                         j++;
108                     }
109                     else if (cards[j].value - cards[j + 1].value == 0)
110                     {
111                         j++;
112                     }
113                     else
114                     {
115                         break;
116                     }
117                 }
118             }
119             return base.Execute(cards);
120         }
121     }
122     public class FlushRule : Rule
123     {
124         public override (string, Card[]) Execute(Card[] cards)
125         {
126             var flush = cards.GroupBy(x => x.suit).Where(g => g.Count() >= 5).SelectMany(card => card).ToList(); 
127             if (flush.Any())
128             {
129                 return ("flush", flush.ToArray());
130             }
131             return base.Execute(cards);
132         }
133     }
134 
135     public class FullHouseRule : Rule
136     {
137         public override (string, Card[]) Execute(Card[] cards)
138         {
139             var triple = new ThreeOfAKindRule();
140             var pair = new PairTwoPairRule();
141 
142             var powerhands = triple.Execute(cards);
143             if (!powerhands.Item1.Equals("nothing"))
144             {
145                 if (powerhands.Item2.Count() == 6) // then 2 three of a kind found
146                 {
147                     return ("full house", powerhands.Item2.Take(5).ToArray());
148                 }
149                 var remainderHand = cards.Where(x => !powerhands.Item2.Any(y => y.Equals(x))).ToArray();
150                 var pairHand = pair.Execute(remainderHand);
151                 if (!pairHand.Item1.Equals("nothing"))
152                 {
153                     var fullhouseHand = powerhands.Item2.Concat(pairHand.Item2.Take(2)).ToArray();
154                     return ("full house", fullhouseHand.Take(5).ToArray());
155                 }
156             }
157             return base.Execute(cards);
158         }
159     }
160     public class FourOfAKindRule : Rule
161     {
162         public override (string, Card[]) Execute(Card[] cards)
163         {
164             var fourOfAKind = cards.GroupBy(x => x.number).Where(g => g.Count() >= 4).SelectMany(card => card).ToList();
165             if (fourOfAKind.Any())
166             {
167                 return ("four-of-a-kind", fourOfAKind.Take(4).ToArray());
168             }
169             return base.Execute(cards);
170         }
171     }
172     public class StraightFlushRule : Rule
173     {
174         public override (string, Card[]) Execute(Card[] cards)
175         {
176             var flushRule = new FlushRule();
177             var straightRule = new StraightRule();
178             var flushHand = flushRule.Execute(cards);
179             var straightHand = straightRule.Execute(flushHand.Item2);
180             if (!straightHand.Item1.Equals("nothing") && !flushHand.Item1.Equals("nothing"))
181             {
182                 return ("straight-flush", straightHand.Item2.Take(5).ToArray());
183             }
184             return base.Execute(cards);
185         }
186     }
187 
188     public class Card{
189         public String number { get; set; }
190         public int value { get; set; }
191         public char suit { get; set; }
192         public Dictionary<char, int> mapping = new Dictionary<char, int>()
193         {
194             { 'A',14 },
195             { 'K',13 },
196             { 'Q',12 },
197             { 'J',11 },
198             { '1', 10}
199         };
200         public Card(String s)
201         {
202             number = (s[0] == '1')? "10": Char.ToString(s[0]);
203             value = mapping.ContainsKey(s[0])? mapping[s[0]]: (int) Char.GetNumericValue(s[0]);
204             suit = s[s.Length-1];
205         }
206         public override string ToString()
207         {
208             return number.ToString();
209         }
210 
211         public bool equals(Card s)
212         {
213             return this.value == s.value && this.suit.Equals(s.suit);
214         }
215     }

測試用例:

  1 namespace Solution
  2 {
  3     using NUnit.Framework;
  4     using System;
  5     using System.Collections.Generic;
  6     using System.Diagnostics;
  7     using System.Linq;
  8     using System.Text;
  9   
 10     [TestFixture]
 11     public class SolutionTest
 12     {
 13         #region Sample Tests
 14     
 15         [Test(Description = "Fixed Tests")]
 16         public void FixedTests()
 17         {
 18             SampleTest(("nothing",         new[] { "A", "K", "Q", "J", "9" }),  new[] { "K♠", "A♦" },  new[] { "J♣", "Q♥", "9♥", "2♥", "3♦" });
 19             SampleTest(("pair",            new[] { "Q", "K", "J", "9" }),       new[] { "K♠", "Q♦" },  new[] { "J♣", "Q♥", "9♥", "2♥", "3♦" });
 20             SampleTest(("two pair",        new[] { "K", "J", "9" }),            new[] { "K♠", "J♦" },  new[] { "J♣", "K♥", "9♥", "2♥", "3♦" });
 21             SampleTest(("three-of-a-kind", new[] { "Q", "J", "9" }),            new[] { "4♠", "9♦" },  new[] { "J♣", "Q♥", "Q♠", "2♥", "Q♦" });
 22             SampleTest(("straight",        new[] { "K", "Q", "J", "10", "9" }), new[] { "Q♠", "2♦" },  new[] { "J♣", "10♥", "9♥", "K♥", "3♦" });
 23             SampleTest(("flush",           new[] { "Q", "J", "10", "5", "3" }), new[] { "A♠", "K♦" },  new[] { "J♥", "5♥", "10♥", "Q♥", "3♥" });
 24             SampleTest(("full house",      new[] { "A", "K" }),                 new[] { "A♠", "A♦" },  new[] { "K♣", "K♥", "A♥", "Q♥", "3♦" });
 25             SampleTest(("four-of-a-kind",  new[] { "2", "3" }),                 new[] { "2♠", "3♦" },  new[] { "2♣", "2♥", "3♠", "3♥", "2♦" });
 26             SampleTest(("straight-flush",  new[] { "J", "10", "9", "8", "7" }), new[] { "8♠", "6♠" },  new[] { "7♠", "5♠", "9♠", "J♠", "10♠" });
 27         }
 28     
 29         private static void SampleTest((string type, string[] ranks) expected, string[] holeCards, string[] communityCards)
 30         {
 31             var actual = Act(holeCards, communityCards);
 32             Verify(expected, actual, holeCards, communityCards);
 33         }
 34     
 35         	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在開始主題前,先看一個 C++ 例子: #include <iostream> struct Data { int a; int b; }; // 註意這裡 struct Data *s; void doSome() { Data k; k.a = 100; k.b = 300; // 註意這裡,會 ...
  • # 整體架構 ![](https://img2023.cnblogs.com/blog/1258602/202308/1258602-20230807095950782-1096148976.jpg) ![](https://img2023.cnblogs.com/blog/1258602/2023 ...
  • 來源:https://blog.csdn.net/qq_14999375/article/details/123309636 ## **前言** K8s + Spring Boot實現零宕機發佈:健康檢查+滾動更新+優雅停機+彈性伸縮+Prometheus監控+配置分離(鏡像復用) ## **配置* ...
  • 在實際應用中,數據集中經常會存在缺失值,也就是某些數據項的值並未填充或者填充不完整。缺失值的存在可能會對後續的數據分析和建模產生影響,因此需要進行處理。 `pandas`提供了多種方法來處理缺失值,例如刪除缺失值、填充缺失值等。刪除缺失值可能會導致數據量減少,填充缺失值則能夠儘量保留原始數據集的完整 ...
  • 實踐過不同前端框架的朋友應該都知道,對於同一個樣式,在不同框架上的表現都會有不同,時時需要做“適配”,在 Blazor 上也不例外。 ...
  • # Unity IPreprocessComputeShaders Unity IPreprocessComputeShaders是Unity引擎中的一個非常有用的功能,它可以讓開發者編譯Compute Shader時自定義哪些操作需要被執行。這個可以幫助開發者更好地控制Compute Shader ...
  • 前言 大家好,我是wacky,最近在工作中遇到一個有趣的問題,同事反饋說WPF中有一個樹形結構的集合,在載入時會直接報堆棧溢出,一直沒時間(懶得)看,導致很久了也沒人解決掉。於是,組長就把這個"艱巨"的任務交給了我。作為新人中的"高手",必然要義不容辭地接受挑戰嘍,廢話不多說,走起。 分析 由於同事 ...
  • LINQ是C#3.0引入的特性,讓處理對象就像執行SQL語句一樣簡單,對於提高C#開發效率有革命性的作用。 對於每個.NET開發者來說,掌握C#的LINQ知識點是非常重要的。LINQ是C#的一個強大的特性,它為數據查詢和操作提供了簡潔、統一的語法,使得數據處理變得更加直觀和靈活。 以下是.NET開發 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...