2010-07-02 143 views
5

我正在實現一個簡單的「玩你的卡片」(否則稱爲更高/更低)的遊戲。如果你在規則非常簡單之前還沒有遇到過它。使用一套卡(例如心)。一次抽出一張卡,目的是正確猜測下一張卡的面值是高於還是低於先前抽取的卡的面值。Java - 簡單遊戲的設計建議

遊戲的邏輯並不特別複雜,我並不擔心這一點。我想出了一個設計,但我並不完全滿意。有幾個方面我確信它可以得到改進,這就是我希望得到您的建議。下面是這個類的接口(用於額外的理解意見,不實評論):

public interface PlayYourCardsRight { 

/** 
* Get the number of cards remaining with higher face values than the previously 
* drawn card 
* @return 
*/ 

public abstract int getNumberCardsHigher(); 

/** 
* Get the number of cards remaining with lower face values than the previously 
* drawn card 
* @return 
*/ 

public abstract int getNumberCardsLower(); 

/** 
* Get all cards that have already been drawn in the order they were drawn in 
* 
*/ 

public abstract List<Card> getPlayedCards(); 

/** 
* Simple prediction algorithm - if there are more cards left in the deck with 
* lower face values than the previous card, then predict 'Lower', if there 
* are more cards left in the deck with higher face values then predict 
* 'Higher', if there are equal numbers of higher/lower cards pick 'higher' or  'lower' 
* at random 
* 
* Prediction is an Enum (Higher/Lower/None) 
* 
*/ 

public abstract Prediction getPrediction(); 

/* 
* Draw the next card at random 
*/ 

public abstract void nextRound(); 

/** 
* Specifiy what the next card should be 
* 
* @param card 
*/ 

public abstract void nextRound(Card card); 

} 

正如你可以看到它是所有相當自我解釋和簡單。這裏是我的問題:

我不希望構造函數自動繪製一張卡片。這意味着最初沒有「先前繪製的卡」。我在Prediction枚舉中有一個NO PREDICTION值,但由於沒有「先前繪製的牌」,所以getNumberCardsHigher()getNumberCardsLower()方法不能返回理智值(當套牌中的所有牌都被繪製時,它們不能返回理智值)。

顯然,我可以簡單地拋出一個異常,但這看起來像是矯枉過正 - 尤其是隨後所有對這些方法的調用都必須被包裝在try/catch中。我也不滿意返回一個負值,因爲如果有人忘記/不能檢查它們,很容易導致一些錯誤。

歡迎任何建議!

回答

4

我個人不要認爲在參數檢查的情況下拋出未經檢查的異常根本就是矯枉過正的 - 這是假設你的代碼斷言了一個無效的狀態(你不應該在該狀態下調用那些方法,EVER)。

我通常使用IllegalArgumentException來表明參數已傳入,但不符合方法調用的約定,並且IllegalStateException表明該對象此時不處於方法調用狀態。

因爲它們都是未經檢查的異常,所以您不必嘗試/捕獲它們,只要讓它們冒泡,它們就會執行異常很好的事情 - 它們會給您一個堆棧跟蹤並準確告訴您錯誤的位置包括不正確地調用它的人。

我通常的方式使用某種類型的字符串,你的情況可能是:

throw new IllegalStateException("You cannot call this method until a card has been drawn"); 

按道理它只是沒有意義的問,如果卡比卡更高或更低的那不存在。

現在,如果你的方法實際上拋出異常,那麼你必須繼續並修復你的代碼,這樣它才能在繪製卡之前調用該方法 - 所以你必須弄清楚如何繪製不管你的第一張卡片。

注意:異常僅用於錯誤檢測,避免將它們用於流量控制。這意味着您不應該嘗試捕捉異常並使用它來繪製卡片,然後再次調用!相反,您應該採用這樣的方式進行編程,以保證在第一次調用方法之前繪製卡片。

0

我會爭辯說,如果沒有先前繪製的卡片,這兩種方法都應返回card.count。還有相同數量的更低和更高的卡片,並且對於兩個卡片都有更多更高/更低的卡片。你的算法然後會工作並返回一個NO_PREDICTION

+0

在這種情況下,我認爲這兩種方法都不會返回'card.count'。這個解決方案表明,有13張牌更高,13張牌更低,這意味着總共26張牌,即使在一套西裝和遊戲中只有13張牌。即使我們知道發生了什麼,想象將這些信息呈現給用戶。這似乎是一個非常不滿意的行爲。 – Peter 2010-07-02 16:45:57

+0

@Peter:我的推理如下:一張卡比卡片的缺失更低和更高。這是兩個相反的狀態在虛無概念上是平等的情況之一。這對我來說似乎並不直觀,但這只是我的看法。當沒有卡時,兩者都應該返回0,所以它們在該階段也是相等的。在開始時,它們應該返回相反的0,在這種情況下card.count。 – JRL 2010-07-02 17:05:03

0

我個人建議在玩家做任何事情之前先準備一張初始牌,因爲玩家在第一張牌出現之前做任何事情都沒有意義,但我認爲「我不想讓構造函數自動畫卡「意味着你不想那樣做。如果你不想這樣做,我會讓這些函數拋出異常,並且讓這些調用它們的代碼(預測函數)在遊戲開始時返回「不預測」而不是甚至試圖調用它們。比賽結束並不是特例,這兩個函數應返回0,因爲沒有卡高於或低於其餘的甲板

另外,補卡,沒有必要宣佈各功能abstract在一個接口,它是自動的,需要

+0

關於遊戲結束的有趣(和正確的觀點),我應該想到這一點!但是,我正在尋找使用例外的替代解決方案,甚至徹底改變了我的設計。 – Peter 2010-07-02 16:43:04

+0

爲了清楚起見,我知道您不必將接口方法聲明爲抽象,Eclipse在我提取接口時會自動執行此操作(出於某種原因)。 **希望你可以編輯評論** – Peter 2010-07-02 16:50:25

+0

@Peter你可以,但只有五分鐘:) – 2010-07-02 16:52:25

1

我不希望構造函數自動繪製一張卡片。這意味着最初沒有「先前繪製的卡片」。我在預測枚舉中有一個NO PREDICTION值,但由於沒有「先前繪製的卡片」,getNumberCardsHigher()和getNumberCardsLower()方法不能返回理智值(它們不能在所有卡片都返回時返回理智值已被繪製)。

我覺得API產生了困惑的事實,你PlayYourCardsRight接口試圖兩回事模式:遊戲引擎/規則的撲克牌。我會將卡片組和剩餘卡片計數方法的狀態移至Deck班。我會將API更改爲getNumberCards[Higher/Lower](Card),並讓遊戲引擎指定要比較哪張牌,而不是期待牌組記下哪張牌是最後繪製的,我將其看作是遊戲狀態的一個元素,而不是牌組。

我強烈建議編寫一些JUnit測試。 TDD有助於產生一個有凝聚力的解耦API。