如何在SML中获取自定义数据类型的随机值?

问题描述

对于以下数据类型,如何返回随机值?

datatype rank = Jack | Queen | King | Ace | Num of int

我正在研究一个函数,该函数会生成随机卡的列表以输入到另一个函数,因此也需要类似的函数来适合西装。

输出应为Jack,King等符号,或2到9之间的整数。

以下代码不正确:

fun pick_rank() =
   case Random.randRange(2,13)  of 13 => Ace
               | 12 => King
               | 11 => Queen
               | 10 => Jacl
               | Int v => v

解决方法

对于以下数据类型,如何返回随机值?

datatype rank = Jack | Queen | King | Ace | Num of int

我有两个答案:要么唯一地生成每个值,要么生成所有可能的值,将它们混洗并选择一个。如果只想隔离一个随机变量,则前者是最简单的。但是,如果您要模拟不能两次绘制同一张纸牌的纸牌游戏,那么您可能需要随机播放。

您可以看到我是如何制作command-line blackjack game的。在这里我将重复两种方法:

(* There are 13 card ranks,4 suits *)
datatype rank
  = Ace | Two | Three | Four | Five | Six | Seven
  | Eight | Nine | Ten | Jack | Queen | King

datatype suit = Hearts | Clubs | Diamonds | Spades

datatype card = Card of suit * rank

fun concatMap f xs = List.concat (List.map f xs)
fun product xs ys = concatMap (fn x => map (fn y => (x,y)) ys) xs

val allCards = map Card
  (product
     [Hearts,Clubs,Diamonds,Spades]
     [Ace,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King])

(* Create a new pseudo-random number generator,prng *)
val prng = Random.newgen ()

(* rlist determines a random index in [0 ; length xs[. *)
fun rlist xs = Random.range (0,length xs) prng

(* remove removes the n'th element of a list *)
fun remove (_,[]) = raise Domain
  | remove (0,card::library) = library
  | remove (n,card::library) = card::remove (n-1,library);

(* randomtake removes and returns the i'th (random) element of a list *)
fun randomtake library =
    let val i = rlist library
        val card = List.nth (library,i)
        val rest = remove (i,library)
    in
      (card,rest)
    end

(* Shuffling is done by removing random cards until there are no cards left *)
fun shuffle [] = []
  | shuffle cards =
    let val (c,r) = randomtake cards
    in
      c :: shuffle r
    end

使用这些功能,您可以通过执行randomtake allCards来选择一张随机卡,或者可以选择任意数量的随机卡而无需先shuffle allCards来选择同一张卡,然后选择顶部的元素。

请注意,这些不是有效的方法。作为练习,您可以实现Fisher-Yates shuffle

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...