public HW5()
{
InitializeComponent();
}
private void btn_RunMyChioce_Click(object sender, EventArgs e)
{
HandCard hand1 = new HandCard();
CardDeck carddeck = new CardDeck();
carddeck.ResetDeck();
switch (cbox_MyChioce.SelectedIndex)
{
case 0:
carddeck.Shuffle();
hand1.Rest(carddeck);
MessageBox.Show(hand1.MyCardAndCardType());
break;
case 1:
HandCard hand2 = new HandCard();
carddeck.Shuffle();
hand1.Rest(carddeck);
hand2.Rest(carddeck);
string result = hand1.MyCardAndCardType() + hand2.MyCardAndCardType() + WhoWin(hand1,hand2);
MessageBox.Show(result);
break;
case 2:
float[] FrequencyData =new float[10];
for (int pass = 1; pass <= 5000000; pass++)
{
carddeck.ResetDeck();
carddeck.Shuffle();
for (int x = 1; x <= 10; x++)
{
hand1.Rest(carddeck);
FrequencyData[hand1.CardType()] += 1;
}
}
PrintProbability(hand1, FrequencyData);
break;
default:
MessageBox.Show("Error");
break;
}
}
string WhoWin(HandCard player1, HandCard player2)
{
if (player1.CardType() > player2.CardType())
return "Player1 Win";
else if(player1.CardType() < player2.CardType())
return "Player2 Win";
else
return "Draw Game";
}
void PrintProbability(HandCard p,float[] q)
{
string output;
for (int i = 0; i < 10; i++)
{
output = "";
output += p.TypeStr[i];
output += ":";
output += (q[i]/50000000).ToString();
output += "\n";
txt_ShowMessage.AppendText(output);
}
}
public PokerCard[] Cards = new PokerCard[52];
private int topIndex = 0;
public void ResetDeck()
{
for (int i = 0; i <= 51; i++)
{
Cards[i] = new PokerCard((i / 13) + 3, (i % 13) + 1);
}
topIndex = 0;
}
public void Shuffle()
{
Random rand = new Random();
PokerCard Change = new PokerCard();
for (int i = 0; i <= 51; i++)
{
Change = Cards[i];
int position = rand.Next(52);
Cards[i] = Cards[position];
Cards[position] = Change;
}
topIndex = 0;
}
public PokerCard Deal()
{
if (topIndex >= 52)
return null;
return Cards[topIndex++];
}
class PokerCard
{
private int suit;
private int rank;
public PokerCard(int suit, int rank)
{
this.suit = suit;
this.rank = rank;
}
public PokerCard()
{
}
public int Rank
{
get { return rank; }
set { rank = value; }
}
public int Suit
{
get { return suit; }
set { suit = value; }
}
private string RankToStr()
{
switch (Rank)
{
case 1:
return "A";
case 11:
return "J";
case 12:
return "Q";
case 13:
return "K";
default:
return Convert.ToString(Rank);
}
}
private string SuitToUni()
{
string Str_Suit;
switch (Suit)
{
case 3:
Str_Suit = "\u2665";
break;
case 4:
Str_Suit = "\u2666";
break;
case 5:
Str_Suit = "\u2663";
break;
case 6:
Str_Suit = "\u2660";
break;
default:
Str_Suit = "Error";
break;
}
return Str_Suit;
}
public string RankAndSuit()
{
return RankToStr() + SuitToUni();
}
private PokerCard[] Hand = new PokerCard[5];
private enum Type { Error,Highcard, Onepair, Twopair, Threeofkind, Straight, Flush, Fullhouse, Fourofkind, StraightFlush };
public string[] TypeStr = { "Error", "Highcard", "Onepair", "Twopair", "Threeofkind", "Straight", "Flush", "Fullhouse", "Fourofkind", "StraightFlush" };
//發牌和做大小排列
public void Rest(CardDeck p)
{
for (int i = 0; i < 5; i++)
{
Hand[i] = p.Deal();
}
this.Sort();
}
//將5張牌由點數小到大排列
private void Sort()
{
PokerCard temp = new PokerCard();
for (int pass = 0; pass < 5; pass++)
{
for (int i = 0; i < 4; i++)
{
if (Hand[i].Rank > Hand[i + 1].Rank)
{
temp = Hand[i];
Hand[i] = Hand[i + 1];
Hand[i + 1] = temp;
}
}
}
}
//判斷5張手牌所組成得類型
public int CardType()
{
switch (JudgeRepeatHowManyTime())
{
case 0:
if (isFlush())
{
if (isStraight())
return (int)(Type.StraightFlush);
else
return (int)(Type.Flush);
}
else if (isStraight())
return (int)(Type.Straight);
else
return (int)(Type.Highcard);
case 2:
return (int)(Type.Onepair);
case 4:
return (int)(Type.Twopair);
case 5:
return (int)(Type.Threeofkind);
case 7:
return (int)(Type.Fullhouse);
case 8:
return (int)(Type.Fourofkind);
default:
return (int)(Type.Error);
}
}
private bool isFlush()
{
for (int i = 0; i < 4; i++)
{
if (Hand[i].Suit != Hand[i + 1].Suit)
return false;
}
return true;
}
/*isStraight
* 如果單純檢查5張牌是否連續會使[A,10,J,Q,K]出現錯誤
*
* 所以先檢查第一張是否是A
* 是A=====>檢查第2~第5張是否連續。是連續======>檢查第2張是否是2或10。是2或10======>是順子
* 不是連續=====>不是順子
* 不是A======>屏蔽掉[A,10,J,Q,K]這個組合,直接檢查五張牌是否連續。是連續======>是順子
* 不是連續=====>不是順子
*/
private bool isStraight()
{
if (Hand[0].Rank == 1)
{
for (int i = 1; i < 4; i++)
{
if (Hand[i].Rank != (Hand[i + 1].Rank) - 1)
{
return false;
}
}
if (Hand[1].Rank == 2 || Hand[1].Rank == 10)
return true;
else
return false;
}
else
{
for (int i = 0; i < 4; i++)
{
if (Hand[i].Rank != (Hand[i + 1].Rank) - 1)
{
return false;
}
}
return true;
}
}
/*JudgeRepeatHowManyTime
若第i張和第(i+1)張相同,是的話x+1和y+1,並在檢查第(i+1)張和第(i+2)張相同,是的話y+1
若第i張和第(i+1)張不相同,不做任何事
for loop跑完時
若牌型是Highcard,則x=0、y=0
Onepair,則x=1,y=1
Twopair,則x=2、y=2
Threeofkind,則x=2、y=3
Straight,則x=0、y=0
Flush,則x=0、y=0
Fullhouse,則x=3、y=4
Fourofkind,則x=3、y=5
StraightFlush,則x=0、y=0*/
private int JudgeRepeatHowManyTime()
{
int x = 0, y = 0;
for (int i = 0; i < 4; i++)
{
if (Hand[i].Rank == Hand[i + 1].Rank)
{
x += 1;
y += 1;
if (i + 2 > 4) //只有五張牌
continue;
if (Hand[i + 1].Rank == Hand[i + 2].Rank)
{
y += 1;
}
}
}
return x+y;
}
//將5張牌和組成的牌型做成字串
public string MyCardAndCardType()
{
string output = "";
for (int i = 0; i < 5; i++)
{
output += Hand[i].RankAndSuit();
output += " ";
}
output += "\n";
output+=TypeStr[CardType()];
output += "\n";
return output;
}
1. Rest 是指 Reset嗎 …?
回覆刪除2. 你們的執行檔是不是沒有更新? 多次測試後得到機率變化很大,應該是樣本數不足。
3. JudgeRepeatHowManyTime()是蠻有意思的判斷方式,可以直接使用此方法判斷有對的情況。
4. 排序的部分可以再化簡,i < 4可以改成i < 4 - pass