Bergervei/Zahlenraten

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</language>
<code id="4d49e6cdee0e4" hidden>
;-- M. Hielscher / Chr. Wagenknecht --
(define random-maker
  (let* ((multiplier 48271)
         (modulus 2147483647)
         (apply-congruence
          (lambda (current-seed)
            (let ((candidate (modulo (* current-seed multiplier) modulus)))
              (if (zero? candidate)
                  modulus
                  candidate))))
         (coerce
          (lambda (proposed-seed)
            (if (integer? proposed-seed)
                (- modulus (modulo proposed-seed modulus)) 19880214))))
  (lambda (initial-seed)
    (let ((seed (coerce initial-seed)))
      (lambda args
        (cond ((null? args)
               (set! seed (apply-congruence seed))
               (/ (- modulus seed) modulus))
              ((null? (cdr args))
               (let* ((proposed-top
                       (ceiling (abs (car args))))
                      (exact-top
                       (if (inexact? proposed-top)
                           (inexact->exact proposed-top)
                           proposed-top))
                      (top
                       (if (zero? exact-top)
                           1
                           exact-top)))
                 (set! seed (apply-congruence seed))
                 (inexact->exact (floor (* top (/ seed modulus))))))
              ((eq? (cadr args) 'reset)
               (set! seed (coerce (car args))))
              (else
               (display "random: unrecognized message")
               (newline))))))))

(require-library 'sisc/libs/srfi/srfi-19)
(import srfi-19)

(define random (random-maker (time-nanosecond (current-time))))
</code>

== Raten einer Zahl ==

Wir kennen das einfache Spiel zum Raten einer Zahl <math>z</math> im Intervall <math>1 \le z \le max</math>:<br />
Aus einem zuvor vereinbarten Intervall denkt sich ein Spieler eine Zahl, die sein Mitspieler erraten muss. Nach jedem Versuch erhält der Mitspieler den Hinweis, ob seine vermutete Zahl kleiner bzw. größer als die erdachte Zahl ist oder sogar mit ihr übereinstimmt. Die erdachte Zahl soll so mit einem Minimum an Versuchen erraten werden.<br />
Zunächst spielen wir gegen den Computer und erraten eine Zufallszahl:

<code id="4d49e6cdee151">
(define zufzahl
  (lambda (max)
    (+ 1 (random max))))

(define spielerraten
  (lambda (max)
    (letrec
        ([suche
          (lambda (z anzahl)
            (let ([zahl (string->number (inputdialog "Deine Zahl:"))])
              (cond
                [(= z zahl) 
                   (string-append "Glueckwunsch, Du hast " (number->string zahl) 
                                  " mit " (number->string anzahl) " Versuch(en) erraten!")]
                [(< z zahl) 
                   (showmessage (string-append "Die Zahl " (number->string zahl) " ist zu groß!"))
                   (suche z (+ 1 anzahl))]
                [else
                   (showmessage (string-append "Die Zahl " (number->string zahl) " ist zu klein!"))
                   (suche z (+ 1 anzahl))])))])
      (suche (zufzahl max) 1))))
</code>

<run id="4d49e6cdee1de">
(spielerraten 100)
</run>