2011-10-12 32 views
5

Xin chào, tôi đang cố gắng tạo lồng nhau nếu trong lisp, nhưng chúng tôi vẫn gặp lỗi và chúng tôi không biết cách khắc phục!Nested if in lisp

** - EVAL: quá nhiều thông số cho toán tử đặc biệt NẾU:

(defun spread-stones-helper(game-state StoneInHand Player player-index pit-index) 

    ;; Do we have more stones in our hand? 
    (if (> 0 StoneInHand) 
     ;; Are we above the pit limit? 
     (if (> pit-index 5) 
      ;; Switch the player and reset the pit-index to 0 
      (setq player-index (switchplayer player-index)) 
      (setq pit-index '0) 
     ) 

     ;; Add 1 to the pit 
     (set-pit game-state player-index (GetCorrectPit player-index pit-index) (+ (get-pit game-state player-index (GetCorrectPit player-index pit-index)) 1)) 

     ;; Recursive call the function, with one less stone and 1 up in pit-index 
     (spread-stones-helper game-state (- StoneInHand 1) Player player-index (+ pit-index 1)) 
    ) 
    ;; There are no more stones in hand, run capture stones 
    ;; (captureStones game-state StoneInHand Player player-index pit-index) 
) 
+0

Tôi nghĩ bạn có thể đang bối rối với phong cách thụt lề/thụt lề lẻ mà bạn đã tạo. – Ken

Trả lời

8

Trong Lisp các nhà điều hành if chấp nhận ba biểu thức có điều kiện, giá trị trong trường hợp điều kiện là đúng và giá trị khi điều kiện là sai .. ví dụ:

(if (< x 0) 
    (print "x is negative") 
    (print "x is greater or equal than zero")) 

Bạn cũng có thể bỏ qua cụm từ cuối cùng và trong trường hợp này, nó được giả định là NIL.

Nếu bạn muốn đặt biểu thức ở một trong hai trường hợp, bạn phải bọc chúng trong một hình thức progn

(if (< x 0) 
    (progn 
     (print "HEY!!!!") 
     (print "The value of x is negative..."))) 

Trường hợp có một biểu if với chỉ một trong hai chi nhánh điền và với nhiều biểu thức đã được tìm thấy là rất thường xuyên và do đó hai biến thể đặc biệt để sử dụng này chính xác đã được thêm vào:

(when (< x 0) 
    (do-this) 
    (do-that) 
    (do-even-that-other-thing)) 

(unless (< x 0) 
    (do-this) 
    (do-that) 
    (do-even-that-other-thing)) 

dạng when trên là tương đương với

(if (< x 0) 
    (progn 
    (do-this) 
    (do-that) 
    (do-even-that-other-thing))) 

Dạng unless có ý nghĩa rất tương tự, nhưng với điều kiện ngược lại ... nói cách khác đó là tương đương với

(if (not (< x 0)) 
    (progn 
    (do-this) 
    (do-that) 
    (do-even-that-other-thing))) 

Để recap bạn nên sử dụng if chỉ khi bạn cần phải viết mã cho cả hai chi nhánh (đúng và sai). Nếu không, hãy sử dụng when hoặc unless tùy thuộc vào nội dung nào dễ đọc hơn đối với thử nghiệm của bạn.

Khi sử dụng mẫu if, bạn phải sử dụng progn trong các chi nhánh mà bạn cần đặt nhiều hơn một biểu mẫu.

5

Đừng quên sử dụng (progn ...) cho nhiều hơn một nếu-tuyên bố

(defun spread-stones-helper (game-state StoneInHand Player 
          player-index pit-index) 

    ;; Do we have more stones in our hand? 
    (if (> 0 StoneInHand) 
     (progn 
     ;; Are we above the pit limit? 
     (if (> pit-index 5) 
     (progn 
       ;; Switch the player and reset the pit-index to 0 
       (setq player-index (switchplayer player-index)) 
       (setq pit-index '0))) 

     ;; Add 1 to the pit 
     (set-pit game-state player-index 
        (GetCorrectPit player-index pit-index) 
        (+ (get-pit game-state player-index 
           (GetCorrectPit player-index pit-index)) 
        1)) 

     ;; Recursive call the function, with one less stone and 1 
     ;; up in pit-index 
     (spread-stones-helper game-state 
           (- StoneInHand 1) 
           Player 
           player-index 
           (+ pit-index 1)))) 
    ;; There are no more stones in hand, run capture stones 
    ;; (captureStones game-state StoneInHand Player player-index pit-index) 
    ) 
5

" nếu "làm bài kiểm tra và hai biểu mẫu -

Bạn đã đưa ra bài kiểm tra" if "đầu tiên và ba biểu mẫu

Giả sử (> 0 StoneInHand) là đúng.

Bạn có muốn chạy cả câu lệnh if và câu lệnh set-pit thứ hai không?

Nếu vậy, bạn cần phải bọc chúng trong một (progn)