;; Exercice 1 ;; 1- ;; iterative (3) (defun compress-it (l) (do ((l l (cdr l)) (r '())) ((endp l) (nreverse r)) (if (or (endp r) (not (eql (car l) (cdar r)))) (push (cons 1 (car l)) r) (incf (caar r))))) ;; Exercice 2 ;; 2- (3) (defun iota (n &optional (start 0) (step 1)) (loop repeat n for i from start by step collect i)) (defun player-shift (player) (* player *half-size*)) (defun player-places (player) "the list of the places of a player" (let ((places (iota *half-size* (player-shift player)))) (if (zerop player) (nreverse places) places))) ;; 3- (1) (defun make-game-array (&optional (nb-pebbles *nb-pebbles*)) (make-array (list *size*) :initial-element nb-pebbles)) ;; 4- (2) (defun player-valid-places (player game-array) "the list of the places where PLAYER may can play" (remove-if (lambda (place) (zerop (aref game-array place))) (player-places player))) ;; 5- (3) (defun next-place (place) (mod (1+ place) *size*)) (defun play-in-place (place game-array) (let ((nb-pebbles (aref game-array place))) (setf (aref game-array place) 0) (loop repeat nb-pebbles for p = (next-place place) then (next-place p) do (incf (aref game-array p))) game-array)) ;; 6- (1.5) (defclass strategy () ((strategy-name :initarg :strategy-name :reader strategy-name) (strategy-fun :initarg :strategy-fun :reader strategy-fun))) ;; 7- (1.5) (defun make-strategy (strategy-name strategy-fun) (make-instance 'strategy :strategy-name strategy-name :strategy-fun strategy-fun)) ;; Exercice 3 ;; 8- (1) (defvar *strategies* (make-hash-table :test #'equal)) ;; 9- (1) (defun add-strategy (strategy) (setf (gethash (strategy-name strategy) *strategies*) strategy)) ;; 10- (3) (defmacro def-strategy (strategy-name &body body) `(add-strategy (make-strategy ,strategy-name (lambda (player game-array) (let ((places (player-valid-places player game-array))) (when places ,@body))))))