簡報
Hand.cs (手牌)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace st_hw05
{
class Hand
{
private PokerCard[] pokerHand = null;
private int numOfSameRank = 0; //點數相同的張數
private int numOfPairs = 0;
private PokerCard maxSingle = null; //單張的最大值
private PokerCard maxKind = null; //多張的最大值
private int typeNum;
private string[] type = { "Zilch", "One Pair", "TwoPairs", "Three of a Kind",
"Straight", "Flush", "FullHouse", "Four of a Kind", "StraightFlush"};
enum CardTypes
{
Zilch = 0, OnePair, TwoPairs, ThreeOfAKind, Straight, Flush, FullHouse, FourOfAKind, StraightFlush
};
public Hand(ref CardDeck CardDeck, int Number) //建構子_1: Number:第N副手牌
{
pokerHand = new PokerCard[5];
for (int i = 0; i < 5; i++)
{
pokerHand[i] = CardDeck.Cards[(Number - 1) * 5 + i];
}
typeNum = JudgeType();
}
public Hand() //建構子_2: 只new出記憶體,不必配置內容
{
pokerHand = new PokerCard[5];
}
public void GetHand(ref CardDeck CardDeck, int Number) //取得手牌
{
Initialize();
for (int i = 0; i < 5; i++)
{
pokerHand[i] = CardDeck.Cards[(Number - 1) * 5 + i];
}
//typeNum = JudgeType();
}
private void Initialize()
{
numOfSameRank = 0; //點數相同的張數
numOfPairs = 0;
maxSingle = null; //單張的最大值
maxKind = null; //多張的最大值
typeNum = 0;
}
public int NumOfSameRank
{
get { return CountSameRank(); }
}
public PokerCard[] PokerHand //屬性
{
get { return pokerHand; }
}
public PokerCard MaxKind
{
get { return maxKind; }
}
public PokerCard MaxSingle
{
get { return maxSingle; }
}
public string Type
{
get { return type[typeNum]; }
}
public int TypeNum
{
get { return JudgeType(); }
}
private int CountSameRank() //找出有相同點數的撲克牌張數
{
int[] count = {1,1};
int j = 0; //控制計數器切換
bool isSame = false;
for (int i = 0; i < 4; i++)
{
if (pokerHand[i].Rank == pokerHand[i + 1].Rank)
{
count[j]++;
isSame = true;
if (i == 3)
{
if (count[j] == 2)
{
//Pair在最後兩張時,倒數第二張的花色較大
maxKind = pokerHand[i];
numOfPairs++;
}
else if (count[j] == 3)
maxKind = pokerHand[i - 1]; //在最後一輪才判斷出三條
else
maxKind = pokerHand[i - 2]; //在最後一輪才判斷出鐵支
}
}
else
{
//前n張連續,第n+1張與前面不同
if (isSame)
{
if (count[j] == 2) //計數器內容要是2才是對子
{
numOfPairs++;
maxKind = pokerHand[i - 1]; //對子的第一張,花色最大
j++; //切換到第二個計數器
}
else if (count[j] == 3)//三條
{
maxKind = pokerHand[i - 2];
j++; //切換到第二個計數器
}
else
maxKind = pokerHand[i - 3]; //鐵支
isSame = false;
}
}
}
if (count[0] >= count[1])
return count[0];
else return count[1];
}
private int JudgeType() //判斷牌型
{
//手牌依點數從小到大排列
SortMethod.SortByRank(ref pokerHand, 1, 5); //可修正:首項(parameter_2),項數(parameter_3)
numOfSameRank = CountSameRank();
if (numOfPairs != 0)
{
//有對子的情況: OnePair, TwoPairs, FullHouse
if (numOfPairs == 1)
{
if (numOfSameRank == 3)
return (int)CardTypes.FullHouse;
return (int)CardTypes.OnePair;
}
else return (int)CardTypes.TwoPairs;
}
else
{
//沒有對子的情況: Ziltch, ThreeOfAKind, Straight, Flush, FourOfAKind, StraightFlush
if (numOfSameRank >= 3)
{
if (numOfSameRank == 3)
return (int)CardTypes.ThreeOfAKind;
else return (int)CardTypes.FourOfAKind;
}
else if (IsStraight())
{
if (IsFlush())
return (int)CardTypes.StraightFlush;
return (int)CardTypes.Straight;
}
else if (IsFlush())
{
return (int)CardTypes.Flush;
}
else return (int)CardTypes.Zilch;
}
}
private bool IsStraight()
{
int error = 0; //當首張牌是Ace時,給for迴圈補位
if (pokerHand[4].Rank == 13) //最後一張牌是K時, {A,10,J,Q,K},{9,10,J,Q,K}
{
if (pokerHand[0].Rank == 1) //第一張牌是A時, {A,10,J,Q,K}
{
maxSingle = pokerHand[0]; //最大的牌: Ace
error = 1;
}
else maxSingle = pokerHand[4]; //一般的順子,最大的牌: K
for (int i = 4; i > (0 + error); i--)
{
if ((pokerHand[i].Rank - pokerHand[i - 1].Rank) != 1)
return false;
}
return true;
}
else
{
maxSingle = pokerHand[4]; //最大的牌: 順子尾端
for (int i = 0; i < 4; i++)
{
if ((pokerHand[i + 1].Rank - pokerHand[i].Rank) != 1)
return false;
else continue;
}
return true;
}
}
private bool IsFlush()
{
//判斷最大的牌
if (pokerHand[0].Rank == 1)
maxSingle = pokerHand[0];
else maxSingle = pokerHand[4];
for (int i = 0; i < 4; i++)
{
if (pokerHand[i].Suit != pokerHand[i + 1].Suit)
return false;
}
return true;
}
public string ShowHand()
{
string str_Hand = null;
string str_CardType = null;
str_CardType = type[typeNum];
for (int i = 0; i < 5; i++)
{
str_Hand += pokerHand[i].Rank + "";
str_Hand += pokerHand[i].SuitToUnicode() + " ";
}
return str_Hand + '\t' + str_CardType ;
}
public string Test(ref int[] testData)
{
/*
//test data
testData[0].Rank = 3;
testData[1].Rank = 10;
testData[2].Rank = 10;
testData[3].Rank = 10;
testData[4].Rank = 10;
testData[0].Suit = 3;
testData[1].Suit = 3;
testData[2].Suit = 5;
testData[3].Suit = 6;
testData[4].Suit = 4;
*/
string str_Card = null;
string str_CardType = null;
//new出測試用手牌,並配置記憶體
Hand testHand = new Hand();
for (int i = 0; i < 5; i++)
{
testHand.pokerHand[i] = new PokerCard();
}
//將測試資料(textBox的輸入)配置給測試用手牌
for (int i = 0; i < 5; i++) //配置花色
{
testHand.pokerHand[i].Suit = testData[i];
}
for (int i = 5; i < 10; i++) //配置點數
{
testHand.pokerHand[i - 5].Rank = testData[i];
}
//判斷測試用手牌的牌型
testHand.typeNum = testHand.JudgeType();
str_CardType = testHand.type[testHand.typeNum];
for (int i = 0; i < 5; i++)
{
str_Card += testHand.pokerHand[i].RankToStr() + "";
str_Card += testHand.pokerHand[i].SuitToUnicode() + " ";
}
return str_Card + '\t' + str_CardType;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace st_hw05
{
class SortMethod
{
public static void SortByRank(ref PokerCard[] Cards, int NHand, int Num) //依點數整理成堆
{
int FirstTerm = (NHand - 1) * 5; //第N副手牌的第一項
for (int i = 0; i < Num - 1; i++)
{
for (int j = 0; j < Num - 1 - i; j++)
{
if (Cards[FirstTerm + j].Rank > Cards[FirstTerm + j + 1].Rank)
Swap(ref Cards[FirstTerm + j], ref Cards[FirstTerm + j + 1]);
else if (Cards[FirstTerm + j].Rank == Cards[FirstTerm + j + 1].Rank) //點數相同時,排花色
if (Cards[FirstTerm + j].Suit > Cards[FirstTerm + j + 1].Suit)
Swap(ref Cards[FirstTerm + j], ref Cards[FirstTerm + j + 1]);
}
}
}
private static void Swap(ref PokerCard Input_1, ref PokerCard Input_2)
{
PokerCard Temp;
Temp = Input_1;
Input_1 = Input_2;
Input_2 = Temp;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace st_hw05
{
class CardJudge
{
public static bool IsWinner_Single(ref Hand hand1,ref Hand hand2)
{
//true: player_1 wins ; false: player_2 wins
if ((hand1.MaxSingle.Rank == 1) || (hand2.MaxSingle.Rank == 1))
{
//兩人最大的牌都是Ace
if ((hand1.MaxSingle.Rank == 1) && (hand2.MaxSingle.Rank == 1))
{
//比較Ace的花色 spade:3 , heart:4 , diamond:5 , club:6
if (hand1.MaxSingle.Suit < hand2.MaxSingle.Suit)
return true; //player_1 wins
else return false; //player_2 wins
}
else if (hand1.MaxSingle.Rank == 1)
return true; //只有player_1拿到Ace, player_1 wins
else return false; //只有player_2拿到Ace, player_2 wins
}
else
{
//兩人的最大點數相同
if (hand1.MaxSingle.Rank == hand2.MaxSingle.Rank)
{
//比較最大點數的花色 spade:3 , heart:4 , diamond:5 , club:6
if (hand1.MaxSingle.Suit < hand2.MaxSingle.Suit)
return true; //player_1 wins
else return false; //player_2 wins
}
else if (hand1.MaxSingle.Rank > hand2.MaxSingle.Rank)
return true; //player_1 wins
else return false; //player_2 wins
}
}
public static bool IsWinner_Kind(Hand hand1, Hand hand2)
{
if ((hand1.MaxKind.Rank == 1) || (hand2.MaxKind.Rank == 1))
{
//兩人最大的牌都是Ace
if ((hand1.MaxKind.Rank == 1) && (hand2.MaxKind.Rank == 1))
{
//比較Ace的花色 spade:3 , heart:4 , diamond:5 , club:6
if (hand1.MaxKind.Suit < hand2.MaxKind.Suit)
return true; //player_1 wins
else return false; //player_2 wins
}
else if (hand1.MaxKind.Rank == 1)
return true; //只有player_1拿到Ace, player_1 wins
else return false; //只有player_2拿到Ace, player_2 wins
}
else
{
//兩人的最大點數相同
if (hand1.MaxKind.Rank == hand2.MaxKind.Rank)
{
//比較最大點數的花色 spade:3 , heart:4 , diamond:5 , club:6
if (hand1.MaxKind.Suit < hand2.MaxKind.Suit)
return true; //player_1 wins
else return false; //player_2 wins
}
else if (hand1.MaxKind.Rank > hand2.MaxKind.Rank)
return true; //player_1 wins
else return false; //player_2 wins
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace st_hw05
{
class ProbProof
{
//Calculate the prbability of all type
public static void CalProb(ref CardDeck Poker, ref double[] result, int runNum)
{
//runNum: 測試次數
Hand hand = new Hand();
int cardType;
for (int i = 0; i < runNum; i++) //統計次數
{
Poker.FastShuffle();
hand.GetHand(ref Poker, 1);
cardType = hand.TypeNum;
result[cardType]++;
}
for (int i = 0; i < 9; i++) //除以執行次數
{
result[i] /= runNum;
}
}
}
}
1. 介面設計功能還不錯。
回覆刪除2. 註解詳細,整個程式看起來很流暢。
3. CountSameRank搭配numOfPairs的判斷方法有意思。
謝謝,不過手動輸入測試的那個地方,我們沒有加入檢查的機制,所以輸入錯誤程式就可能崩潰.
刪除當初是想說先把這個功能做出來,讓組員debug時比較方便,所以就沒有想說做檢查機制.