Игровая петля для ракетки
Я работаю над очень простой игрой в память в RACKET, которая представляет пользователю 7 случайных чисел от 1 до 10 и просит их ввести цифры в том же порядке. Я могу заставить это работать один раз, но я хочу, чтобы он работал непрерывно, пока пользователь не выйдет. (Повторите ОСНОВНУЮ ПРОГРАММУ) Любые идеи о том, как этого добиться???
(require math/base)
; =======================================
; Functions
; =======================================
; set essentially constants
(define lowerLimit 1)
(define upperLimit 11)
(define amount 7)
; builds a list with random integers between lowerLimit and upperLimit
(define (buildSimon x L)
(cond [(= x 0) L]
[else (buildSimon (- x 1) (cons (random-integer lowerLimit upperLimit) L))]))
; adds element to back of the list
(define (addBack L e)
(if (null? L)
(list e)
(cons (first L) (addBack (rest L) e))))
; gets input from user and builds list
(define (getInput n x L)
(cond [(= n 1) (addBack L x)]
[else (getInput (- n 1) (read) (addBack L x))]))
; =======================================
; Main program below here
; =======================================
; Generate new random number sequence
(printf "Simon says: ")
(define sequence (buildSimon amount (list)))
(display sequence) (newline)
(printf "== Memorize and guess ==\n")
(printf "== Type 'go' and hit enter to guess ==\n")
(read)
; Add spacing to hide numbers
(printf "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
(printf "== Type the numbers in order as they appeared. ==\n")
(printf "== Hit ENTER in between each number. ==\n")
; Gather input for comparison
(define answer (getInput amount (read) (list)))
; Do comparison
(if (equal? sequence answer)
(printf "Correct! Congratulations on your perfect memory.\n")
(printf "Wrong! I'm sorry your memory has failed you.\n"))
Заранее спасибо.
2 ответа
Вы можете создать функцию, которая содержит весь ваш основной код, а последняя строка функции рекурсивно вызывает сама себя.
Как уже было сказано, вы можете использовать простую рекурсивную функцию:
(define (game-loop)
(let ([finished? (run-your-code)])
(unless finished?
(game-loop))))
(game-loop)
где (run-your-code)
это функция, которая генерирует текущее состояние игры и решает, закончена ли она или требуется еще один запуск, на основе пользовательского ввода.
В качестве альтернативы вы можете использовать цикл while, но я считаю это менее элегантным, чем приведенное выше решение. И код не сильно изменится, если только мы не рассмотрим использование изменяемых состояний игры. Тогда код будет выглядеть примерно так:
(define (game-loop)
(while (done? game-state)
(render-next-step game-state)))
(game-loop)
Другой способ будет использовать #:break
в бесконечном цикле:
(define (game-loop)
(for ([i (in-naturals)]
#:break (done? game-state))
(render-next-step game-state)))
(game-loop)
опять же, используя изменяемое состояние игры.
Но это всего лишь некоторые идеи (и вы также можете избавиться от изменчивости, сделав текущее состояние параметром game-loop
). И вы должны инкапсулировать весь код после "Основная программа ниже здесь" в game-loop
функция, чтобы сделать вещи проще.