Function 我怎样才能从哈斯凯尔的牌组中抽出那么多的牌

Function 我怎样才能从哈斯凯尔的牌组中抽出那么多的牌,function,haskell,blackjack,Function,Haskell,Blackjack,在这个程序中,我想询问用户卡的数量,并从一副牌中抽出该数量的卡(见下文),然后告诉用户卡和 “总计”这些卡片。在这种情况下,我指的是21点计数,加上 计数超过21,不返回任何内容。21点计数的面值为2-10,jacks, 皇后和国王算作10,王牌算作1或11。我需要两个功能: drawHand::Int->Deck->([Card],Deck)和totalCards::[Card]->可能Int 导入数据。列表 导入数据。随机 drawHand::Int->Deck->([卡片],卡片组) to

在这个程序中,我想询问用户卡的数量,并从一副牌中抽出该数量的卡(见下文),然后告诉用户卡和 “总计”这些卡片。在这种情况下,我指的是21点计数,加上 计数超过21,不返回任何内容。21点计数的面值为2-10,jacks, 皇后和国王算作10,王牌算作1或11。我需要两个功能:
drawHand::Int->Deck->([Card],Deck)
totalCards::[Card]->可能Int

导入数据。列表
导入数据。随机
drawHand::Int->Deck->([卡片],卡片组)
totalCards::[Card]->可能是Int
main=do
putStrLn“多少张牌?”
随机::MonadRandom=>Deck->m Deck
Random ran=runRVar(洗牌牌组)StdRandom

随机此时,我们没有关于
数据类型的信息

然而,目前的问题似乎是从最初的N张牌中随机抽取M张牌

如果这个问题的解释是正确的,那么我们就可以使用
Rand
monad构造函数,从定义一个只将一张牌从右牌组转移到左牌组的单子动作开始

由于我们没有关于正在使用的类型的信息,我们将假设“卡片”由普通数字表示,从0到51

接下来,我们定义一个动作,递归移动M张卡,移动一张卡,然后用(M-1)参数调用我们自己。对于M=0,我们将动作定义为no-op

这将是一元代码:

import  System.Random
import  Control.Monad.Random


moveOneCardLeft :: RandomGen g => ([a],[a]) -> Rand g ([a],[a])
moveOneCardLeft (deck, rest) =
    do
        let  remCount = length rest
        choice <- getRandomR (0, (remCount-1))
        let  (top, bot) = splitAt choice rest
        return $ ((head bot) : deck, top ++ (tail bot))


moveSomeCardsLeft :: RandomGen g => Int -> ([a],[a]) -> Rand g ([a],[a])
moveSomeCardsLeft 0 (deck, rest) = return (deck, rest)  -- unchanged
moveSomeCardsLeft n (deck, rest) =
    do
        (deck1, rest1) <- moveOneCardLeft (deck, rest)
        (deck2, rest2) <- moveSomeCardsLeft (n-1) (deck1, rest1)
        return (deck2, rest2)


extractSomeCards :: RandomGen g => Int -> [a] -> Rand g ([a], [a])
extractSomeCards n xs =
    do
        (deck, rest) <- moveSomeCardsLeft n ([], xs)
        return (deck, rest)
注意:如果认为合适,可以使用包中的
nest::Monad m=>Int->(a->ma)->a->ma
函数简化上述
moveOneCardLeft
之外的代码

像这样:

import  Control.Monad.HT  (nest)

moveOneCardLeft :: RandomGen g => ([a],[a]) -> Rand g ([a],[a])
moveOneCardLeft (deck, rest) =
    do
        let  remCount = length rest
        choice <- getRandomR (0, (remCount-1))
        let  (top, bot) = splitAt choice rest
        return $ ((head bot) : deck, top ++ (tail bot))

drawSomeCards :: RandomGen g => g -> Int -> [a] -> (([a], [a]), g)
drawSomeCards gen0 n xs = let action = nest n moveOneCardLeft ([], xs)
                          in  runRand action gen0
import Control.Monad.HT(嵌套)
moveOneCardLeft::RandomGen g=>([a],[a])->兰德g([a],[a])
moveOneCardLeft(甲板,休息)=
做
让remCount=剩余长度
选择g->Int->[a]->(([a],[a]),g)
drawSomeCards gen0 n xs=let action=nest n moveOneCardLeft([],xs)
在runRand action gen0中

错误告诉您GHC找不到
数据.Random
-在
Random
包中有一个
系统.Random
-可能是您想要的?关于您的两个函数,可能更紧迫、更有趣的问题是:到目前为止您尝试了什么?任何起点?一个猜测:
totalCards[]=Nothing
totalCards xs=Just(length xs)
。。。没有线索-您没有给出
牌组
的定义(我想
类型牌组=[Card]
是因为
洗牌
?)@丹尼尔·瓦格纳——我认为这个问题最终会被解决,但我不认为这真的是你的问题的翻版linked@Carsten询问者有责任确定他们想问什么问题。如果你想让它成为读者的责任,并将问题从问题扩展到完整的问题,那么我对此没有意见,但解决方案仍然很接近(这次是因为没有足够的针对性)。因此,看起来“像复制一样接近”至少和其他选项一样是一个好的结果——因为它至少可以帮助他们解决一个问题,而不是一个问题都没有。
drawSomeCards :: RandomGen g => g -> Int -> [a] -> (([a], [a]), g)
drawSomeCards gen0 n xs = runRand (extractSomeCards n xs) gen0

cardValue :: Int -> Int
cardValue n = let rank = mod n 13
              in  if (rank < 10) then (rank+1)
                                 else {- Jack Queen King -} 10

deckValue :: [Int] -> Int
deckValue cards = sum (map cardValue cards)

totalOfCards :: [Int] -> Maybe Int
totalOfCards cards =
    let  s = deckValue cards
    in   if (s <= 21)  then  (Just s)  else  Nothing

main = do
    let  wholeDeck  = [0..51]
         randomSeed = 4243
         gen0 = mkStdGen randomSeed
    putStrLn "How many cards ?"
    inLine <- getLine
    let count = (read inLine :: Int)
    putStrLn $ "Want to extract " ++ (show count) ++ " cards."

    let  ((deck, rest), gen1) = drawSomeCards gen0 count wholeDeck
         sumw = sum wholeDeck
         suma = sum deck
         sumb = sum rest
         sum0 = (suma + sumb) - sumw
    putStrLn $ "Must be zero: " ++ (show sum0)   -- sanity check
    putStrLn $ "deck: " ++ (show deck)
    putStrLn $ "rest: " ++ (show rest)
    putStrLn $ "Deck value: " ++ (show $ deckValue deck)
$ q67025780.x
How many cards ?
10
Want to extract 10 cards.
Must be zero: 0
deck: [8,47,38,49,4,31,9,30,28,23]
rest: [0,1,2,3,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,29,32,33,34,35,36,37,39,40,41,42,43,44,45,46,48,50,51]
Deck value: 77
$ 

import  Control.Monad.HT  (nest)

moveOneCardLeft :: RandomGen g => ([a],[a]) -> Rand g ([a],[a])
moveOneCardLeft (deck, rest) =
    do
        let  remCount = length rest
        choice <- getRandomR (0, (remCount-1))
        let  (top, bot) = splitAt choice rest
        return $ ((head bot) : deck, top ++ (tail bot))

drawSomeCards :: RandomGen g => g -> Int -> [a] -> (([a], [a]), g)
drawSomeCards gen0 n xs = let action = nest n moveOneCardLeft ([], xs)
                          in  runRand action gen0