Reputation: 1111
I'm trying to created a player that would solve the game Mastermind in LISP. I tried using the following nested loop in a helper function
(defparameter *counter* 0)
;analyze the score to determine whether points need to be added to counter
(defun analyze (last-response)
(if (> (first last-response) 0)
(setf *counter* (+ (first last-response) *counter*))))
;helper function for finding correct color
(defun guessColor (length colors last-response)
(loop while (< *counter* 4) do
(loop for i from 1 to length
collect (first colors)
(setf colors (rest colors)))
(analyze (last-reponse))))
;baseline Holyguacamole player will guess all colors before trying all combinations of correct color
(defun HolyGuacamole (board colors SCSA last-response)
(declare (ignore SCSA))
;(print last-response)
(guessColor board colors last-response)
(print *counter*)
;(sortColor)
)
The while loop is supposed to run while the global variable *counter*
is less than 4. The inside loop is supposed to guess colors based on the length of pegs required (variable length). I've been running into the compilation error
during macroexpansion of (LOOP WHILE (< COUNTER 4) ...). Use ;
BREAK-ON-SIGNALS to intercept.
I'm unfamiliar with LISP so I'm not sure what that error code means and how to fix it. I felt like I nested it correctly with the proper parenthesis, but I'm not actually sure what's wrong with it.
Link to Mastermind environment.
Upvotes: 1
Views: 2071
Reputation: 6994
There is no obstacle in principle to nesting a loop inside another loop. However, a COLLECT
or COLLECTING
clause can only take a single expression, as @jkiiski pointed out.
For instance, the following program
(defun nested-loop ()
(loop for i from 1 to 10 doing
(loop for j from 1 to 10 collecting
(print "some string")
(print (list 'nested-loop i j)))))
(nested-loop)
produces a syntax error under CLISP.
*** - LOOP: illegal syntax near (PRINT (LIST 'NESTED-LOOP I J)) in
(LOOP FOR J FROM 1 TO 10 COLLECTING (PRINT "some string")
(PRINT (LIST 'NESTED-LOOP I J)))
Using a do
or doing
clause works, as does grouping the multiple expressions associated with a collecting
clause with progn
.
(defun nested-loop ()
(loop for i from 1 to 10 doing
(loop for j from 1 to 10 collecting
(progn
(print "some string")
(print (list 'nested-loop i j))))))
(nested-loop)
Upvotes: 1