2014年3月24日 星期一

[Code Review] Team 02 - Hw04



/*********************** 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.Threading.Tasks;
using System.Windows.Forms;
using Q4;

namespace HW4
{
    public partial class Form1 : Form
    {
        CardDeck deck = new CardDeck();

        public Form1()
        {
            InitializeComponent();            
            deck.CreateDeck();
            deck.ResetDeck();
        }

        private void btn_cmoSelect_Click(object sender, EventArgs e)
        {
            switch(cbo_Select.SelectedIndex)
            {
                case 0:
                    txt_Display.AppendText("Combobox 按花色牌列 已被選定\n");
                    deck.ResetDeck();
                    ShowDeck(deck);
                    break;
                case 1:
                    txt_Display.AppendText("Combobox 亂數排列 已被選定\n");
                    deck.Shuffle();
                    ShowDeck(deck);
                    break;
                case 2:
                    txt_Display.AppendText("Combobox 按點數牌列 已被選定\n");
                    deck.OrderByRank();
                    ShowDeck(deck);
                    break;
                default:
                    txt_Display.AppendText("請重新選擇!\n");
                    break;
            }
        }

        private void btn_chkSelect_Click(object sender, EventArgs e)
        {
            if (chk_ResetDeck.Checked)
            {
                txt_Display.AppendText("Checkbox 按花色牌列 已被選定\n");
                deck.ResetDeck();
                ShowDeck(deck);
            }
            if (chk_Shuffle.Checked)
            {
                txt_Display.AppendText("Checkbox 亂數排列 已被選定\n");
                deck.Shuffle();
                ShowDeck(deck);
            }
            if (chk_OrderByRank.Checked)
            {
                txt_Display.AppendText("Checkbox 按點數牌列 已被選定\n");
                deck.OrderByRank();
                ShowDeck(deck);
            }
        }

        private void ShowDeck(CardDeck deck)
        {
            string s = "";
            for (int i = 0; i < 52; i++)
            {
                s += deck.Cards[i].RankToStr() + deck.Cards[i].SuitToAscii() + "  ";
                if (i % 13 == 12)
                {
                    s += "\n";
                }
            }
            MessageBox.Show(s);
        }
    }
}
/*********************** CardDeck.cs ************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q4
{
    class CardDeck
    {
        public int CardNum  = 52;
        public PokerCard[] Cards;

        public CardDeck()
        { 
            Cards = new PokerCard[CardNum];
        }
        public void CreateDeck()  //產生出52個PokerCard的物件
        {
            for (int i = 0; i < CardNum; i++)
            {
                Cards[i] = new PokerCard();
            }
        }
        public void ResetDeck() //牌堆回復原始狀態
        {
            for (int i = 0; i < CardNum; i++)
            {
                Cards[i].Suit = i / 13 + 3;
                Cards[i].Rank = i % 13 + 1;
            }
        }
        public void Shuffle() //洗牌
        {
            Random rand = new Random();
            int RandNum = 0;
            PokerCard TempCard = new PokerCard();
            for (int i = 0; i < CardNum; i++)
            {
                RandNum = rand.Next(CardNum);
                TempCard = Cards[RandNum];
                Cards[RandNum] = Cards[i];
                Cards[i] = TempCard;
            }
        }
        public void OrderByRank() //依點數排序
        {
            for (int i = 0; i < CardNum; i++)
            {
                Cards[i].Suit = i % 4 + 3;
                Cards[i].Rank = i / 4 + 1;
            }
        } 
    }
}
/*********************** PokerCard.cs ************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q4
{
    class PokerCard
    {
        public int Suit = 0;  //花色
        public int Rank = 0;  //點數

        public string RankToStr()  //將點數轉為字串
        { 
// 不好的寫法
/*            string[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
            return num[Rank];*/

// 較佳的寫法
            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 "NULL";
            }
        }
        public string SuitToAscii()  //將花色轉為 Ascii 字元碼
        {
            switch (Suit)
            {
                case 3:
                    return "♥";
                case 4:
                    return "♦";
                case 5:
                    return "♣";
                case 6:
                    return "♠";
                default:
                    return "";
            }

        }
    }

}

15 則留言:

  1. RanktoString方法部分若只寫case1,case11,case12,case13,其他都用default來寫會不會比較精簡一點呢?

    回覆刪除
    回覆
    1. 會,但是如果不只13種數字呢?
      這樣寫比較容易懂,而且容易擴充。

      刪除
  2. 最後SuitToAscii() function命名應該修改成SuitToString()

    回覆刪除
    回覆
    1. 對,這是修改內容沒修改標題的結果。

      刪除
  3. team6神回復
    17~19我反而覺得這樣比較好
    // 不好的寫法
    /* string[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    return num[Rank];*/

    回覆刪除
    回覆
    1. 如果不是在[]不是在0~13,多+一層徵錯就好

      刪除
    2. 這方法不好的地方是寫在function內,
      導致每次使用都產生陣列,然後用完又丟。
      效率不好。

      其實更佳的寫法是使用靜態變數,相關的寫法可以參考林高遠在疑難雜症區的寫法。

      刪除
  4. 推"♥♦♣♠ 太有才"!
    ================
    想不到還有這個方法!

    回覆刪除
  5. === 林高遠 ===
    CardDeck 被 new 出來時 沒有一次做完 [生52張牌] 的動作, 這樣不好, 因為你不會去書局買到只有空盒子的撲克牌

    回覆刪除
    回覆
    1. 為什麼這樣寫呢?
      因為 PokerCard[] Cards = new PokerCard[CardNum]; 行不通
      這樣可以保持程式擴充性,可以藉由修改 CardNum 來產生
      不同數量的牌。

      刪除
  6. 對直接return "♥""♦""♣""♠" 的寫法感到新奇

    然後ShowDeck(deck);不用丟Deck進去
    在同一個class中可以直接使用
    用ShowDeck();即可

    回覆刪除
    回覆
    1. 可以這樣寫,但為什麼不呢,其實還是為了降低輸出與程式內容的偶合性。

      刪除
  7. CardDeck.cs中
    行37int RandNum = 0; 初始值是否為必要?
    By 吳珠鈺

    回覆刪除
    回覆
    1. 寫作習慣,
      我不喜歡變數宣告出來沒有值,
      所以都會塞一個初始值進去。

      變數會放0,而參考則放null。

      刪除