Form1.cs
public partial class Form1 : Form
{
CardDeck Deck = new CardDeck();
HandCardType[] Players = new HandCardType[5];
HandCardType TestPlayer;
double[] TypeTimes = new double[9];
public Form1()
{
InitializeComponent();
}
private void Btn_Confirm_Click(object sender, EventArgs e)
{
Deck.Shuffle();
switch (Cbox_Cards.SelectedIndex)
{
case 0:
if (Players[0] == null)
Players[0] = new HandCardType("Player1");
HandCardType.PlayerNum = 1;
Players[0].LicensingCard(Deck);
Players[0].Sort();
MessageBox.Show( HandCardType.ShowDeck(Players));
break;
case 1:
if (Players[0] == null)
{
Players[0] = new HandCardType("Player1");
Players[1] = new HandCardType("Player2");
}
if (Players[1] == 1)
Players[1] = new HandCardType("Player2");
HandCardType.PlayerNum = 2;
Players[0].LicensingCard(Deck);
Players[0].Sort();
Players[1].LicensingCard(Deck);
Players[1].Sort();
MessageBox.Show(HandCardType.ShowDeck(Players)+"Winner is "+Winner());
break;
case 2:
string Display = "";
if (Players == null)
{
Players = new HandCardType[1];
Players[0] = new HandCardType("Player1");
}
for (int i = 0; i < 9; i++)
{
TypeTimes[i] = 0;
}
for (int i = 0; i < 5000000; i++)
{
for (int j = 0; j < 10; j++)
{
Players[0].LicensingCard(Deck);
Players[0].Sort();
Players[0].Check();
TypeTimes[Players[0].TypeWeight]++;
}
Deck.Shuffle();
}
for (int i = 0; i < 9; i++)
{
Display+=HandCardType.Type[i]+" 機率為 "+(TypeTimes[i]/50000000).ToString()+"\n";
}
MessageBox.Show(Display);
break;
default:
break;
}
}
private void btn_test_Click(object sender, EventArgs e)//測試用
{
HandCardType.PlayerNum = 1;
string TestDisplay = "";
if (TestPlayer == null)
{
TestPlayer = new HandCardType("Test");
for (int i = 0; i < 5; i++)
{
TestPlayer.handcard[i] = new PokerCardUseUnitCode();
}
}
TestPlayer.handcard[0].Rank = 13;
TestPlayer.handcard[0].Suit = 5;
TestPlayer.handcard[1].Rank = 11;
TestPlayer.handcard[1].Suit = 6;
TestPlayer.handcard[2].Rank = 1;
TestPlayer.handcard[2].Suit = 4;
TestPlayer.handcard[3].Rank = 10;
TestPlayer.handcard[3].Suit = 3;
TestPlayer.handcard[4].Rank = 11;
TestPlayer.handcard[4].Suit = 3;
TestPlayer.Sort();
for (int i = 0; i < 5; i++)
{
TestDisplay += TestPlayer.handcard[i].RankToStr() + TestPlayer.handcard[i].SuitToUnicode() + " ";
}
TestDisplay += TestPlayer.Check();
if (TestPlayer.RankWeight == 1)
TestPlayer.RankWeight = 14;
TestPlayer.AllWeight = TestPlayer.TypeWeight * 1000 + TestPlayer.RankWeight * 10 + TestPlayer.SuitWeight;
TestDisplay += TestPlayer.AllWeight.ToString();
MessageBox.Show(TestDisplay);
}
public string Winner()
{
int index = 0;
for (int i = 0; i < Players.Length; i++)
{
if (Players[i].RankWeight == 1)
Players[i].RankWeight = 14;
Players[i].AllWeight = Players[i].TypeWeight * 1000 + Players[i].RankWeight * 10 + Players[i].SuitWeight;
if (Players[i].AllWeight > Players[index].AllWeight)
index = i;
}
return Players[index].name;
}
}
HandCardType.cs class HandCardType
{
public PokerCardUseUnitCode[] handcard = new PokerCardUseUnitCode[5];
public static int PlayerNum = 0;
public string name = "";
public int TypeWeight = 0;
public int RankWeight = 0;
public int SuitWeight = 0;
public int AllWeight = 0;
public HandCardType(string name)
{
this.name = name;
}
public static string[] Type = { "Zilch", "One Pair", "Two Pairs", "Three of a kind", "Straight", "Flush", "Fullhouse", "Four of a Kind", "Straight Flush" };
public void LicensingCard(CardDeck Deck)
{
TypeWeight = 0;
RankWeight = 0;
SuitWeight = 0;
AllWeight = 0;
for (int i = 0; i < 5; i++)
{
handcard[i] = Deck.Cards[Deck.Topindex];
Deck.Topindex++;
}
}
public void Sort()
{
PokerCardUseUnitCode temp;
int index;
for (int i = 4; i>0; i--)
{
index = i;
for (int j = i ; j >=0; j--)
{
if (handcard[j].Rank == 1)
{
index = j;
break;
}
if (handcard[j].Rank > handcard[index].Rank)
index = j;
}
temp = handcard[i];
handcard[i] = handcard[index];
handcard[index] = temp;
}
}
public string Check()//判斷牌型
{
switch (PairsNum())
{
case 0:
if (isStaright())
{
if (isFlush())
TypeWeight = 8; //同花順
else
TypeWeight = 4; //順子
}
else if (isFlush())
{
TypeWeight = 5; //同花
RankWeight = handcard[4].Rank;
SuitWeight = handcard[4].Suit;
}
else
{
TypeWeight = 0;//無王
RankWeight = handcard[4].Rank;
SuitWeight = handcard[4].Suit;
}
break;
case 1:
TypeWeight = 1;//一對
break;
case 2:
if (isThreeOfkind())//三條
{
TypeWeight = 3;
RankWeight = handcard[2].Rank;
}
else
TypeWeight = 2;//兩對
break;
case 3:
if (isFourOfKind())//四條
TypeWeight = 7;
else
TypeWeight = 6;//葫蘆
RankWeight = handcard[2].Rank;
break;
default:
break;
}
return Type[TypeWeight];
}
public bool isFlush()//同花
{
for (int i = 1; i < handcard.Length; i++)
{
if (handcard[i - 1].Suit != handcard[i].Suit)
return false;
}
RankWeight = handcard[4].Rank;
SuitWeight = handcard[4].Suit;
return true;
}
public bool isStaright()//順子
{
if (handcard[0].Rank == 10 && handcard[1].Rank == 11 && handcard[2].Rank == 12 && handcard[3].Rank == 13 && handcard[4].Rank == 1)
{
RankWeight = handcard[4].Rank;
SuitWeight = handcard[4].Suit;
return true;
}
if (handcard[0].Rank == 2 && handcard[1].Rank == 3 && handcard[2].Rank == 4 && handcard[3].Rank == 5 && handcard[4].Rank == 1)
{
RankWeight = handcard[3].Rank;
SuitWeight = handcard[3].Suit;
return true;
}
for (int i = 1; i < handcard.Length; i++)
{
if ((handcard[i].Rank - handcard[i - 1].Rank) != 1)
return false;
}
RankWeight = handcard[4].Rank;
SuitWeight = handcard[4].Suit;
return true;
}
public bool isFourOfKind()//四條
{
if ((handcard[0].Rank == handcard[3].Rank || handcard[1].Rank == handcard[4].Rank))
{
RankWeight = handcard[2].Rank;
return true;
}
else
return false;
}
public bool isFullhouse()//葫蘆
{
if ((handcard[0].Rank == handcard[2].Rank && handcard[3].Rank == handcard[4].Rank) || (handcard[2].Rank == handcard[4].Rank && handcard[0].Rank == handcard[1].Rank))
{
RankWeight = handcard[2].Rank;
return true;
}
else
return false;
}
public bool isThreeOfkind()//三條
{
if ((handcard[0].Rank == handcard[2].Rank || handcard[1].Rank == handcard[3].Rank || handcard[2].Rank == handcard[4].Rank))
{
RankWeight = handcard[2].Rank;
return true;
}
else
return false;
}
public int PairsNum()//對子數量
{
int Num = 0;
for (int i = 0; i < 4; i++)
{
if (handcard[i].Rank == handcard[i + 1].Rank)
{
RankWeight = handcard[i].Rank;
SuitWeight = Math.Max(handcard[i].Suit, handcard[i+1].Suit);
Num++;
}
}
return Num;
}
public static string ShowDeck(HandCardType[] player)
{
string Display = "";
for (int j = 0; j < PlayerNum; j++)
{
Display += player[j].name + "\n";
for (int i = 0; i < 5; i++)
{
Display += player[j].handcard[i].RankToStr() + player[j].handcard[i].SuitToUnicode() + " ";
}
Display += "\n";
Display += player[j].Check() + "\n\n";
}
return Display;
}
}
CardDeck.cs class CardDeck
{
public PokerCardUseUnitCode[] Cards;
public int Topindex = 0;
public CardDeck()
{
Cards = new PokerCardUseUnitCode[52];
CreateDeck();
ResetDeck();
}
public void CreateDeck() //產生出52個PokerCardUseUnitCode的物件
{
for (int i = 0; i < 52; i++)
{
Cards[i] = new PokerCardUseUnitCode();
}
}
public void ResetDeck() //牌堆回復原始狀態
{
for (int i = 0; i < 52; i++)
{
Cards[i].Suit = i / 13 + 3;
Cards[i].Rank = i % 13 + 1;
}
}
public void Shuffle() //洗牌
{
Random rand = new Random();
PokerCardUseUnitCode temp;
int T;
for (int i = 0; i < 52; i++)
{
T = rand.Next(52);
temp = Cards[i];
Cards[i] = Cards[T];
Cards[T] = temp;
}
Topindex = 0;
}
public void ResetDeckwithRank()
{
for (int i = 0; i < 52; i++)
{
Cards[i].Suit = i % 4 + 3;
Cards[i].Rank = i /4 + 1;
}
}
}
PokerCardUseUnitCode.cs class PokerCardUseUnitCode
{
public int Suit; //花色
public int Rank; //點數
public string RankToStr() //將點數轉為字串
{
string RankString;
switch (Rank)
{
case 1:
RankString = "A";
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
RankString = Rank.ToString();
break;
case 11:
RankString = "J";
break;
case 12:
RankString = "Q";
break;
case 13:
RankString = "K";
break;
default:
RankString = "error";
break;
}
return RankString;
}
public string SuitToUnicode() //將花色轉為 UnitCode 字元碼
{
string[] SuitUnitcode = new string[4] { "\u2663", "\u2666", "\u2665", "\u2660" }; //梅花 方塊 紅心 黑桃
return SuitUnitcode[Suit - 3];
}
}投影片
1. Form1看起來簡單乾淨,而且各項目都寫得蠻清楚。
回覆刪除2. Form1的Winner()中,AllWeight的概念很有意思,可以省去了許多巢狀判斷。不過畢竟AllWeight與TypeWeight、RankWeight、SuitWeight相關,因此寫成HandCardType的方法會更佳。
public int AllWeight()
{
return PTypeWeight * 1000 + RankWeight * 10 + SuitWeight;
}
3. 判斷RankWeight、SuitWeight的方式還不錯。
[第六組]
回覆刪除Form1.cs - 26行 if (Players[0] == null)
這邊為什麼只判斷Player[0]之後就可以new兩個Player?
然後再 31行 if (Players[1] == 1)
反而這樣就new出Player[1]? 會不會是你們打錯?
不知道你們是不是這樣想:"先檢查P0,不存在就把P0,P1一起new出來;如果P0存在,那就檢查P1,P1若不存在,那就只要new出P1即可".如果是這樣,建議你們用
if(Players[0] == null)...else if(Players[1] == null)...
這樣在第一個if把P0,P1 new出來後,就不必再檢查一次P1.
HandCardType.cs
11行 public HandCardType(string name)
這個建構子只有把外部傳進的name指派到本身的name.
如果是我的話,我會把它改成傳進int,然後這樣寫
public HandCardType(int PlayerNum)
{
name = "Player" + Convert.ToSrting(PlayerNum);
}
這樣要宣告多個Player時,比較容易用for迴圈宣告.(原本的寫法還是可以,只是在form1.cs那邊就不太好寫.)
另外,因為這個參數與name有關,思考一下如何屬性去處理或許更好.
一副手牌最好就當作一個物件,這樣HandCardType這個類別內的ShowDeck就不必一次處理多副手牌.
要顯示出多副手牌的話,只需要在Form1.cs將手牌名稱改成陣列:Player[].之後使用for迴圈配合Player[i]分批印出多副手牌應該會比較好.
Players[1] 的部分的確是打錯,你提出的方式確實比較好。
刪除name的部分,當時是想說玩家可以輸入各式各樣的名稱所以才這樣寫,類似玩遊戲的感覺
ShowDeck也是因為遊戲中玩家要攤牌應該要一起攤,所以才採用這樣的寫法。
這2部分只是個人愛玩,所以才用玩遊戲的想法寫,我也了解並不是這樣寫真的比較好。