2013-03-22 77 views
0

我是Racket的新手,并且正在努力为我的Programming Languages课程编写一个Mastermind游戏。我已经完成了代码,它也运行。在下面的代码中,'solution'是一个4个随机生成的颜色列表。我想问我该如何修改我的'constructSolution'函数,以便我可以运行循环/递归而不是编写集合! 4次不同。我尝试修改像这样的constructSolution函数:在球拍中循环播放列表

(define i 0) 
(define (constructSolution) 
    (cond 
    ((if (< i 4) 
     (set! solution (append solution (list (random-color)))) 
     (set! i (+ i 1)))) 
    (else #f)) 
) 

但它没有工作。理想情况下,用户将输入列表的长度,功能将检查'(如果(< i长度))''而不是'(如果(< i 4))''。任何帮助,将不胜感激。这里是我的代码有:

#lang racket 
(require racket/gui/base) 

(define solution1 '(yellow red black blue)) 
(define solution '()) 
(define blackPegs 0) 
(define totalPegs 0) 
(define whitePegs 0) 
(define countPegs 0) 
(define numBlackPegs 0) 
(define guessText "") 
(define displayGuess "Guess ") 
(define displayScore "Black Pegs = ") 
(define displaySolution "Solution: ") 
(define numGuess 1) 


(define f (new frame% [label "Mastermind"] 
         [width 300] 
         [height 500] 
         [alignment '(center center)])) 
(send f show #t) 
(define c (new editor-canvas% [parent f])) 
(define t (new text%)) 
(send c set-editor t) 
(send t insert "Welcome to Mastermind!\n\n") 

(define (constructSolution) 
    (set! solution (append solution (list (random-color)))) 
    (set! solution (append solution (list (random-color)))) 
    (set! solution (append solution (list (random-color)))) 
    (set! solution (append solution (list (random-color)))) 
) 

(define (random-color) 
    (choose '(red blue green yellow orange purple black))) 

(define (choose xs) 
    (list-ref xs (random (length xs)))) 

(define (alist->string alst) 
    (string-join (map symbol->string alst) " ")) 

(constructSolution) 
(set! displaySolution (string-append displaySolution (alist->string solution))) 
(send t insert displaySolution) 
(send t insert "\n\n") 

(define (try guess) 
    (compareBlackPegs guess solution blackPegs) 
    (printf "(~a, " numBlackPegs) 
    (compareWhitePegs guess solution) 
    (printf "~a) ~n" whitePegs) 
    (set! guessText (alist->string guess)) 
    (set! totalPegs 0) 
    (set! displayGuess (string-append displayGuess (number->string numGuess))) 
    (set! displayGuess (string-append displayGuess ": ")) 
    (set! displayGuess (string-append displayGuess guessText)) 
    (set! displayGuess (string-append displayGuess "\n")) 
    (send t insert displayGuess) 
    (set! displayGuess "Guess ") 
    (set! displayScore (string-append displayScore (number->string numBlackPegs))) 
    (set! displayScore (string-append displayScore ", White Pegs = ")) 
    (set! displayScore (string-append displayScore (number->string whitePegs))) 
    (set! displayScore (string-append displayScore "\n\n")) 
    (send t insert displayScore) 
    (set! displayScore "Black Pegs = ") 
    (set! numGuess (+ numGuess 1)) 
) 

(define (compareBlackPegs guess solution blackPegs) 
    (if (null? guess) (set! numBlackPegs blackPegs) 
     (if (equal? (car guess) (car solution)) (compareBlackPegs (cdr guess) (cdr solution) (+ blackPegs 1)) 
      (compareBlackPegs (cdr guess) (cdr solution) blackPegs))) 
) 

(define (compareWhitePegs guess solution) 
    (cond ((null? solution) 
     (set! whitePegs (- totalPegs numBlackPegs))) 
     ;(printf "~a) ~n" totalPegs)) 
     (else 
     (let ((a (count (car solution) guess countPegs)) 
       (b (count (car solution) solution countPegs))) 
     (if (equal? (< a b) #t) (set! totalPegs (+ totalPegs a)) 
      (set! totalPegs (+ totalPegs b)))) 
     (compareWhitePegs guess (cdr solution)))) 
) 

(define (count x alist countPegs) 
    (if (null? alist) countPegs 
     (if (equal? x (car alist)) (count x (cdr alist) (+ countPegs 1)) 
      (count x (cdr alist) countPegs))) 
) 


(try '(red red red red)) 
(try '(red yellow yellow yellow)) 
(try '(yellow red green green)) 
(try '(yellow red blue blue)) 
(try '(yellow red blue white)) 
(try '(yellow red black blue)) 
(send t insert "\nGoodbye!\n") 

回答

0

请避免使用set!实施方案的循环,这不是要走的路 - 使用递归或内置looping constructs。如果你想重复一个函数调用的固定次数(比如4)这里有一个如何使用显式递归来做到这一点的例子:

(define (repeat f n) 
    (cond ((zero? n) 'done) 
     (else (f) 
       (repeat f (sub1 n))))) 

以上将调用f的给定次数。如有必要,修改它以将其他参数传递到f。例如:

(repeat (lambda() (display 'xo)) 4) 
=> xoxoxoxo 
    'done 
+0

谢谢!这有帮助。 – spatra 2013-03-22 07:38:31