我正在计划中编写一个小型的刽子手游戏,并且得到了一个非常奇怪的问题,几乎看起来像是一个语言特定的问题。
在我的游戏中,我有一个变量,它保存了允许的错误数量,并且在我的游戏循环的每次递归调用中,如果需要更改,我将“值”设置为新值。这里有一些代码可以帮助我们了解如何运行游戏循环。
guessed_list - 包含旧猜测和一个新猜测的字符串字符列表(例如'(“a”“x”“b”),其中“a”是新猜测)
game_word - '(“a”“b”“c”)
display_word - 包含我已匹配的字母的字符串字符列表,以及那些我没有达到游戏循环迭代次数的字符串(ex'(“”“b”“”))其中来自guessed_list的“a”将被评估此循环迭代)
mistakes_left - 由于错误的猜测,我在比赛前的错误数量应该结束。最初这是从6开始,但在我当前的例子中应该是5,因为1个字母“x”被猜错了。
;; Game Loop.
(define (game-loop guessed_list display_word mistakes_left)
(let ((n_mistakes_left
(- mistakes_left (if (contains? game_word (car guessed_list))
0 1))))
(if (= n_mistakes_left 0)
(display n_mistakes_left);; End game output
(let ((display_word (fill-in-guess (list (car guessed_list))
game_word display_word))
(guessed_list (sort guessed_list string<?)))
(display "You have guessed: ")
(display-list guessed_list ", ")
(display "\n\n")
(draw-hangman n_mistakes_left)
(display "\n\nWord: ")
(display-list display_word " ")
(cond ((contains? display_word "_")
(display "\n\nEnter a letter to guess: ")
(game-loop (append (list (symbol->string (read))) guessed_list)
display_word n_mistakes_left))
(else (display "\n\nYou Won!")))))))
我可以发布我的帮助方法包含?,fill-in-guess,display-list,draw-hangman,如果有必要,但是所有这些方法都可以正常运行,并且不会为了它们的功能而更改my mist_left变量的值。 / p>
我遇到的问题是我的mistakes_left变量从6开始并在游戏循环的第一次调用时通过罚款,但在后续调用中,即使在猜测正确的值时也会变小。我已经单独拍摄了每一件作品,并对其进行了测试,并且错误地给出了正确的值,直到我递归为止。
我怀疑它与递言和“让”我的变量有关,但如果有人可以或指出我遗漏的最可能的简单错误,我想要一个不同的答案!
编辑:
以下是要测试的其余代码,我仍然遇到问题。我认为追加工作是因为它将第二个列表附加到第一个列表,所以在这个意义上,cons和append给了我相同的输入。
(define zero_wrong "
|---------
| |
|
|
|
|
|
|
|
|_______________")
(define one_wrong "
|---------
| |
___
| |. .|
---
|
|
|
|
|
|
|_______________")
(define two_wrong "
|---------
| |
___
| |. .|
---
| |
|
| |
|
|
|
|
|
|_______________")
(define three_wrong "
|---------
| |
___
| |. .|
---
| |
|----
| |
|
|
|
|
|
|_______________")
(define four_wrong "
|---------
| |
___
| |. .|
---
| |
----|----
| |
|
|
|
|
|
|_______________")
(define five_wrong "|---------
| |
___
| |. .|
---
| |
----|----
| |
|
| \\
\\
|
|
|
|_______________")
(define six_wrong "|---------
| |
___
| |x x|
---
| |
----|----
| |
|
| / \\
/ \\
|
|
|
|_______________")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Read list value at x.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (get-str-at x str_lst)
(cond ((equal? x 0)
(car str_lst))
(else
(get-str-at (- x 1) (cdr str_lst))
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Car operation for strings.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (string-car str)
(substring str 0 1)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cdr operation for strings.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (string-cdr str)
(substring str 1 (string-length str))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Converts a string into a
;; list of character strings.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (string-to-char-string-list str)
(cond
((equal? (string-cdr str) "")
(list str)
)
(
(append (list (string-car str)) (string-to-char-string-list (string-cdr str)))
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Tests if a list contains a spefified object.
;;
;; Method code from:
;; http://stackoverflow.com/questions/1869116/scheme-built-in-to-check-list-containment
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (contains? list item)
(if (empty? list)
#f
(or (eq? (first list) item)
(contains? (rest list) item)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Displays a list with the
;; given separater.
;;
;; Base code from:
;; ftp://ftp.cs.utexas.edu/pub/garbage/cs345/schintro-v13/schintro_99.html
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (display-list a_list separater)
(if (null? a_list)
(display "")
(begin
(display (car a_list))
(if (null? (cdr a_list))
(display "")
(display separater))
(display-list (cdr a_list) separater)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Gets the Xth word in the
;; provided file.
;;
;; Does not check for eof
;; condition, so x must be
;; within range of the file.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (get-word x file)
(cond
((= 1 x)
(read file))
(else
(read file)
(get-word (- x 1) file)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Returns a list of blanks
;; equal to the number of
;; letters in provided word.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (init-display-word game_word)
(cond
((null? game_word)
(list))
(else
(append (init-display-word (cdr game_word)) '("_"))
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fills in the blank spaces
;; in the display word with
;; the letter that matches
;; those positions in the
;; game word.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (fill-in-guess letter game_word display_word)
(cond
((null? game_word)
(list)
)
(else
(cond
((equal? letter (list (car game_word)))
(append letter (fill-in-guess letter (cdr game_word) (cdr display_word)))
)
(else
(append (list (car display_word)) (fill-in-guess letter (cdr game_word) (cdr display_word)))
)
)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Draws the hanging man.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (draw-hangman guesses_left)
(cond ((equal? guesses_left 6)
(display zero_wrong))
(else (cond ((equal? guesses_left 5)
(display one_wrong))
(else (cond ((equal? guesses_left 4)
(display two_wrong))
(else (cond ((equal? guesses_left 3)
(display three_wrong))
(else (cond ((equal? guesses_left 2)
(display four_wrong))
(else (cond ((equal? guesses_left 1)
(display five_wrong))
(else (display six_wrong))
)))))))))))
)
答案 0 :(得分:1)
我对您的代码进行了一些修改。我在功能上面用注释标记了我的更改,并解释了它们。你的问题是你排序guessed_list
。没有必要这样做。我测试了它,它的工作原理。请记住,如果您使用空的猜测列表调用game-loop
,则会出错。要解决此问题,您需要测试guessed_list
是否为空,并且还为减法返回0。我会把它留给你。
此外,在您的代码中的许多地方,您嵌套了cond
s这是没有必要的。请在此处阅读:cond
(define game_word '("a" "b" "c"))
(define zero_wrong "
|---------
| |
|
|
|
|
|
|
|
|_______________")
(define one_wrong "
|---------
| |
___
| |. .|
---
|
|
|
|
|
|
|_______________")
(define two_wrong "
|---------
| |
___
| |. .|
---
| |
|
| |
|
|
|
|
|
|_______________")
(define three_wrong "
|---------
| |
___
| |. .|
---
| |
|----
| |
|
|
|
|
|
|_______________")
(define four_wrong "
|---------
| |
___
| |. .|
---
| |
----|----
| |
|
|
|
|
|
|_______________")
(define five_wrong "|---------
| |
___
| |. .|
---
| |
----|----
| |
|
| \\
\\
|
|
|
|_______________")
(define six_wrong "|---------
| |
___
| |x x|
---
| |
----|----
| |
|
| / \\
/ \\
|
|
|
|_______________")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Read list value at x.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (get-str-at x str_lst)
(cond ((equal? x 0)
(car str_lst))
(else
(get-str-at (- x 1) (cdr str_lst)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Car operation for strings.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (string-car str)
(substring str 0 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cdr operation for strings.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; *** This is enough.
(define (string-cdr str)
(substring str 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Converts a string into a
;; list of character strings.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (string-to-char-string-list str)
(cond
((equal? (string-cdr str) "")
(list str))
((append (list (string-car str)) (string-to-char-string-list (string-cdr str))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Tests if a list contains a spefified object.
;;
;; Method code from:
;; http://stackoverflow.com/questions/1869116/scheme-built-in-to-check-list-containment
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (contains? list item)
(if (empty? list)
#f
(or (string=? (first list) item)
(contains? (rest list) item))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Displays a list with the
;; given separater.
;;
;; Base code from:
;; ftp://ftp.cs.utexas.edu/pub/garbage/cs345/schintro-v13/schintro_99.html
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (display-list a_list separater)
(if (null? a_list)
(display "")
(begin
(display (car a_list))
(if (null? (cdr a_list))
(display "")
(display separater))
(display-list (cdr a_list) separater))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Gets the Xth word in the
;; provided file.
;;
;; Does not check for eof
;; condition, so x must be
;; within range of the file.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (get-word x file)
(cond
((= 1 x)
(read file))
(else
(read file)
(get-word (- x 1) file))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Returns a list of blanks
;; equal to the number of
;; letters in provided word.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (init-display-word game_word)
(cond
((null? game_word)
(list))
(else
(append (init-display-word (cdr game_word)) '("_")))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fills in the blank spaces
;; in the display word with
;; the letter that matches
;; those positions in the
;; game word.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; No need for append here. Just use cons when adding to the start of the list.
; No need to nest conds
(define (fill-in-guess letter game_word display_word)
(cond
((null? game_word)
'())
((equal? letter (car game_word))
(cons letter (fill-in-guess letter (cdr game_word) (cdr display_word))))
(else
(cons (car display_word)
(fill-in-guess letter (cdr game_word) (cdr display_word))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Draws the hanging man.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; You used cond as an if/else statement. You can have multiple clauses in a cond.
; You only need one final else cluase.
(define (draw-hangman guesses_left)
(cond ((equal? guesses_left 6)
(display zero_wrong))
((equal? guesses_left 5)
(display one_wrong))
((equal? guesses_left 4)
(display two_wrong))
((equal? guesses_left 3)
(display three_wrong))
((equal? guesses_left 2)
(display four_wrong))
((equal? guesses_left 1)
(display five_wrong))
(else (display six_wrong))))
; Don't sort the guessed-list.
; You had display when guess left was 0. Not draw_hagman
(define (game-loop guessed_list display_word mistakes_left)
(let ((n_mistakes_left
(- mistakes_left (if (contains? game_word (car guessed_list))
0 1))))
(if (= n_mistakes_left 0)
(draw-hangman n_mistakes_left);; End game output
(let ((display_word (fill-in-guess (car guessed_list)
game_word display_word)))
(display "You have guessed: ")
(display-list guessed_list ", ")
(display "\n\n")
(draw-hangman n_mistakes_left)
(display "\n\nWord: ")
(display-list display_word " ")
(cond ((contains? display_word "_")
(display "\n\nEnter a letter to guess: ")
(game-loop (cons (symbol->string (read)) guessed_list)
display_word n_mistakes_left))
(else (display "\n\nYou Won!")))))))
答案 1 :(得分:0)
我将问题概括为不关注它的刽子手方面。该问题得到了立即回答,并且评论进一步解释了错误的原因。您可以在这篇文章中找到所有这些信息:Scheme Recursion Loop Incorrect Values and Variable Binding。