首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在数据结构中存储值Haskell

在数据结构中存储值Haskell
EN

Stack Overflow用户
提问于 2012-03-06 18:09:15
回答 3查看 3.7K关注 0票数 3

我尝试将随机生成的骰子值存储在一些数据结构中,但不知道如何在Haskell中确切地做到这一点。到目前为止,我只能生成随机整数,但我希望能够将它们与相应的颜色值进行比较,并存储颜色(不能真正想象函数会是什么样子)。这是我的代码--

代码语言:javascript
复制
module Main where

import System.IO
import System.Random
import Data.List

diceColor = [("Black",1),("Green",2),("Purple",3),("Red",4),("White",5),("Yellow",6)]
diceRoll = []

rand :: Int -> [Int] -> IO ()
rand n rlst = do
       num <- randomRIO (1::Int, 6)
       if n == 0
        then printList rlst       -- here is where I need to do something to store the values
        else rand (n-1) (num:rlst)

printList x = putStrLn (show (sort x))

--matchColor x = doSomething()

main :: IO ()
main = do
    --hSetBuffering stdin LineBuffering
    putStrLn "roll, keep, score?"
    cmd <- getLine
    doYahtzee cmd
    --rand (read cmd) []

doYahtzee :: String -> IO ()
doYahtzee cmd = do
if cmd == "roll" 
    then do rand 5 []
        else putStrLn "Whatever"

在此之后,我想让用户能够保持相同的骰子(就像它的累积点),并让他们选择在骰子上重新滚动左边的骰子-我认为这可以通过遍历数据结构(带有骰子值)并将重复的骰子计数为点并将其存储在另一个数据结构中来实现。如果用户选择重新滚动,他必须能够再次调用随机数并替换原始数据结构中的值。

我来自OOP背景,而Haskell对我来说是一个新领域。非常感谢您的帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-07 04:27:10

所以,有几个问题,让我们逐一回答:

First:如何使用System.Random中的函数生成整数以外的其他东西(这是一个很慢的生成器,但对于您的应用程序来说,性能并不重要)。有几种方法,对于你的列表,你必须编写一个函数intToColor:

代码语言:javascript
复制
intToColor :: Int -> String
intToColor n = head . filter (\p -> snd p == n) $ [("Black",1),("Green",2),("Purple",3),("Red",4),("White",5),("Yellow",6)]

不是很好。不过,如果你以(键,值)的顺序编写这对代码,你会做得更好,因为在Data.List中有一点对“关联列表”的支持,带有查找函数:

代码语言:javascript
复制
intToColor n = fromJust . lookup n $ [(1,"Black"),(2,"Green"),(3,"Purple"),(4,"Red"),(5,"White"),(6,"Yellow")]

当然,你也可以忘记Int key在列表中从1到6的事情,因为列表已经被Int索引了:

代码语言:javascript
复制
intToColor n = ["Black","Green","Purple","Red","White","Yellow"] !! n

(注意,这个函数有点不同,因为intToColor 0现在是“黑色”,而不是intToColor 1,但考虑到你的目标,这并不是真的很重要,如果它真的让你震惊,你可以写"!!(n-1)“)

但由于您的颜色并不是真正的字符串,而更像是符号,因此您可能应该创建一个Color类型:

代码语言:javascript
复制
data Color = Black | Green | Purple | Red | White | Yellow deriving (Eq, Ord, Show, Read, Enum)

所以现在黑色是一个颜色类型的值,你可以在你的程序中的任何地方使用它(如果你写了Blak,GHC会抗议),多亏了自动派生的魔力,你可以比较颜色值,或显示它们,或使用toEnum将Int转换为颜色!

所以现在你可以写:

代码语言:javascript
复制
randColorIO :: IO Color
randColorIO = do
   n <- randomRIO (0,5)
   return (toEnum n)

对于第二个,您希望在数据结构中存储骰子值(颜色),并提供保持相同投掷的选项。因此,首先应该存储几次抛出的结果,考虑到同时抛出的最大数量(5)和数据的复杂性,一个简单的列表就足够了,并且考虑到在Haskell中处理列表的函数数量,它是一个很好的选择。

所以你想掷几个骰子:

代码语言:javascript
复制
nThrows :: Int -> IO [Color]
nThrows 0 = return []
nThrows n = do
   c <- randColorIO
   rest <- nThrows (n-1)
   return (c : rest)

这是一个很好的第一种方法,这就是你所做的,或多或少,除非你使用if而不是模式匹配,并且你有一个显式的累加器参数(你打算使用尾部递归吗?),除了严格的累加器(Int而不是lists),并不是更好。

当然,Haskell推广高阶函数,而不是直接递归,所以让我们看看组合符,用Hoogle搜索"Int -> IO a -> IO a“会给出:

代码语言:javascript
复制
replicateM :: Monad m => Int -> m a -> m [a]

它做的正是你想要的:

代码语言:javascript
复制
nThrows n = replicateM n randColorIO

(我甚至不确定我会把它写成一个函数,因为我发现显式表达式更清晰,而且几乎一样简短)

一旦你有了抛出的结果,你应该检查哪些是相同的,我建议你看看排序,分组,映射和长度来实现这个目标(将你的结果列表转换成相同结果的列表,不是最有效的数据结构,但在这种规模下,是最合适的选择)。然后,将你得到的颜色保留几次只需使用滤镜即可。

然后你应该写一些更多的函数来处理交互和评分:

代码语言:javascript
复制
type Score = Int
yahtzee :: IO Score
yahtzeeStep :: Int -> [[Color]] -> IO [[Color]] -- recursive
scoring :: [[Color]] -> Score

因此,我建议保留并传输一个[Color],以跟踪被放在一边的内容。这应该足以满足您的需求。

票数 7
EN

Stack Overflow用户

发布于 2012-03-06 19:12:43

你在这里基本上问了两个不同的问题。第一个问题可以用getColor n = fst . head $ filter (\x -> snd x == n) diceColor这样的函数来回答。

然而,你的第二个问题要有趣得多。您不能替换元素。你需要一个可以递归调用自身的函数,这个函数将驱动你的游戏。它需要接受当前得分和保留的骰子列表作为参数。一旦进入,分数将为零,所保存的骰子列表将为空。然后,它将根据需要掷出尽可能多的骰子来填充列表(我不熟悉Yahtzee的规则),将其输出给用户,并要求选择。如果用户选择结束游戏,该函数将返回分数。如果他选择保留一些骰子,该函数将使用当前得分和保留的骰子列表调用自己。所以,总结一下,playGame :: Score -> [Dice] -> IO Score

免责声明:我也是Haskell的初学者。

票数 3
EN

Stack Overflow用户

发布于 2012-03-06 18:31:48

首先想到的是:

代码语言:javascript
复制
rand :: Int -> IO [Int]
rand n = mapM id (take n (repeat (randomRIO (1::Int, 6))))

尽管haskeller可以删除括号

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9581521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档