递归方案函数值错误 [英] Recursive Scheme Function Value Error

查看:48
本文介绍了递归方案函数值错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在计划中编写一个小型的子手游戏,并且遇到了一个非常奇怪的问题,几乎就像是特定于语言的问题.

I am writing a small hangman game in scheme and am getting a very weird issue that almost seems like a language specific one.

在我的游戏中,我有一个变量,该变量保存允许的错误数,并且在我的游戏循环的每次递归调用中,如果需要更改值,我会将其放"到一个新值.这是一些代码,可帮助可视化我如何运行游戏循环.

In my game I have a variable that holds the number of mistakes allowed and on each recursive call of my game loop, I "let" the value to a new one if it needs to be changed. Here is some code to help visualize how I run the game loop.

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

guessed_list - a list of string characters containing old guesses and one new guess (ex. '("a" "x" "b") where "a" is the new guess)

game_word-'("a""b""c")

game_word - '("a" "b" "c")

display_word-包含我已匹配的字母和连字符的字符串字符列表,这些字符我尚未达到游戏循环的此迭代(例如'("<">" b" )在这个循环迭代中,将对guessed_list中的"a"进行评估

display_word - a list of string characters containing letters I have matched and hyphens for those I haven't up to this iteration of my game loop (ex '("" "b" "") where "a" from the guessed_list is going to be evaluated this loop iteration)

mistakes_left-由于猜错,我在游戏之前应该结束的错误数.最初,它从6开始,但是在我当前的示例中应该为5,因为错误地猜出了1个字母"x".

mistakes_left - The number of mistakes I have before my game should end because of wrong guessed. Initially this starts at 6, but in my current example should be 5 because 1 letter, "x", was guessed incorrectly.

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

如有必要,我可以发布我的辅助方法包含?,填充猜测,显示列表,绘制hangman,但是它们全部按应有的方式工作,并且不会更改我的errors_left变量的功能值.

I can post my helper methods contains?, fill-in-guess, display-list, draw-hangman if necessary, but all of them work as they should and do not change values of my mistakes_left variable for their functionality.

我遇到的问题是我的errors_left变量始于6,并在第一次调用游戏循环时顺利通过,但在随后的调用中,即使猜测正确的值也会变小.我已经单独拿走了每一块,对其进行了测试,并且errors_left会以正确的值显示出来,直到我递归为止.

The problem I am running into is my mistakes_left variable starts out at 6 and passes through fine on the first call of game-loop, but on subsequent calls, gets smaller even when guessing a correct value. I have taken every piece individually, tested it and mistakes_left comes out with the right value until I recurse.

我怀疑这与递归和放"我的变量有关,但是如果有人可以或者指出我所缺少的最简单的错误,我想给出一个明确的答案!

I suspect it has to do with the recurse and "let"ing my variable, but I would like a difinitive answer if anyone could or point out the most likely simple error I am missing!

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

Here is the rest of the code to test, I still get the issue. I think append worked because it appends the second list to the first, so in that sense cons and append gave me the same input.

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

推荐答案

我将问题概括为不关注其子手方面.立即解决了该问题,并通过注释进一步解释了该错误的原因.您可以在这篇文章中找到所有这些信息:方案递归循环不正确值和变量绑定.

I generalize the question to not focus on the hangman aspect of it. There was an immediate answer to the problem and comments further explained the reasoning for the error. You can find all of that information in this post: Scheme Recursion Loop Incorrect Values and Variable Binding.

这篇关于递归方案函数值错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆