计划中的3桩Nim游戏

时间:2015-09-24 04:54:42

标签: scheme racket

我在计划中构建一个Nim游戏,提示用户输入桩号和他们想要删除的物品数量。计算机将简单地从第一堆中移除1,如果第一堆是空的,它将从第二堆中移除,而不是第三堆。

我的代码无法正常运行,有人可以指出我犯错误的地方吗?提前谢谢。

这是我的代码:

(define play-with-turns
  (lambda (game-state player)
    (display-game-state game-state)
    (cond ((over? game-state) 
           (announce-winner player))
          ((equal? player 'human)  
           (play-with-turns (human-move game-state) 'computer))
          ((equal? player 'computer)  
           (play-with-turns (computer-move game-state) 'human))
          (else  
           (error "player wasn't human or computer:" player)))))

(define computer-move
  (lambda (game-state)
    (let ((pile (if (> (size-of-pile game-state 1) 0)
                    1
                    2)))
      (display "I take 1 coin from pile ")
      (display pile)
      (newline)

      (remove-coins-from-pile game-state 1 pile))))

(define prompt
  (lambda (prompt-string)
    (newline)
    (display prompt-string)
    (newline)
    (read)))

(define human-move
  (lambda (game-state)
    (let ((p (prompt "Which pile will you remove from?")))
      (let ((n (prompt "How many coins do you want to remove?")))
        (remove-coins-from-pile game-state n p)))))

(define over?
  (lambda (game-state)
    (= (total-size game-state) 0)))

(define announce-winner
  (lambda (player)
    (if (equal? player 'human) 
        (display "You lose. Better luck next time.")
        (display "You win. Congratulations."))))

(define remove-coins-from-pile
  (lambda (game-state num-coins pile-number)
    (cond ((= pile-number 1)
           (make-game-state (- (size-of-pile game-state 1)
                               num-coins) 
                            (size-of-pile game-state 2)
                            (size-of-pile game-state 3)))
          ((= pile-number 2)
           (make-game-state (size-of-pile game-state 1)
                            (- (size-of-pile game-state 2)
                               num-coins)
                            (size-of-pile game-state 3)))
          ((= pile-number 3)
           (make-game-state (size-of-pile game-state 1)
                            (size-of-pile game-state 2)
                            (- (size-of-pile game-state 3)
                               num-coins))))))

(define exponent-of-in
  (lambda (n int)
    (if (= (remainder int n) 0)
        (+ 1 (exponent-of-in n (quotient int n)))
        0)))

(define make-game-state
  ;Returns a game state with n coins in the first pile
  ;m coins in the second pile, and k coins in the third pile.
  (lambda (n m k)
    (lambda (x)
      (cond ((= x 1) n)
            ((= x 2) m)
            ((= x 3) k)))))



(define size-of-pile
  ;Returns an integer equal to the number of coins in
  ;pile pile-number of the game-state.
  (lambda (game-state pile-number)
    (game-state pile-number)))

;; Utilities

(define display-game-state
  (lambda (game-state)
    (newline)
    (newline)
    (display "    Pile 1: ")
    (display (size-of-pile game-state 1))
    (newline)
    (display "    Pile 2: ")
    (display (size-of-pile game-state 2))
    (newline)
    (display "    Pile 3: ")
    (display (size-of-pile game-state 3))
    (newline)
    (newline)))

(define total-size
  (lambda (game-state)
    (+(+ (size-of-pile game-state 1)
         (size-of-pile game-state 2)) (size-of-pile game-state 3))))

示例输出:

(play-with-turns (make-game-state 5 9 8) 'human)


    Pile 1: 5
    Pile 2: 9
    Pile 3: 8


Which pile will you remove from?
1

How many coins do you want to remove?
2


    Pile 1: 4
    Pile 2: 9
    Pile 3: 8

I take 1 coin from pile 1


    Pile 1: 3
    Pile 2: 9
    Pile 3: 8


Which pile will you remove from?
2

How many coins do you want to remove?
2


    Pile 1: 2
    Pile 2: 7
    Pile 3: 8

I take 1 coin from pile 1


    Pile 1: 1
    Pile 2: 7
    Pile 3: 8


Which pile will you remove from?
2

How many coins do you want to remove?
2


    Pile 1: 1
    Pile 2: 5
    Pile 3: 8

I take 1 coin from pile 1


    Pile 1: 0
    Pile 2: 5
    Pile 3: 8

1 个答案:

答案 0 :(得分:0)

首先要做的事情:我强烈建议您按照How To Design Programs中所述的设计方案进行操作。首先,您的函数可以真正使用每个单行目的语句。接下来,您真的需要这些功能的测试用例。我强烈怀疑你的remove-coins-from-pile函数有问题。

我看到您的代码中至少有一个错误,您可以通过一组好的测试用例轻松捕获​​这些错误。如果您正在使用其中一种学生语言,您应该能够通过写作来测试,例如:

(check-expect ((remove-coins-from-pile (make-game-state 3 9 7) 5 2) 3) 172)

请注意,此测试用例实际上是错误的;你必须解决它。

如果您使用完整的#lang球拍语言,则需要添加

(require rackunit)

然后使用check-equal进行测试?:

(check-equal? ((remove-coins-from-pile (make-game-state 3 9 7) 5 2) 3) 172)

老实说,有人引导你走向基于功能的方法(游戏状态被表示为一种功能),这使得测试比其他方式更加困难;如果你有一个“游戏状态”结构,你可以通过写作来测试整个游戏状态,例如,

(check-equal? (remove-coins-from-pile (make-game-state 3 9 7) 5 2)
              (make-game-state 17 27 0))

我猜这是一个真正喜欢功能的教练的作业。嗯,说实话,非常喜欢功能,但它们并不顺利 在这样的情况下进行测试。

有关详细信息,我会再次推荐您使用如何设计程序文本。