2014年4月4日 星期五

[Code Review] Team 10 - Hw05




完整程式:WindowsFormsApp_HW05_StudPoker.rar
執行檔:WindowsFormsApp_HW05_StudPoker.exe


Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApp_HW05
{
    public partial class Form1 : Form
    {
        CardDeck deck = null;
        StudPoker hand1 = null;
        StudPoker hand2 = null;
        private string[] HandType = { "High Card", "One Pair", "Two Pair", "Three of a kind", "Stright", "Flush", "Full House", "Four of a kind", "Straight Flush" };

        public Form1()
        {
            InitializeComponent();            
        }
        
        private void btn_comfirm_Click(object sender, EventArgs e)
        {
            if (deck == null || hand1 == null || hand2 == null)
            {
                deck = new CardDeck();
                hand1 = new StudPoker();
                hand2 = new StudPoker();
            }
            switch (cmb_select.SelectedIndex)
            {
                case 0:
                    txt_Display.AppendText("******ComboBox 單人牌組 已被選定。******" + "\n");
                    deck.Shuffle();
                    for (int i = 0; i < 5; i++)
                        hand1.Add(deck.deal());
                    hand1.sort();
                    lbl_Hand.Text = ShowStudCard(hand1);
                    lbl_Hand2.Text = "";    //Clear
                    txt_Display.AppendText("牌型:" + HandType[hand1.getCardType()] + "\n");
                    break;
                case 1:
                    txt_Display.AppendText("******ComboBox 雙人牌組 已被選定。******" + "\n");
                    deck.Shuffle();
                    for (int i = 0; i < 5; i++)
                        hand1.Add(deck.deal());
                    hand1.sort();
                    lbl_Hand.Text = ShowStudCard(hand1);
                    txt_Display.AppendText("玩家1的牌型:" + HandType[hand1.getCardType()] + "\n");

                    for (int i = 0; i < 5; i++)
                        hand2.Add(deck.deal());
                    hand2.sort();
                    lbl_Hand2.Text = ShowStudCard(hand2);
                    txt_Display.AppendText("玩家2的牌型:" + HandType[hand2.getCardType()] + "\n");
                    txt_Display.AppendText("結果:" + WhoWin(hand1, hand2) + "\n");
                    break;
                case 2:
                    txt_Display.AppendText("******ComboBox 計算牌型機率 已被選定。******" + "\n");                    
                    int[] Cardtypes = new int[9];
                    deck.Shuffle();
                    progressBar.Value = 0;
                    for (int i = 0; i < 5000000; i++)    //50000000
                    {
                        for (int j = 0; j < 10; j++)
                        { 
                            for (int k = 0; k < 5; k++)
                            { 
                                hand1.Add(deck.deal());
                            }
                            hand1.sort();
                            Cardtypes[hand1.getCardType()]++;                    
                        }
                        progressBar.PerformStep();  //step=1
                        deck.Shuffle();
                    }                    
                    for (int i = 0; i < 9; i++)
                    {
                        txt_Display.AppendText( HandType[i] + "的機率:" + (double)Cardtypes[i] / 50000000 + "\n");
                    }                    
                    break;
            }            
        }

        private void btn_test_Click(object sender, EventArgs e)
        {
            StudPoker hand = new StudPoker();
            hand.test();
            hand.sort();
            lbl_Hand.Text = ShowStudCard(hand);
            lbl_Hand2.Text = "";    //Clear
            txt_Display.AppendText("**********測試*********" + "\n");
            txt_Display.AppendText("牌型:" + HandType[hand.getCardType()] + "\n");
        }
        
        private void btn_clearLog_Click(object sender, EventArgs e)
        {
            txt_Display.Clear();
            lbl_Hand.Text = "";
            lbl_Hand2.Text = "";
            progressBar.Value = 0;
            MessageBox.Show("清除!");
        }

        private string ShowStudCard(StudPoker hand)
        {
            string str = "";
            for (int i = 0; i < 5; i++)
            {
                str += hand.Hand[i].ToString() + " ";
            }
            return str;
        }
        private string WhoWin(StudPoker hand1, StudPoker hand2)
        {
            string str = "";
            if (hand1.getCardType() == hand2.getCardType())
                str = "平手!";
            else if (hand1.getCardType() > hand2.getCardType())
                str = "玩家1獲勝!";
            else if (hand1.getCardType() < hand2.getCardType())
                str = "玩家2獲勝!";
            else
                str = "錯誤!";
            return str;
        }

    }
}

StudPoker.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApp_HW05
{
    class StudPoker
    {
        private PokerCard[] hand = new PokerCard[5];
        private int amount = 0;
        private enum cardtype { HIGH_CARD = 0, ONE_PAIR, TWO_PAIR, THREE_OF_A_KIND, STRAIGHT, FLUSH, FULL_HOUSE, FOUR_OF_A_KIND, STRAIGHT_FLUSH };

        public PokerCard[] Hand
        {
            get { return hand; }
        }
        public void Add(PokerCard card)
        {
            amount %= 5;
            hand[amount++] = card;
        }
        public void sort()  //SortByRank
        {
            for (int j = 0; j < 5 - 1; j++)
            {
                for (int i = 0; i < 5 - 1 - j; i++)
                {
                    if (hand[i].Rank > hand[i + 1].Rank)
                        ChangeTwoCards(i, i + 1);                    
                }
            }
        }
        private void ChangeTwoCards(int card1, int card2)
        {
            PokerCard temp = null;

            temp = hand[card1];
            hand[card1] = hand[card2];
            hand[card2] = temp;
        }         
        public int getCardType()
        {
            if (isFlush())
            {
                if (isStraight())
                    return (int)cardtype.STRAIGHT_FLUSH;
                else
                    return (int)cardtype.FLUSH;
            }            
            else
            {
                //從機率大至小來做檢查
                if (CheckPair())
                    if (isStraight())            
                        return (int)cardtype.STRAIGHT;
                    else
                        return (int)cardtype.HIGH_CARD;
                else if (isOnePair())
                    return (int)cardtype.ONE_PAIR;
                else if (isTwoPair())
                    return (int)cardtype.TWO_PAIR;
                else if (isThreeOfAKind())
                    return (int)cardtype.THREE_OF_A_KIND;
                else if (isFullHouse())
                    return (int)cardtype.FULL_HOUSE;
                else if (isFourOfAKind())
                    return (int)cardtype.FOUR_OF_A_KIND;
                else
                    return -1;  //error!
            }          
        }
        public bool isStraightFlush()
        {
            if (isFlush() && isStraight())
                return true;
            else
                return false;
        }
        public bool isFourOfAKind()
        {
            int count = 0;
            for (int j = 0; j < 5 - 1; j++)
            {
                for (int i = j; i < 5 - 1; i++)
                {
                    if (hand[j].Rank == hand[i + 1].Rank)
                        count++;
                }
            }
            if (count == 6)
                return true;
            else
                return false;
        }
        public bool isFullHouse()
        {
            int count = 0;
            for (int j = 0; j < 5 - 1; j++)
            {
                for (int i = j; i < 5 - 1; i++)
                {
                    if (hand[j].Rank == hand[i + 1].Rank)
                        count++;
                }
            }
            if (count == 4)
                return true;
            else
                return false;
        }
        public bool isFlush()
        {
            int count = 0;
            for (int i = 0; i < 5 - 1; i++)
            {
                if (hand[i].Suit == hand[i + 1].Suit)
                    count++;
            }            
            if (count == 4)
                return true;
            else
                return false;
        }
        public bool isStraight()
        {
            int count = 0;
            for (int i = 0; i < 5-1; i++)
            {
                if (hand[i].Rank + 1 == hand[i + 1].Rank)
                    count++;                
            }
            if (hand[4].Rank == 12 && hand[0].Rank == 0)    //特例:A 10 J Q K
                    count++;
            if (count == 4)
                return true;
            else
                return false;
        }
        public bool isThreeOfAKind()
        {
            int count = 0;
            for (int j = 0; j < 5 - 1; j++)
            {
                for (int i = j; i < 5 - 1; i++)
                {
                    if (hand[j].Rank == hand[i + 1].Rank)
                        count++;
                }
            }
            if (count == 3)
                return true;
            else
                return false;
        }
        public bool isTwoPair()
        {
            int count = 0;
            for (int j = 0; j < 5 - 1; j++)
            {
                for (int i = j; i < 5 - 1; i++)
                {
                    if (hand[j].Rank == hand[i + 1].Rank)
                        count++;
                }
            }
            if (count == 2)
                return true;
            else
                return false;
        }
        public bool isOnePair()
        {
            int count = 0;
            for (int i = 0; i < 5 - 1; i++)
            {
                if (hand[i].Rank == hand[i + 1].Rank)
                    count++;
            }
            if(count==1)
                return true;
            else
                return false;
        }
        public bool CheckPair()
        {
            int count = 0;
            for (int i = 0; i < 5 - 1; i++)
            {
                if (hand[i].Rank == hand[i + 1].Rank)
                    count++;
            }
            if (count == 0)
                return true;
            else
                return false;
        }
        public void test()
        {
            hand[0] = new PokerCard(2, 12);
            hand[1] = new PokerCard(1, 11);
            hand[2] = new PokerCard(2, 13);
            hand[3] = new PokerCard(1, 1);
            hand[4] = new PokerCard(2, 9);
        }
    }
}
CardDeck.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApp_HW05
{
    class CardDeck
    {
        //Field
        private PokerCard[] Cards = new PokerCard[52];
        private int topIndex = 0;
       
        //Property
        public CardDeck() //產生出52個PokerCard的物件
        {
            for (int i = 0; i < 52; i++)
                Cards[i] = new PokerCard(i / 13, i % 13 + 1);
        }
        //Method
        public PokerCard deal()  //發牌
        {
            if (topIndex >= 50)
                Shuffle();
            return Cards[topIndex++];
        }
        public void ResetDeck() //牌堆回復原始狀態
        {
            for (int i = 0; i < 52; i++)
            {
                Cards[i].Rank = i % 13 + 1;
                Cards[i].Suit = i / 13 ;
            }
        }
        public void Shuffle() //洗牌
        {
            Random rand = new Random();
            
            for (int i = 0; i < 52; i++)
            {
                int card1 = rand.Next(52);
                ChangeTwoCards(i, card1);
            }
            topIndex = 0;
        }
        public void OrderByRank() //按點數大小排列
        {
            for (int i = 0; i < 52; i++)
            {
                Cards[i].Rank = i / 4 + 1;
                Cards[i].Suit = i % 4;
                
            }
        }
        private void ChangeTwoCards(int card1, int card2)
        {
            PokerCard temp = null;

            temp = Cards[card1];
            Cards[card1] = Cards[card2];
            Cards[card2] = temp;
        }
    }
}
PokerCard.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApp_HW05
{
    class PokerCard
    {
        //Field
        private int suit;  //花色
        private int rank;  //點數
        private string[] suitToUnicode={"\u2665","\u2666","\u2663","\u2660"};//愛心,菱形,梅花,黑桃

        public PokerCard(int suit,int rank)
        {
            this.suit = suit;
            this.rank = rank;
        }
        public int Suit
        {
            get { return suit; }
            set 
            {
                if (value < 4 && value >= 0)
                    suit = value;
            }
        }
        public int Rank
        {
            get { return rank; }
            set 
            {
                if (value < 13 && value >= 0)
                    rank = value;
            }
        }
        public string RankToStr()  //將點數轉為字串
        {
            switch (rank)
            {
                case 1:
                    return "A";
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                    return Convert.ToString(rank);
                case 11:
                    return "J";
                case 12:
                    return "Q";
                case 13:
                    return "K";
                default:
                    return "error!";
            }           
        }
        public string SuitToUnicode()  //將花色轉為unicode
        {
            return suitToUnicode[suit]; 
        }
        public override string ToString()
        {
            return RankToStr() + SuitToUnicode();
        }
    }
}

1 則留言:

  1. int count = 0;
    for (int j = 0; j < 5 - 1; j++)
    {
    for (int i = j; i < 5 - 1; i++)
    {
    if (hand[j].Rank == hand[i + 1].Rank)
    count++;
    }
    }
    這段程式碼重複出現在所有判斷牌型的方法中
    如果把他設定為手牌的一個屬性
    在手牌內容更新時做一次運算
    接下來判斷牌型時只須呼叫他的值而不需要進行重複的計算
    應該可以讓程式更有效率

    回覆刪除