#|
I've peaked as a programmer, 
I will never write something this great again.
In order for (require 'alexandria) to work,
you need
https://gitlab.common-lisp.net/alexandria/alexandria.git
in your
~/common-lisp/
which you should have anyway.
You would run this like
ecl --load best-game.lisp
should be portable to any lisp.
Doesn't require X.
|#

(require 'asdf)
(require 'alexandria)

(setq *counter* (let ((score 0))
                 (lambda ()
                  (format t "Score is ~@:r~%" 
                   (incf score)))))

(defvar *player-line* (coerce ".........x........" 'list))
(defvar *other-lines* 
 (list
  (coerce ".................." 'list)
  (coerce ".................." 'list)
  (coerce ".....oo....oo....." 'list)
  (coerce ".................." 'list)
  (coerce ".................." 'list)
  (coerce "........o........." 'list)
  (coerce "....o.........o..." 'list)
  (coerce ".............o...." 'list)
  (coerce ".....oo..ooo......" 'list)
  (coerce ".......oo........." 'list)))

(loop
 for ch = (read-char-no-hang)
 do (funcall *counter*)
 do (format t "~{~a~}
~{~{~a~}~%~}" *player-line* *other-lines*)
 do (when ch
     (cond ((char= ch #\l) 
            (setf *player-line* (alexandria:rotate *player-line* +1)))
           ((char= ch #\h) 
            (setf *player-line* (alexandria:rotate *player-line* -1))) 
      ((char= ch #\q) (quit)))
      )
 do (when (char= #\o (nth  (search '(#\x) *player-line*) (car *other-lines*)))
     (format t "~%You weren't meant to hit the o :-( ~%") ;)
     (return))
 do (setf *other-lines*
     (append (cdr *other-lines*)
      (list (loop for x below (length *player-line*)
             for r = (random 7)
             collecting (if (zerop r) #\o #\.)))) )
 do (sleep 1))

(quit)