【问题标题】:(Random) in Common Lisp Not So Random?Common Lisp 中的(随机)不是那么随机吗?
【发布时间】:2011-05-01 08:20:22
【问题描述】:

好的,最后一个问题,我将用 Common Lisp 完成我的猜数字游戏! :D 每当游戏开始时(或在第一场比赛后开始新的比赛),都会调用以下函数。

;;; Play the game
(defun play ()
    ;; If it's their first time playing this session,
    ;; make sure to greet the user.
    (unless (> *number-of-guesses* 0)
        (welcome-user))
    ;; Reset their remaining guesses
    (setq *number-of-guesses* 0)
    ;; Set the target value
    (setq *target*
        ;; Random can return float values,
        ;; so we must round the result to get
        ;; an integer value.
        (round
            ;; Add one to the result, because
            ;; (random 100) yields a number between
            ;; 0 and 99, whereas we want a number
            ;; from 1 to 100 inclusive.
            (+ (random 100) 1)))
    (if (eql (prompt-for-guess) t)
        (play)
        (quit)))

所以按理说,每次玩家开始游戏时,*target* 应该被设置为 1-100 之间的新随机整数。但是,*target* 每次都默认为 82。如何让(random) 随机执行...?

【问题讨论】:

    标签: random lisp common-lisp sbcl


    【解决方案1】:

    您需要在程序开始时播种随机状态。

    (setf *random-state* (make-random-state t))
    ;; # this initializes the global random state by
    ;;   "some means" (e.g. current time.)
    

    【讨论】:

    • 评论不一定正确。 CL 规范没有强制使用当前时间,它只是说“通过某种方式随机初始化”。
    • 至少在 CCL 中,random 必须在 *random-state* 的词法范围内调用以导致结果发生变化,例如,使用 let
    【解决方案2】:

    我认为如果你定义一个带有随机数的函数,当你调用函数时它不会被调用,实际上,它会在你加载文件时确定,当它运行这个定义时它被固定为那个值。然后您每次都调用该函数,数字将始终相同。当我每次调用一个随机变量时,它每次都是随机的。至少,这是我在我的程序中所经历的

    【讨论】:

    • 这是错误的。 random 是一个函数,像许多其他函数一样依赖于副作用。它在与任何其他函数调用相同的情况下进行评估。如果在宏中调用它(而不是与返回的调用对应的形式),那么它将返回一个数字,而不是一些计算为随机数的特殊对象(请注意,这样的特殊对象将是类似的形式(random 1.0))。也许这就是你的意思。
    猜你喜欢
    • 2018-03-29
    • 1970-01-01
    • 2012-04-24
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2021-12-10
    • 2012-10-04
    相关资源
    最近更新 更多