2013-10-25 65 views
0

嗨,我有問題總結我的手,因爲一個Ace可以是1或11.我怎樣才能使一個功能,需要在手中,即[卡]並計算總值?哈斯克爾21點遊戲

這是我到目前爲止有:

其中val已經定義並從卡返回值的數組
handValue :: [Card]->[Int] 
handValue [] = 0 
handValue (x:xs) = sum((val x)++([handValue xs])) 

。 val(「Ace」,「Hearts」)給出[1,11] val(「Five」,「Hearts」)給出[5]

任何指針將不勝感激。

編輯:duplodes建議後,我有這樣的:

handValue :: [Card]->[Int] 
handValue [] = 0 
handValue (x:xs) = 
      if (val x ==[1,11]) 
      then (map sum (sequence [[1,11], handValue xs])) 
       else [ sum [(val x)]++([handValue xs])] 

回答

1

除了固定的功能,你應該注意它爲什麼沒有排在首位的工作。首先,你給的類型是

handValue :: [Card] -> [Int] 

,但你的遞歸定義有單一的價值觀,而不是清單,結果類型(在0文字的第一個等式中,使用sum,這是第二個Num a => [a] -> a )。

現在,假設類型更改爲[Card] -> Int,您的定義將是合法的,但結果會很奇怪。你的第二個等式是:

handValue (x:xs) = sum((val x)++([handValue xs])) 

如果x是一個ace會發生什麼? val x將是[1, 11],所以兩個值將被連接幷包括在總和中。實際上,現在你的王牌不是1或11,而是12分!納米的解決方案,我意譯這裏作爲解決該問題

Prelude> map sum . sequence $ [[1,11], [5], [6]] 
[12,22] 

裙通過生成值列表王牌(sequence)的所有可能的選擇和所有的可能性分別(map sum)求和,產生的值的列表(如最初給出的簽名一樣)。但是,這並不能解決問題,因爲您最終需要決定其中一種可能性。現在,我們可能有足夠的材料來解決不同的問題,一旦你達到那個點...

+1

這是一個機械的選擇,是否將一個王牌視爲1或11:將其視爲11,除非總分將超過21。用戶不需要選擇。 IOW,我認爲n.m.的解決方案是一個很好的方法(如果只有人會解釋它爲什麼會起作用)。 – luqui

+0

我對紙牌遊戲的無知已經顯現出來......在任何情況下,這意味着應該有一個自動決定覈算手的部分總數或從nm選擇小於或等於21的最大和的方式「解決方案。 – duplode

+0

@duplode我看不出如何在我的例子中使用它。我編輯了我的解決方案。 – John

1
Prelude Control.Monad> liftM sum . sequence $ [[1,11], [5], [6]] 
[12,22] 
+0

是的,但是爲什麼?... – luqui

+0

爲什麼?它爲什麼有效?爲什麼它屬於?爲什麼張貼答案並破壞樂趣? –

+0

@ n.m。我明白要使用順序,但我無法得到它的工作,看我的例子。 – John