首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归格式函数值误差

递归格式函数值误差
EN

Stack Overflow用户
提问于 2014-10-01 05:52:47
回答 2查看 219关注 0票数 1

我正在写一个小的绞刑架游戏,在计划和得到一个非常奇怪的问题,几乎似乎是一个语言特定的问题。

在我的游戏中,我有一个变量,它保存允许的错误数量,并且在我的游戏循环的每个递归调用中,如果需要更改,我会将值“让”为一个新值。这里有一些代码来帮助可视化我是如何运行游戏循环的。

guessed_list -包含旧猜测和一个新猜测的字符串字符列表(例如。‘'("a“x”b")其中"a“是新的猜测)

game_word -‘(a "b“"c")

display_word --包含我匹配的字母和连字符的字符串列表,用于那些我还没有到游戏循环(“ex‘( "b”") )迭代的字符串,其中guessed_list中的"a“将在这个循环迭代中进行计算。

mistakes_left --由于猜错了,我在比赛前犯的错误数量应该会结束。最初从6开始,但在我当前的示例中应该是5,因为一个字母"x“被错误地猜错了。

代码语言:javascript
复制
     ;; 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!")))))))

我可以发布我的助手方法包含?,填充猜测,显示列表,如果必要的话,但是所有这些方法都可以正常工作,并且不为它们的功能更改我的mistakes_left变量的值。

我遇到的问题是,我的mistakes_left变量从6开始,在游戏循环的第一次调用时会很好地通过,但是在随后的调用中,即使在猜测正确的值时,也会变得更小。我已经取得了每一件单独的,测试它和mistakes_left出了正确的价值,直到我恢复。

我怀疑这是与递归和“让”我的变量,但我想要一个明确的答案,如果有人可以或指出最可能的简单错误,我错过了!

编辑:

下面是要测试的其余代码,我仍然知道问题所在。我认为追加之所以有效,是因为它将第二个列表附加到第一个列表中,因此在这个意义上,cons和append给了我相同的输入。

代码语言:javascript
复制
  (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))
      )))))))))))
  )
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-04 16:24:16

我概括了这个问题,不把重点放在绞刑方面。问题得到了立即的回答,评论进一步解释了错误的原因。您可以在这篇文章中找到所有这些信息:方案递归循环值不正确和变量绑定

票数 0
EN

Stack Overflow用户

发布于 2014-10-01 15:20:29

我对你的代码做了几处修改。我在函数上方用注释标记了我的更改,并对它们进行了解释。你的问题是你把guessed_list分类了。没有必要这样做。我已经测试过了,而且效果很好。请记住,如果您使用一个空的猜测列表调用game-loop,它将出错。要解决这个问题,您需要测试guessed_list是否为null,并返回0作为减法。我会把这个留给你。此外,在代码中的许多地方,都有不必要的嵌套cond。在这里阅读:条件

代码语言:javascript
复制
(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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26134917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档