Thanks both for responding, and I'm sorry that I'm responding a few days late. I found a work around to the problem I was having, although I never figured out what was wrong initially.
@nuntius: I'll include my recursive function at the end of this point, although it is lengthy and messy, as I'm not a great programmer and still learning CLISP. I've been slowly reading that book you posted (I found it a couple weeks ago just through searching), but have also been constantly referencing later chapters for extra info.
@smithzv: I didn't declare any special variables as such, so I guess that wasn't the problem. I wasn't having trouble with my board, but I think the problem you brought up was probably the issue.
I'll post the recursive function just below. The function AI sets up a 'route' variable with two symbols, board and score. The board symbol contains a value with whatever the current state of the board is, and the score symbol is defaulted to 0, since no score for that particular route has been calculated.
AI then places a call to a "choose" method (the recursive method), which chooses the best possible route to take, and therefor the next move (or it should anyway, lol).
The problem I WAS having is that I also had a depth symbol attached to the route, which would be incremented every time I called "choose". Choose would then generate all possible moves of that board. If the depth is less than 4, it would loop through each newly generated move, calling "choose" for each one. If the depth has reached 4, choose would then call another function, which calculates the score of that board (or move). That route (with current board and new score) are then passed back to the previous level.
Once all of the scores of those moves are found, choose would calculate which one is the best, and then return to the previous level, and so on. My problem was that each time I went back to the previous level, the depth wouldn't be the right number. It just kept incrementing, no matter what depth I was really at.
I solved the problem by getting rid of depth as a separate symbol for route. Instead, I just pass in an incremented depth each time I call choose. I tried to make it as clear as possible, so sorry if it's hard to understand what I mean. Here's the code:
Code: Select all
(defun ai (board)
(let
()
(princ "I'm thinking...")(terpri)
(putprop 'route 'board board)
(putprop 'route 'score 0)
(if (equal board '(nil nil nil nil nil nil nil nil nil))
'(nil nil nil nil nil nil 5 nil nil)
(get (choose 'route 0) 'board))))
(defun choose (route depth)
(let
()
(if (equal depth depthlength)
(putprop route 'score (determine-score (get route 'board)))
(progn
(setf child-scores '(-1))
(setf child-boards (gen-next (get route 'board)))
(if (equal depth 0)
(progn
(setf end nil)
(loop for i in child-boards
do (if (check-end i)
(progn
(putprop 'route 'board i)
(setf end t))))))
(setf child-boards (gen-next (get route 'board)))
(if (and (not (null child-boards)) (not end))
(progn
(loop for i in child-boards
do (putprop 'temp-route 'board i)
do (putprop 'temp-route 'score 0)
do (cond
((equal (car child-scores) -1) (setf child-scores (list (get (choose 'temp-route (+ depth 1)) 'score))))
(t (setf child-scores (concatenate 'list child-scores (list (get (choose 'temp-route (+ depth 1)) 'score)))))))
(setf goal (car child-scores))
(setf index 0)
(setf goal-index 0)
(loop for j in child-scores
do (if (> j goal)
(progn
(setf goal j)
(setf goal-index index)))
do (setf index (+ index 1)));))
(setf child-boards (gen-next (get route 'board)))
(putprop route 'board (car (nth-cdr goal-index child-boards)))
(putprop route 'score (car (nth-cdr goal-index child-scores))))
(putprop route 'score (determine-score (get route 'board))))))
route))