910 likes | 919 Views
集合 (Collections). 鄭士康 國立台灣大學 電機工程學系 / 電信工程研究所 / 資訊網路與多媒體研究所. 綱要. Collections 與泛型概說 List 類別 堆疊 Stack 類別 二十一點模擬程式 0.1GC 版 *遞迴函式 *二分搜尋法 Dictionary 類別. 綱要. Collections 與泛型概說 List 類別 堆疊 Stack 類別 二十一點模擬程式 0.1GC 版 *遞迴函式 *二分搜尋法 Dictionary 類別.
E N D
集合(Collections) 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
綱要 • Collections與泛型概說 • List類別 • 堆疊Stack類別 • 二十一點模擬程式0.1GC版 • *遞迴函式 • *二分搜尋法 • Dictionary類別
綱要 • Collections與泛型概說 • List類別 • 堆疊Stack類別 • 二十一點模擬程式0.1GC版 • *遞迴函式 • *二分搜尋法 • Dictionary類別
Collections, Enumerator, Enumerable • 列串List • 動態列串Linked List, 動態加入與刪除, 排序 • 堆疊 • Comparer
綱要 • Collections與泛型概說 • List類別 • 堆疊Stack類別 • 二十一點模擬程式0.1GC版 • *遞迴函式 • *二分搜尋法 • Dictionary類別
UsingList.Program.cs (1/11) /* * 示範List的使用 * 1/3/2009 */ using System; using System.Collections.Generic; namespace UsingList { public enum Suit { CLUB = 0, DIAMOND = 1, HEART = 2, SPADE = 3 }
UsingList.Program.cs (2/11) public struct Card : IComparable<Card> { public Suit suit; public int rank; public Card(Suit suit, int rank) { this.suit = suit; this.rank = rank; } public string Name() { string result = null;
UsingList.Program.cs (3/11) switch (suit){ case Suit.CLUB: result = "c" + rank.ToString(); break; case Suit.DIAMOND: result = "d" + rank.ToString(); break; case Suit.HEART: result = "h" + rank.ToString(); break; case Suit.SPADE: result = "s" + rank.ToString(); break; default: break; }
UsingList.Program.cs (4/11) return result; } public void Dump() { string[] ranks = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; switch (suit){ case Suit.CLUB: Console.Write("c" + ranks[rank - 1]); break; case Suit.DIAMOND: Console.Write("d" + ranks[rank - 1]); break;
UsingList.Program.cs (5/11) case Suit.HEART: Console.Write("h" + ranks[rank - 1]); break; case Suit.SPADE: Console.Write("s" + ranks[rank - 1]); break; default: break; } } public int CompareTo(Card c) { int result = 0;
UsingList.Program.cs (6/11) if (this.suit < c.suit){ result = -1; }else if (this.suit > c.suit){ result = 1; }else{ if (this.rank < c.rank){ result = -1; }else if (this.rank > c.rank){ result = 1; }else{ result = 0; } } return result; } }
UsingList.Program.cs (7/11) public class CardComparer : IComparer<Card> { public int Compare(Card cx, Card cy) { return cx.CompareTo(cy); } } class Program { static void Main(string[] args) { List<Card> hand = new List<Card>(); WriteList(hand);
UsingList.Program.cs (8/11) Console.WriteLine( "加入c2, sJ, hQ, hA, d7, c7"); hand.Add(new Card(Suit.CLUB, 2)); hand.Add(new Card(Suit.SPADE, 11)); hand.Add(new Card(Suit.HEART, 12)); hand.Add(new Card(Suit.SPADE, 1)); hand.Add(new Card(Suit.DIAMOND, 7)); hand.Add(new Card(Suit.CLUB, 7)); WriteList(hand); Console.WriteLine("位置1插入d9"); hand.Insert(1,new Card(Suit.DIAMOND, 9)); WriteList(hand); Console.WriteLine("移走位置2的牌卡"); hand.Remove(hand[2]); WriteList(hand);
UsingList.Program.cs (9/11) Console.WriteLine("移走位置3的牌卡"); hand.RemoveAt(3); WriteList(hand); Console.WriteLine("反轉排列順序"); hand.Reverse(); WriteList(hand); Console.WriteLine("重新由小而大排序"); hand.Sort(); WriteList(hand); int idx; Card d7 = new Card(Suit.DIAMOND, 7); Console.WriteLine("搜尋d7"); if (hand.Contains(d7)){ idx = hand.BinarySearch(d7); Console.WriteLine( "於位置{0}找到d7",idx); }
UsingList.Program.cs (10/11) else{ Console.WriteLine("沒有找到d7"); } Console.WriteLine("搜尋c10"); idx = hand.BinarySearch( new Card(Suit.CLUB, 10), new CardComparer()); if (idx >= 0){ Console.WriteLine( "於位置{0}找到c10", idx); } else{ Console.WriteLine("沒有找到c10"); } Console.WriteLine(); }
UsingList.Program.cs (11/11) static void WriteList(List<Card> lc) { foreach( Card c in lc ) { c.Dump(); Console.Write("\t"); } Console.WriteLine( "容量=" + lc.Capacity + "; 牌數=" + lc.Count); } } }
練習 • 撰寫類別Square,模擬邊長為整數a的正方形。注意繼承IComparable介面,定義CompareTo函式,以便比較不同正方形之大小。 • 撰寫測試程式,建立正方形的List,嘗試加入或刪除其中元素,反轉排列,重新排序,以foreach取出所有元素,尋找某一元素。
綱要 • Collections與泛型概說 • List類別 • 堆疊Stack類別 • 二十一點模擬程式0.1GC版 • *遞迴函式 • *二分搜尋法 • Dictionary類別
堆疊(Stack) • Push • Pop • Peek top
TestStack.Program.cs (1/12) /* * 示範Stack的使用 * 1/3/2009 */ using System; using System.Collections.Generic; namespace TestStack { public enum Suit { CLUB = 0, DIAMOND = 1, HEART = 2, SPADE = 3 }
TestStack.Program.cs (2/12) public struct Card { public Suit suit; public int rank; public Card(Suit suit, int rank){ this.suit = suit; this.rank = rank; } public string Name(){ string result = null;
TestStack.Program.cs (3/12) switch (suit){ case Suit.CLUB: result = "c" + rank.ToString(); break; case Suit.DIAMOND: result = "d" + rank.ToString(); break; case Suit.HEART: result = "h" + rank.ToString(); break; case Suit.SPADE: result = "s" + rank.ToString(); break; default: break; }
TestStack.Program.cs (4/12) return result; } public void Dump() { string[] ranks = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; switch (suit) { case Suit.CLUB: Console.Write("c" + ranks[rank - 1]); break;
TestStack.Program.cs (5/12) case Suit.DIAMOND: Console.Write("d" + ranks[rank - 1]); break; case Suit.HEART: Console.Write("h" + ranks[rank - 1]); break; case Suit.SPADE: Console.Write("s" + ranks[rank - 1]); break; default: break; } } }
TestStack.Program.cs (6/12) public class Deck { private Stack<Card> cardStack = new Stack<Card>(); public Deck() { Random rand = new Random(); PrepareDeck(rand); } public Deck(int seed) { Random rand = new Random(seed); PrepareDeck(rand); }
TestStack.Program.cs (7/12) // Reference: ArrayAndFileIO.ppt, p. 39 private void PrepareDeck(Random rand) { int i; bool[] used = new bool[52]; for (i = 0; i < 52; ++i) { used[i] = false; } int pos; // position in the table given in reference int s; Suit suit;
TestStack.Program.cs (8/12) for (i = 0; i < 52; ++i){ pos = rand.Next() % 52; // search for un-used position while (used[pos]){ ++pos; pos = pos % 52; } s = pos / 13; switch (s) { case 0: suit = Suit.CLUB; break; case 1: suit = Suit.DIAMOND; break;
TestStack.Program.cs (9/12) case 2: suit = Suit.HEART; break; case 3: suit = Suit.SPADE; break; default: suit = Suit.CLUB; break; } int rank = pos % 13 + 1; used[pos] = true; cardStack.Push(new Card(suit, rank)); } }
TestStack.Program.cs (10/12) public Deck(Card[] cards) { int nCards = cards.Length; this.cardStack = new Stack<Card>(); int i; for (i = 0; i < nCards; ++i) { cardStack.Push(cards[i]); } } public Card DealACard() { return cardStack.Pop(); }
TestStack.Program.cs (11/12) public bool HasMoreCard() { bool empty = false; try { cardStack.Peek(); } catch (Exception) { empty = true; } return !empty; } }
TestStack.Program.cs (12/12) class Program{ static void Main(string[] args){ Deck deck = new Deck(); int i; Card card; for (i = 0; i < 53; ++i){ if (deck.HasMoreCard()){ card = deck.DealACard(); card.Dump(); Console.Write("\t"); if ((i + 1) % 10 == 0) Console.WriteLine(); } } } } }
綱要 • Collections與泛型概說 • List類別 • 堆疊Stack類別 • 二十一點模擬程式0.1GC版 • *遞迴函式 • *二分搜尋法 • Dictionary類別
BlackJack_0_1GC.MainForm.cs(1/11) 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 BlackJack_0_1GC { //*********************************** public struct PlayerInfo { public string name; public Status status;
BlackJack_0_1GC.MainForm.cs(2/11) public int totalPoints; public List<Card> cards; } //*********************************** public partial class MainForm : Form { //******************************* private Game game; private PlayerInfo playerInfo; private PlayerInfo dealerInfo; private Image image; private Graphics graphics; private bool inGame = false; //*******************************
BlackJack_0_1GC.MainForm.cs(3/11) public MainForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //************************************ game.ProcessPlayerRun(out playerInfo); ShowInfo(); CheckBlackJackOrBurst(playerInfo); CheckBlackJackOrBurst(dealerInfo); //************************************* }
BlackJack_0_1GC.MainForm.cs(4/11) //***************************************** private void ShowInfo() { int i; string fileName; graphics = CreateGraphics(); for (i = 0; i < playerInfo.cards.Count; ++i) { fileName = "..\\PlayingCards\\" + playerInfo.cards[i].Name() + ".jpg"; image = Image.FromFile(fileName); graphics.DrawImage(image, 5 + 100 * i, 220,85, 150); }
BlackJack_0_1GC.MainForm.cs(5/11) for (i = 0; i < dealerInfo.cards.Count; ++i){ fileName = "..\\PlayingCards\\" + dealerInfo.cards[i].Name() + ".jpg"; image = Image.FromFile(fileName); graphics.DrawImage(image, 5 + 100 * i, 5,85, 150); } label1.Text = dealerInfo.totalPoints.ToString(); label2.Text = playerInfo.totalPoints.ToString(); label11.Text = dealerInfo.name; label12.Text = playerInfo.name; } //******************************************
BlackJack_0_1GC.MainForm.cs(6/11) private void button3_Click(object sender, EventArgs e) { //************************************** // "開始"按鈕 inGame = true; game = new Game(); game.InitPlay(out playerInfo, out dealerInfo); ShowInfo(); CheckBlackJackOrBurst(playerInfo); CheckBlackJackOrBurst(dealerInfo); button3.Enabled = false; button4.Enabled = true; //*************************************** }
BlackJack_0_1GC.MainForm.cs(7/11) private void button2_Click(object sender, EventArgs e) { //************************************** // "停"按鈕 game.ProcessDealerRun(out dealerInfo); ShowInfo(); CheckBlackJackOrBurst(playerInfo); CheckBlackJackOrBurst(dealerInfo); if (playerInfo.status == Status.PASS && dealerInfo.status == Status.PASS) {
BlackJack_0_1GC.MainForm.cs(8/11) if (dealerInfo.totalPoints >= playerInfo.totalPoints) { MessageBox.Show(dealerInfo.name + "勝" + playerInfo.name); } else { MessageBox.Show(playerInfo.name + "勝" + dealerInfo.name); } } //************************************** }
BlackJack_0_1GC.MainForm.cs(9/11) private void CheckBlackJackOrBurst( PlayerInfo info) { if (info.status == Status.BLACK_JACK) { MessageBox.Show(info.name + " 二十一點"); } if (info.status == Status.BURST) { MessageBox.Show(info.name + " 爆!!!"); } }
BlackJack_0_1GC.MainForm.cs(10/11) private void button4_Click(object sender, EventArgs e) { //************************************** // "清除"按鈕 inGame = false; Invalidate(); label1.Text = "0"; label2.Text = "0"; button4.Enabled = false; button3.Enabled = true; //************************************** }
BlackJack_0_1GC.MainForm.cs(11/11) //**************************************** protected override voidOnPaint( PaintEventArgs e){ base.OnPaint(e); if (inGame) { ShowInfo(); } } private void MainForm_Load(object sender, EventArgs e) {} //***************************************** } }
BlackJack_0_1GC.Game.cs (1/6) /* * 二十一點遊戲, GUI and Collections 版本 * 1/11/2009 */ using System; namespace BlackJack_0_1GC { class Game { const int N_PLAYERS = 2; Deck deck; Player[] players = new Player[N_PLAYERS]; public Game() {
BlackJack_0_1GC.Game.cs (2/6) players[0] = new Player("Jeng"); players[N_PLAYERS - 1] = new Dealer(); deck = new Deck(); } public void InitPlay(out PlayerInfo playerInfo, out PlayerInfo dealerInfo) { int i; // 第一輪發牌 for (i = 0; i < N_PLAYERS; ++i) { players[i].SaveACard( deck.DealACard()); }
BlackJack_0_1GC.Game.cs (3/6) // 第二輪發牌 for (i = 0; i < N_PLAYERS; ++i) { players[i].SaveACard( deck.DealACard()); } playerInfo.name = players[0].Name; playerInfo.status = players[0].GetStatus(); playerInfo.totalPoints = players[0].GetTotalPoints(); playerInfo.cards = players[0].DumpCards(); dealerInfo.name = players[N_PLAYERS - 1].Name;
BlackJack_0_1GC.Game.cs (4/6) dealerInfo.status = players[N_PLAYERS - 1].GetStatus(); dealerInfo.totalPoints = players[N_PLAYERS - 1].GetTotalPoints(); dealerInfo.cards = players[N_PLAYERS - 1].DumpCards(); } public void ProcessPlayerRun(out PlayerInfo playerInfo) { players[0].SaveACard(deck.DealACard()); playerInfo.name = players[0].Name; playerInfo.status = players[0].GetStatus();
BlackJack_0_1GC.Game.cs (5/6) playerInfo.totalPoints = players[0].GetTotalPoints(); playerInfo.cards = players[0].DumpCards(); } public void ProcessDealerRun(out PlayerInfo dealerInfo) { while ( players[N_PLAYERS - 1].WantOneMoreCard()) { players[N_PLAYERS - 1].SaveACard( deck.DealACard()); }
BlackJack_0_1GC.Game.cs (6/6) dealerInfo.name = players[N_PLAYERS - 1].Name; dealerInfo.status = players[N_PLAYERS - 1].GetStatus(); dealerInfo.totalPoints = players[N_PLAYERS - 1].GetTotalPoints(); dealerInfo.cards = players[N_PLAYERS - 1].DumpCards(); } } }
BlackJack_0_1GC.Player.cs (1/7) /* * 模擬玩家, GUI與Collections版本 * 1/11/2009 */ using System; using System.Collections.Generic; namespace BlackJack_0_1GC { class Player { private List<Card> hand = new List<Card>(); private Status status; private int totalPoints; private string name;