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