Skip to content

Instantly share code, notes, and snippets.

@nathanlippi
Created September 3, 2012 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathanlippi/3609840 to your computer and use it in GitHub Desktop.
Save nathanlippi/3609840 to your computer and use it in GitHub Desktop.
Problem -- Old board being remembered for (play-game)
(defvar *player-symbol* '(" " "X" "O")) ;; Strictly used for display
;; (defmacro setk (list keyword value)
;; `(setf (getf ,list ,keyword) ,value))
(defun display-board(board)
(loop for row in board do
(display-row row)
(format *query-io* "~%")))
(defun display-row(row)
(let* ((row-len (list-length row)) (row-output ""))
(do ((n 0 (1+ n))
(mid-char "" "|"))
((= n row-len) (format t row-output))
(setf row-output
(concatenate 'string row-output mid-char (nth (nth n row) *player-symbol*))))))
;; Will randomly mark a square as played
;; Takes a list of lists that represents a board
(defun play-random (board player-number)
;; Get all empty positions
(let ((empty-cells ()))
(loop for y from 0 to 2 do
(loop for x from 0 to 2 do
(if (= (get-pos board x y) 0)
(setf empty-cells (cons (list x y) empty-cells)) nil)))
(if (= (length empty-cells) 0)
board
(let* ((cell (random-elt empty-cells))
(pos-x (nth 0 cell)) (pos-y (nth 1 cell)))
(set-pos board pos-x pos-y player-number)))))
(defun get-pos (board x y) (nth x (nth y board)))
(defun set-pos (board x y val) (setf (nth x (nth y board)) val) board)
;; http://norvig.com/paip/simple.lisp
(defun random-elt (choices)
(elt choices (random (length choices))))
(defun play-game ()
(let ((board '((0 0 0) (0 0 0) (0 0 0))))
(loop for i from 0 to 8 do
;; (if (> (check-win board) 0)
;; (progn (print "We have a winner!~%") (return nil)))
(display-board board)
(format *query-io* "~%") ;; Extra newline
(setq board (play-random board (1+ (mod i 2)))))
(display-board board)))
(defun rotate (list-of-lists)
(apply #'mapcar #'list list-of-lists))
(defun check-win (board)
(let ((winners nil))
(setf winners (append winners (check-board-rows board)))
(setf winners (append winners (check-board-rows (rotate board))))
;; Check the diagonals
(setf winners (append winners (check-positions board '((0 0) (1 1) (2 2)))))
(setf winners (append winners (check-positions board '((0 2) (1 1) (2 0)))))
(if (and (> (length winners) 0) (apply '= winners)) (car winners) 0)))
(defun check-board-rows (board)
(let ((winner nil))
(loop for row in board do
(if (and (> (car row) 0) (apply '= row)) (setf winner (cons (car row) winner))))
winner))
(defun check-positions (board pos-list)
(let ((positions
(loop for pos in pos-list collect
(get-pos board (car pos) (nth 1 pos)))))
(if (and (> (car positions) 0) (apply '= positions)) (list (car positions)) nil)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment