
| 實習目標 | 練習設計及規劃物件系統 練習 bottom-up 的物件實作方式 |
|---|---|
| 步驟一 | 上一個實習中, 我們還沒有實作到牌桌上看到的一切, 包括:
|
| 步驟二 | CenterDeck 類別
首先我們來實作牌桌上四疊不同花色的牌:
int i;
CenterDeck centerDeck;
centerDeck.reset();
cout << "Before the test\n";
centerDeck.display(cout);
// 測試按照順序出牌
for (i=7; i>1; i--)
{
centerDeck.add(Card(Spade, i));
centerDeck.add(Card(Heart, i));
centerDeck.add(Card(Diamond, i));
centerDeck.add(Card(Club, i));
}
// 故意測試不按照順序出牌
if (centerDeck.add(Card(Spade, 11)))
cout << "SJ added successfully\n";
else
cout << "SJ fail to add to center deck\n";
for (i=8; i<=12; i++)
{
centerDeck.add(Card(Spade, i));
centerDeck.add(Card(Heart, i));
centerDeck.add(Card(Diamond, i));
centerDeck.add(Card(Club, i));
}
centerDeck.add(Card(Heart, 1));
centerDeck.add(Card(Club, 1));
centerDeck.add(Card(Spade, 13));
centerDeck.add(Card(Diamond, 13));
cout << "After adding 48 cards\n";
centerDeck.display(cout);
範例執行程式
測試結果如下:
Before the test
Center Deck #0: -- -- -- -- -- -- -- -- -- -- -- -- --
Center Deck #1: -- -- -- -- -- -- -- -- -- -- -- -- --
Center Deck #2: -- -- -- -- -- -- -- -- -- -- -- -- --
Center Deck #3: -- -- -- -- -- -- -- -- -- -- -- -- --
SJ fail to add to center deck
After adding all 52 cards
Center Deck #0: -- S2 S3 S4 S5 S6 S7 S8 S9 ST SJ SQ SK
Center Deck #1: H1 H2 H3 H4 H5 H6 H7 H8 H9 HT HJ HQ --
Center Deck #2: -- D2 D3 D4 D5 D6 D7 D8 D9 DT DJ DQ DK
Center Deck #3: C1 C2 C3 C4 C5 C6 C7 C8 C9 CT CJ CQ -- |
| 步驟三 | 接下來請替 CenterDeck 增加一個很重要的界面函式,
int queryNextMoves(Card nextMoves[]);
這個函式可以判斷接下來 CenterDeck 究竟可以接受哪些牌。 每一個 Player 基本上只知道自己手上的牌, 必須要呼叫 CenterDeck
的這個界面函式來知道下一步可以出哪些牌, 每次呼叫時需要傳進一個 Card nextMoves[8] 的陣列, 因為最多可能有八種可以出的牌,
queryNextMoves() 則會傳回可以出的牌的數目, Player 再根據這些資訊以及自己手上的牌來決定自己該出哪一張牌。
你製作完 queryNextMoves() 函式後, 可以用下面的程式碼來測試
CenterDeck centerDeck;
Card nextMoves[8];
centerDeck.add(Card(Spade, 7));
centerDeck.add(Card(Spade, 8));
centerDeck.add(Card(Spade, 9));
centerDeck.add(Card(Heart, 7));
centerDeck.add(Card(Heart, 6));
centerDeck.add(Card(Club, 7));
centerDeck.display(cout);
int nMoves = centerDeck.queryNextMoves(nextMoves);
int i;
cout << "Possible next moves:\n";
for (i=0; i<nMoves; i++)
nextMoves[i].display(cout);
cout << endl; 範例執行程式 測試結果如下:
Center Deck #0: -- -- -- -- -- -- S7 S8 S9 -- -- -- --
Center Deck #1: -- -- -- -- -- H6 H7 -- -- -- -- -- --
Center Deck #2: -- -- -- -- -- -- -- -- -- -- -- -- --
Center Deck #3: -- -- -- -- -- -- C7 -- -- -- -- -- --
Possible next moves:
S6 ST H5 H8 D7 C6 C8 |
| 步驟四 | Player::nextMove()
接下來我們要來撰寫 Player 出牌的動作了, 每次 Game 物件送一個 nextMove 的訊息過來時, Player 物件會執行這個成員函式來回應, 這個函式應該要先去詢問 CenterDeck 物件到底可以出些什麼牌, 然後根據 Player 自己手上有哪些牌來判斷是否有牌可以出, 如果有很多張牌可以出的話, 選擇到底要出哪一張牌, 如果沒有牌可以出的話, 也需要選擇一張牌來蓋牌。 上面的這些動作你可以選擇最簡單的方式來實作, 例如說如果有多張牌可以出的話, Player 就出第一張牌, 如果需要蓋牌的話, Player 也蓋手上的第一張牌, 我們可以先把程式架構起來以後再回頭來修改這些部份, 讓 Player 變得比較聰明。 哪些是程式的基本架構呢? 你再仔細一點來看這個 nextMove() 成員函式, 你會發現它需要和其它的物件有一些互動, 比方說詢問 CenterDeck 有哪些牌是可以出的, 比方說出牌的動作, 比方說蓋牌的動作應該也需要和桌面上你專屬的牌堆互動, 你需要思考 Player 這個物件是否需要和相關的物件有靜態的關係, 如果要有的話該在什麼時候建立, 該如何建立? 或者不需要有靜態的關係, 你可以在 nextMove() 的參數裡動態地傳進來, 比方說 nextMove(CenterDeck *centerDeck) 接下來又到了設計測試的部份了, 簡單起見, 我們可以寫一個迴圈輪流讓四個 Player 出牌, 而且你知道只要每個人出十三次遊戲就結束了, 例如:
for (i=0; i<13; i++)
for (j=0; j<4; j++)
{
player[j].nextMove(centerDeck);
centerDeck.display(cout);
}
如此你就可以看到四個人自動把牌通通出完了, 不過你可能也希望在過程中把每一個 Player 手上所有的牌都印出來, 把每一個 Player
所蓋的牌都印出來, 這樣子可以檢查程式是不是正確地執行。 |
| 步驟五 | 上個步驟中你也許已經實作了給每個 Player 蓋牌的那四個容器, 如果沒有的話, 在這個步驟中你可以這樣子修改你的程式。
接下來還有不少事情需要一一處理的, 你可以在作業裡慢慢完成, 例如:
|
| 步驟六 | 請將所完成的 project (去掉 debug/ 資料匣下的所有內容) 壓縮起來儲存在 cyber 上你的帳號內, 後面的實習課程可能需要使用這裡所完成的程式 |

回
C++ 物件導向程式設計課程
首頁
製作日期: 04/27/2004
by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw
TEL: 02 24622192x6615
海洋大學
電機資訊學院
資訊工程系
Lagoon