anchor.diff:    "Construct a human vs human Dots and Boxes game."
     (make-dab :game-size size
               :graph (create-dab-graph size)
  -            :players (cons (make-player :edge-function #'get-human-edge :name p1-name :next-player #'cdr)
  -                           (make-player :edge-function #'get-human-edge :name p2-name :next-player #'car))))
  +            :players (cons (make-player :edge-function #'get-human-edge :name p1-name :next-player #'cdr :tag #\A)
  +                           (make-player :edge-function #'get-human-edge :name p2-name :next-player #'car :tag #\B))))
   
   (defun create-computer-human-dab (size p-name)
     "Create a human vs computer Dots and Boxes game."
     (make-dab :game-size size
               :graph (create-dab-graph size)
  -            :players (cons (make-player :edge-function #'get-human-edge :name p-name :next-player #'cdr)
  -                           (make-player :edge-function #'get-random-computer-edge :name "Computer" :next-player #'car))))
  +            :players (cons (make-player :edge-function #'get-human-edge :name p-name :next-player #'cdr :tag #\A)
  +                           (make-player :edge-function #'get-random-computer-edge :name "Computer" :next-player #'car :tag #\B))))
   
   (defun create-computer-computer-dab (size p1-name p2-name)
     "Create a computer vs computer Dots and Boxes game."
     (make-dab :game-size size
               :graph (create-dab-graph size)
  -            :players (cons (make-player :edge-function #'get-random-computer-edge :name p1-name :next-player #'cdr)
  -                           (make-player :edge-function #'get-random-computer-edge :name p2-name :next-player #'car))))
  -
  -
  -
  -
  -(defun show-square-graph (graph)
  +            :players (cons (make-player :edge-function #'get-random-computer-edge :name p1-name :next-player #'cdr :tag #\A)
  +                           (make-player :edge-function #'get-random-computer-edge :name p2-name :next-player #'car :tag #\B))))
  +
  +
  +
  +
  +(defun show-square-graph (graph owners)
     "Display a square graph."
  -  (let ((size+1 (game-size+1 graph)))
  -    (dotimes (j size+1)
  -      (dotimes (i size+1)
  -        (multiple-value-bind (v1 v2 v3 v4) (square-vertices-at graph i j)
  +  (let ((dot-size (game-dot-size graph)))
  +    (dotimes (j dot-size)
  +      (dotimes (i dot-size)
  +        (multiple-value-bind (v1 v2 v3 v4) (verts-for-square graph (+ i (* j dot-size)))
             (declare (ignorable v3 v4))
             (if (has-edge-p graph v1 v2)
                 (format t "~2d---" v1)
                 (format t "~2d   " v1))))
         (terpri)
  -      (dotimes (i size+1)
  -        (multiple-value-bind (v1 v2 v3 v4) (square-vertices-at graph i j)
  +      (dotimes (i dot-size)
  +        (multiple-value-bind (v1 v2 v3 v4) (verts-for-square graph (+ i (* j dot-size)))
             (declare (ignorable v3 v4))
             (if (has-edge-p graph v1 v3)
  -              (format t " |   ")
  +              (let* ((vert (+ i (* j dot-size)))
  +                     (owner-pair (assoc vert owners))
  +                     (owner (if owner-pair (cdr owner-pair) #\space)))
  +                (format t " | ~a " owner))
                 (format t "     "))))
         (terpri))))
   
   
  -(defun play-dab-game (dab)
  +(defun play-dab-game (dab &optional (verbosity 2))
     "Play a game of Dots and Boxes against the computer."
  -  (with-slots (game-size num-squares players graph) dab
  -    (let ((cur-player (car players)))
  -      (loop until (= num-squares (* game-size game-size))
  +  (with-slots (game-size squares players graph owners) dab
  +    (let ((cur-player (car players))
  +          (old-len 0))
  +      (loop until (= (length squares) (* game-size game-size))
            do
  -           (with-slots (name score edge-function next-player) cur-player
  -             (format t "~a: ~a |  ~a: ~a~%"
  -                     (player-name (car players))
  -                     (player-score (car players))
  -                     (player-name (cdr players))
  -                     (player-score (cdr players)))
  -             (format t "================================~%")
  -             (show-square-graph graph)
  -             (format t "================================~%~%")
  -             (format t "~%It's ~a's turn!~%" name)
  +           (with-slots (name score edge-function next-player tag) cur-player
  +             (when (> verbosity 1)
  +               (format t "~a: ~a |  ~a: ~a~%"
  +                       (player-name (car players))
  +                       (player-score (car players))
  +                       (player-name (cdr players))
  +                       (player-score (cdr players)))
  +               (format t "================================~%")
  +               (show-square-graph graph owners)
  +               (format t "================================~%~%")
  +               (format t "~%It's ~a's turn!~%" name))
                (multiple-value-bind (v1 v2) (funcall edge-function graph)
                  (add-edge graph v1 v2)
  -               (let ((new-squares (count-complete-squares graph)))
  -                 (if (> new-squares num-squares)
  -                     (incf score (- new-squares num-squares))
  +               (let* ((new-squares (find-complete-squares graph))
  +                      (new-len (length new-squares)))
  +                 (if (> new-len old-len)
  +                     (progn 
  +                       (dolist (square (set-difference new-squares squares))
  +                         (push (cons square tag) owners))
  +                       (incf score (- new-len old-len)))
                        (setf cur-player (funcall next-player players)))
  -                 (setf num-squares new-squares))))))
  -        (terpri)
  -        (format t "~a: ~a |  ~a: ~a~%"
  -                (player-name (car players))
  -                (player-score (car players))
  -                (player-name (cdr players))
  -                (player-score (cdr players)))
  -        (format t "================================~%")
  -        (show-square-graph graph)
  -        (format t "================================~%")
  -        (let ((car-score (player-score (car players)))
  -              (cdr-score (player-score (cdr players))))
  +                 (setf squares new-squares)
  +                 (setf old-len new-len)))))
  +      (let ((car-score (player-score (car players)))
  +            (cdr-score (player-score (cdr players))))
  +        (when (> verbosity 0)
  +          (terpri)
  +          (format t "~a: ~a |  ~a: ~a~%"
  +                  (player-name (car players))
  +                  (player-score (car players))
  +                  (player-name (cdr players))
  +                  (player-score (cdr players)))
  +          (format t "================================~%")
  +          (show-square-graph graph owners)
  +          (format t "================================~%")
             (format t "~%Game over!~%The score was ~a to ~a~%" car-score cdr-score)
   
             (if (= car-score cdr-score)
  
positive.code:   (score 0 :type fixnum)
    (edge-function #'get-human-edge)
    (name "human" :type string)
    (next-player #'cdr))
  
  (defstruct dab
    "A structure representing a Dots and Boxes game."
    (game-size 2 :type fixnum)
    (num-squares 0 :type fixnum)
    (players (cons (make-player :edge-function #'get-human-edge :name "Human" :next-player #'cdr)
                   (make-player :edge-function #'get-random-computer-edge :name "Computer" :next-player #'car)))
    (graph (create-dab-graph 2) :type graph))
  
  
  
negative.code:   "Figure out a computer move."
    (declare (ignorable graph))
    (loop for vert = (random (length (graph-edges graph))) then (random (length (graph-edges graph)))
       for possibilities = (get-possibilities graph vert)
       while (not possibilities)
       finally (return-from get-random-computer-edge (values vert (nth (random (length possibilities)) possibilities)))))
  
  
  
  