(Random) in Common Lisp Not So Random?
Asked Answered
B

3

19

Okay, final question and I'll have finished my number guessing game in Common Lisp! :D Whenever the game starts (or a new game begins after the first game), the following function is called.

;;; 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)))

So supposedly, each time the player starts a game, *target* should be set to a new random integer between 1-100. However, each time, *target* defaults to 82. How do I make (random) act... randomly?

Bywaters answered 27/10, 2010 at 13:57 Comment(0)
P
34

You need to seed the random state at the start of the program.

(setf *random-state* (make-random-state t))
;; # this initializes the global random state by
;;   "some means" (e.g. current time.)
Proline answered 27/10, 2010 at 14:4 Comment(3)
The comment is not necessarily correct. The CL specification does not mandate using the current time, it just says "randomly initialized by some means".Buss
In CCL at least, random must be called in the lexical scope of *random-state* to cause a change of the results, e.g., with let.Dwanadwane
@TorstenAnders : there is no lexical binding for *random-state*. It's a special variable.Kriss
S
0

I think that if you define a function with a random number in it, it is not called when you call the function, actually, it will be determined when you load in the file and when it runs this definition it is fixed to that value. Then you are calling the function each time, the number will always be the same. When I passed in a variable to the function with a random each time it was called, then it was random each time. At least, that what I experienced in my program

Spooky answered 16/4, 2018 at 2:51 Comment(1)
This is false. random is a function and relies on side effects like many others. It is evaluated in the same circumstances as any other function call. If it is called in a macro (rather than a form corresponding to a call to it being returned) then it will return a single number and not some special object which evaluates to random numbers (note that such a special object would be a form like (random 1.0)). Perhaps that is what you mean.Craigcraighead
L
-1

In Gimp Scheme (Lisp derivative) I found that I needed to use the following: (set! *seed* (car (gettimeofday))) This is the Random Number Seed From Clock (seed is global)

You may also need: (random-next) This generates the next Random Number Using Seed

The non-truly random method is to set the seed: (srand 12345) ; used in cases where the result is to be repeatable - useful in graphic design contexts.

Laocoon answered 28/7, 2022 at 8:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.