Вложенный if в lisp

#lisp

#lisp

Вопрос:

Здравствуйте, я пытаюсь создать вложенный if в lisp, но мы продолжаем получать ошибку, и мы не знаем, как это исправить!

** — EVAL: слишком много параметров для специального оператора IF:

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

Комментарии:

1. Я думаю, вы, вероятно, путаете себя с созданным вами странным стилем парения / отступа.

Ответ №1:

В lisp if оператор принимает три выражения, которые являются условием, значением в случае, если условие истинно, и значением, когда условие ложно … например

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

Вы также можете опустить последнее выражение, и в этом случае предполагается, что оно равно НУЛЮ.

Если вы хотите поместить больше выражений в один из двух случаев, вы должны обернуть их в progn форму

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

Было обнаружено, что случай наличия if выражения только с одной из двух заполненных ветвей и со многими выражениями встречается очень часто, и поэтому были добавлены два специальных варианта для этого точного использования:

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

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

Приведенная when выше форма эквивалентна

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

unless Форма имеет то же значение, но с обратным условием… другими словами, это эквивалентно

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

Напомним, что вы должны использовать if только тогда, когда вам нужно написать код для обеих ветвей (истинной и ложной). В противном случае используйте либо when или unless в зависимости от того, что более читаемо для вашего теста.

При использовании if формы вы должны использовать a progn в ветвях, где вам нужно поместить более одной формы.

Ответ №2:

«if» принимает тест и две формы —

Вы дали первому «if» тест и три формы

Предположим, что (> 0 StoneInHand) имеет значение true .

Вы хотите выполнить как второй if, так и операторы set-pit?

Если это так, вам нужно обернуть их в (progn)

Ответ №3:

Не забудьте использовать (progn ...) для более чем одного if-оператора

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