(defun letters () ;; Introductory information (format t "~%Welcome to Mattsoft Letters v.1.7.4~%") (loop (format t "~%Would you like to play? (y/n) ") (setf play? (read)) (if (equal play? 'n) (format t "The computer will play for now.~%") ) (if (not (or (equal play? 'n) (equal play? 'y))) (format t "That is an invalid selection.") ) (when (or (equal play? 'y) (equal play? 'n)) (return)) ) ;; Initialize game (setf table (make-array '(5 5) :initial-element '_ )) (setf score 0) (setf num_letters 6) (setf master_letter_list '(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)) (setf max_depth 0) (setf letter_list (butlast master_letter_list (- 26 num_letters))) (setq state (let ((cnt (mod (get-internal-real-time) 100000))) (dotimes (i cnt *random-state*) (random 10)))) (setf next_three (get_random_letters letter_list)) ;; Start game loop (loop ;; Pieces added to board and checks for loss (cond ((> score (* 10000 (- num_letters 5))) (setf table (make-array '(5 5) :initial-element '_ )) (setf num_letters (+ 1 num_letters)) (setf letter_list (butlast master_letter_list (- 26 num_letters))) ) ) (setf table (add_all table next_three)) (if (board_full? table) (return) ) (setf next_three (get_random_letters letter_list)) ;; Print state of game (print_state table score next_three) ;; Input if human playing (if (equal play? 'y) (loop (format t "~%What piece would you like to move?~%") (princ "(row) ") (setf irow (read)) (princ "(col) ") (setf icol (read)) (format t "~%Where would you like to move it?~%") (princ "(row) ") (setf frow (read)) (princ "(col) ") (setf fcol (read)) (when (verify_move table irow icol frow fcol) (return) ) (format t "~%That is an invalid selection. Try again.~%") (print_state table score next_three) ) ) ;; Input if computer playing (cond ((equal play? 'n) (setf real? 'n) (setf hello (+ 0.0 (get-internal-run-time))) (setf computers_move (generate_move table 0 next_three 'y)) (format t "~%CPU moved: ") (princ computers_move) (setf byebye (get-internal-run-time)) (format t "~%Time: ") (princ (/ (- byebye hello) internal-time-units-per-second)) (format t " seconds") (setf irow (nth 0 computers_move)) (setf icol (nth 1 computers_move)) (setf frow (nth 2 computers_move)) (setf fcol (nth 3 computers_move))) ) (setf real? 'y) (make_move table irow icol frow fcol) (setf table (update_board table frow fcol)) ) (format t "~%Game over. Your final score was ") (princ score) ) ;;;;;;;;;; ;; print_state ;; prints the state of the game ;; args: table, score, next_letters (defun print_state (table score next) (setf i 0) (loop (format t "~% |+++|+++|+++|+++|+++|~%") (setf j 0) (princ i) (princ " |") (loop (princ " ") (princ (aref table i j)) (princ " |") (setf j (+ j 1)) (when (> j 4) (return)) ) (setf i (+ i 1)) (when (> i 4) (return)) ) (format t "~% |+++|+++|+++|+++|+++|~%") (format t " 0 1 2 3 4 ~%") (princ "Score: ") (princ score) (princ " Next: ") (princ next) ) ;;;;;;;;;;;; ;; make_move ;; applys a player's move to the board ;; args: table, square moved from, square moved to ;; returns updated table (defun make_move (ta xinit yinit xfin yfin) (setf (aref ta xfin yfin) (aref ta xinit yinit)) (setf (aref ta xinit yinit) '_) ta ) ;;;;;;;;;;;;;; ;; verify_move ;; checks to ensure that player has made a legal move ;; args: table, square moved from, square moved to ;; returns a boolean value (defun verify_move (table xinit yinit xfin yfin) (if (or (> xinit 4) (< xinit 0) (> yinit 4) (< yinit 0) (> xfin 4) (< xfin 0) (> yfin 4) (< yfin 0) (equal (aref table xinit yinit) '_) (not (equal (aref table xfin yfin) '_))) nil t ) ) ;;;;;;;;;;;;;; ;; get_random function ;; returns a random number modulus the input (defun get_random (modulus) (random modulus state) ) ;;;;;;;;;;; ;; get_random_letters ;; creates a list of three random letters from the letter_list ;; arg: letter_list ;; returns a list (defun get_random_letters (letter_list) (list (nth (get_random (length letter_list)) letter_list) (nth (get_random (length letter_list)) letter_list) (nth (get_random (length letter_list)) letter_list) ) ) ;;;;;;;;;;;;;;; ;; slot_empty? ;; checks to see if a particular square is empty ;; args: table, square ;; returns boolean value (defun slot_empty? (table x y) (if (equal (aref table x y) '_) t ) ) ;;;;;;;;;;;;; ;; board_full? ;; checks to see if the board is full ;; arg: table ;; returns a boolean value (defun board_full? (table) (setf i 0) (setf flag 0) (loop (setf j 0) (loop (if (slot_empty? table i j) (setf flag 1) ) (setf j (+ j 1)) (when (> j 4) (return)) ) (setf i (+ i 1)) (when (> i 4) (return)) ) (if (equal flag 1) nil t) ) ;;;;;;;;;;;;;;; ;; add_to_table ;; adds a single letter to the table ;; args: table, letter, x-coor, y-coor ;; returns table (defun add_to_table (table letter i j) (setf (aref table i j) letter) table ) ;;;;;;;;;;;;;; ;; add_all ;; adds a list of letters to the table ;; args: table, list of letters ;; returns table (defun add_all (table three_letters) (dolist (x three_letters) (loop (setq k (get_random 5)) (setq l (get_random 5)) (when (slot_empty? table k l) (return) ) (when (board_full? table) (return) ) ) (if (not (board_full? table)) (setf table (add_to_table table x k l)) ) ) table ) ;;;;;;;;;;;;;; ;; update_board ;; takes a player's move and generates all consequences of it ;; args: table, row r, column c (defun update_board (table r c) ;; Get a list of unit vectors in whose direction we should search (setf direction (list (if (and (> r 0) (> c 0) (equal (aref table (- r 1) (- c 1)) (aref table r c))) '(-1 -1)) (if (and (> c 0) (equal (aref table r (- c 1)) (aref table r c))) '(0 -1)) (if (and (< r 4) (> c 0) (equal (aref table (+ r 1) (- c 1)) (aref table r c))) '(1 -1)) (if (and (< r 4) (equal (aref table (+ r 1) c) (aref table r c))) '(1 0)) (if (and (< r 4) (< c 4) (equal (aref table (+ r 1) (+ c 1)) (aref table r c))) '(1 1)) (if (and (< c 4) (equal (aref table r (+ c 1)) (aref table r c))) '(0 1)) (if (and (> r 0) (< c 4) (equal (aref table (- r 1) (+ c 1)) (aref table r c))) '(-1 1)) (if (and (> r 0) (equal (aref table (- r 1) c) (aref table r c))) '(-1 0)) ) ) ;; Compile list of squares to remove. (setf remove_list ()) (dolist (vector direction) (cond ((not (null vector)) (setf i (+ r (car vector))) ; First square in direction (setf j (+ c (cadr vector))) ; of vector (setf i1 (+ i (car vector))) ; Second square in direction (setf j1 (+ j (cadr vector))) ; of vector (setf i2 (+ r (- 0 (car vector)))) ; First square in direction opposite vector (setf j2 (+ c (- 0 (cadr vector)))) ;; Check to see if there is a third matching value ; Check in direction of vector (cond ((and (> i1 -1) (< i1 5) (> j1 -1) (< j1 5) (equal (aref table r c) (aref table i1 j1)) ) (setf remove_list (append remove_list (list (list i j)))) (setf remove_list (append remove_list (list (list i1 j1)))) ;; After confirming three values, add all others in the line (setf i3 i1) (setf j3 j1) (loop (setf i3 (+ i3 (car vector))) (setf j3 (+ j3 (cadr vector))) (when (or (< i3 0) (> i3 4) (< j3 0) (> j3 4)) (return) ) (if (equal (aref table r c) (aref table i3 j3)) (setf remove_list (append remove_list (list (list i3 j3)))) (return) ) ) ) ) ; Check in direction opposite vector (cond ((and (> i2 -1) (< i2 5) (> j2 -1) (< j2 5) (equal (aref table r c) (aref table i2 j2)) (not (and (> i1 -1) (< i1 5) (> j1 -1) (< j1 5) (equal (aref table r c) (aref table i1 j1)) ) ) ) ; Add if it hasn't been added (setf remove_list (append remove_list (list (list i j)))) ) ) ) ) ) ;; Finally, add the moved piece to the remove_list, ;; remove all pieces in remove_list, and update score (if (not (null remove_list)) (setf remove_list (append remove_list (list (list r c)))) ) (dolist (piece remove_list) (setf (aref table (car piece) (cadr piece)) '_) ) (if (AND (equal real? 'y) (not (null remove_list))) (increase_score (length remove_list)) ) table ) ;;;;;;;;;;; ;; increase_score ;; increases the current score by applying a function to the number of pieces ;; arg: number of pieces (defun increase_score (pieces) (if (< pieces 11) (setf score (+ score (score_function pieces))) (setf score (+ score 200)) ) ) ;;;;;;;;;;;; ;; score_function ;; applys a function to the number of pieces removed, resulting in a score ;; arg: number ;; returns: score (defun score_function (n) (case n (3 20) (4 30) (5 45) (6 65) (7 90) (8 120) (9 155) (10 200) ) ) ;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;; ;; AI Functions ;; ;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;; ;; generate_move ;; If top? is equals y, then it returns the move with the lowest score ;; Otherwise, returns the score of the best move for this table. ;; args: table, depth_so_far, next_three, top? ;; returns: move or score (defun generate_move (table depth_so_far next_three top?) (let ((filled_slots (get_filled_slots table)) (move '(0 0 0 0)) (best_move_score 26) ) (dolist (from (car filled_slots)) (dolist (to (cadr filled_slots)) (setf current_table (copy_table table)) (setf this_move_score (generate_move_helper depth_so_far (update_board (make_move current_table (first from) (second from) (first to) (second to)) (first to) (second to)) next_three) ) (cond ((< this_move_score best_move_score) (if (= depth_so_far 0) (setf move (list (first from) (second from) (first to) (second to))) ) (setf best_move_score this_move_score) ) ) ) ) (if (equal top? 'y) (setf return_value move) (setf return_value best_move_score) ) return_value ) ) ;;;;;;;;;;;;;;;;;;;;;;; ;; generate_move_helper ;; If max_depth is reached, returns the number of pieces on the table ;; If number of pieces on the table is < 3, then returns 25 ;; Otherwise, takes a completed move, adds next three to all spaces and ;; runs generate_move on them. Returns the mean of the values returned ;; from each move. ;; args: depth_so_far, table, next_three ;; returns: score of table (defun generate_move_helper (depth_so_far table next) (cond ((not (or (= depth_so_far max_depth) (< (count_pieces table) 3))) (setf possible_scores ()) (setf depth_so_far (+ 1 depth_so_far)) (dotimes (n 3) (setf current_table (copy_table table)) (setf current_table (add_all current_table next)) (setf current_next (get_random_letters letter_list)) (setf possible_scores (cons (generate_move current_table depth_so_far current_next 'n) possible_scores) ) ) ) ) (if (= depth_so_far max_depth) (setf value (evaluation table)) (if (< (count_pieces table) 3) (setf value 25) (setf value (mean possible_score)) ) ) value ) ;;;;;;;;;;;;;;;;;;; ;; get_filled_slots ;; generates a list of all the slots in the table that contain a letter ;; args: table ;; returns: a list with two sublists. One for filled slots, one for empty. ;; Each sublist contains two sublists. The first for the rows, ;; the second for the columns. ;; (defun get_filled_slots (table) (setf filled_list () empty_list ()) (setf i 0) (loop (setf j 0) (loop (cond ((slot_empty? table i j) (setf empty_list (cons (list i j) empty_list)) ) ) (cond ((not (slot_empty? table i j)) (setf filled_list (cons (list i j) filled_list)) ) ) (setf j (+ j 1)) (when (> j 4) (return) ) ) (setf i (+ i 1)) (when (> i 4) (return) ) ) (list filled_list empty_list) ) ;;;;;;;;;;;;;;;;;;;; ;; copy_table ;; generates a copy of the table ;; args: table ;; returns: table_copy (defun copy_table (table) (setf table_copy (make-array '(5 5) :initial-element '_)) (dotimes (i 5) (dotimes (j 5) (setf (aref table_copy i j) (aref table i j)) ) ) table_copy ) ;;;;;;;;;;;;;;;;;;;; ;; count_pieces ;; counts the number of pieces on the board ;; args: table ;; returns: number of pieces (defun count_pieces (table) (setf count 0) (dotimes (i 5) (dotimes (j 5) (if (not (slot_empty? table i j)) (setf count (+ 1 count)) ) ) ) count ) ;;;;;;;;;;;;;;;;;;;;; ;; 3/4equal ;; Returns t if the three/four args are equal ;; args: a, b, c, (d) ;; returns: boolean value (defun 3equal (a b c) (setf return_boolean nil) (if (and (equal a b) (equal b c) ) (setf return_boolean t) ) return_boolean ) (defun 4equal (a b c d) (setf return_boolean nil) (if (and (equal a b) (equal b c) (equal c d) ) (setf return_boolean t) ) return_boolean ) ;;;;;;;;;;;;;;;;;;;; ;; mean ;; calculates the mean value of a list of numbers ;; args: list of numbers ;; returns: mean of the numbers (defun mean (numbers) (setf total 0) (dolist (x numbers) (setf total (+ total x)) ) (/ total (length numbers)) ) ;;;;;;;;;;;;;;;;;;;;; ;; evaluation ;; Assigns a value to the setup of any board ;; args: table ;; returns: value (defun evaluation (table) (setf count 0) (setf vert_lines (make-array '(5) :initial-element ())) (setf horiz_lines (make-array '(5) :initial-element ())) (setf maj_diag_lines (make-array '(5) :initial-element ())) (setf min_diag_lines (make-array '(5) :initial-element ())) (setf table_value 0) ;; Horizontal cases (setf start_points '(0 0 1 0 2 0 3 0 4 0)) (dotimes (n 5) (setf p (nth (* 2 n) start_points)) (setf q (nth (+ (* 2 n) 1) start_points)) (cond ((or (= n 0) (= n 4)) (if (or (and (equal (aref table p q) (aref table p (+ q 1))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table p (+ q 2))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p (+ q 1)) (aref table p (+ q 2))) (equal (aref table p q) '_) (not (equal (aref table p (+ q 1)) '_))) ) (setf (aref horiz_lines n) (list 2 2)) (setf (aref horiz_lines n) ()) ) ) ) (cond ((or (= n 1) (= n 3)) (if (or (and (equal (aref table p q) (aref table p (+ q 1))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table p (+ q 2))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p (+ q 1)) (aref table p (+ q 2))) (or (equal (aref table p q) '_) (equal (aref table p (+ q 3)) '_)) (not (equal (aref table p (+ q 1)) '_))) (and (equal (aref table p (+ q 3)) (aref table p (+ q 2))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p (+ q 3)) '_))) (and (equal (aref table p (+ q 1)) (aref table p (+ q 3))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p (+ q 3)) '_))) ) (setf (aref horiz_lines n) (list 2 2)) (setf (aref horiz_lines n) ()) ) (if (or (and (3equal (aref table p (+ q 1)) (aref table p (+ q 2)) (aref table p q)) (equal (aref table p (+ q 3)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p (+ q 1)) (aref table p (+ q 2)) (aref table p (+ q 3))) (equal (aref table p q) '_) (not (equal (aref table p (+ q 3)) '_))) (and (3equal (aref table p q) (aref table p (+ q 2)) (aref table p (+ q 3))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table p (+ q 1)) (aref table p (+ q 3))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p q) '_))) ) (setf (aref horiz_lines n) (list 3 3 3)) ) ) ) (cond ((= n 2) (if (or (and (equal (aref table p q) (aref table p (+ q 1))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table p (+ q 2))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p (+ q 1)) (aref table p (+ q 2))) (or (equal (aref table p q) '_) (equal (aref table p (+ q 3)) '_)) (not (equal (aref table p (+ q 1)) '_))) (and (equal (aref table p (+ q 3)) (aref table p (+ q 2))) (or (equal (aref table p (+ q 1)) '_) (equal (aref table p (+ q 4)) '_)) (not (equal (aref table p (+ q 2)) '_))) (and (equal (aref table p (+ q 1)) (aref table p (+ q 3))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p (+ q 1)) '_))) (and (equal (aref table p (+ q 2)) (aref table p (+ q 4))) (equal (aref table p (+ q 3)) '_) (not (equal (aref table p (+ q 2)) '_))) (and (equal (aref table p (+ q 3)) (aref table p (+ q 4))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p (+ q 3)) '_))) ) (setf (aref horiz_lines n) (list 2 2)) (setf (aref horiz_lines n) ()) ) (if (or (and (3equal (aref table p (+ q 1)) (aref table p (+ q 2)) (aref table p q)) (equal (aref table p (+ q 3)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p (+ q 1)) (aref table p (+ q 2)) (aref table p (+ q 3))) (or (equal (aref table p q) '_) (equal (aref table p (+ q 4)) '_)) (not (equal (aref table p (+ q 3)) '_))) (and (3equal (aref table p q) (aref table p (+ q 2)) (aref table p (+ q 3))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table p (+ q 1)) (aref table p (+ q 3))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p (+ q 4)) (aref table p (+ q 2)) (aref table p (+ q 3))) (equal (aref table p (+ q 1)) '_) (not (equal (aref table p (+ q 4)) '_))) (and (3equal (aref table p (+ q 4)) (aref table p (+ q 1)) (aref table p (+ q 3))) (equal (aref table p (+ q 2)) '_) (not (equal (aref table p (+ q 4)) '_))) ) (setf (aref horiz_lines n) (list 3 3 3)) ) (if (or (and (4equal (aref table p (+ q 1)) (aref table p (+ q 2)) (aref table p q) (aref table p (+ q 3))) (equal (aref table p (+ q 4)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p (+ q 1)) (aref table p (+ q 2)) (aref table p (+ q 4)) (aref table p (+ q 3))) (equal (aref table p q) '_) (not (equal (aref table p (+ q 4)) '_))) (and (4equal (aref table p q) (aref table p (+ q 2)) (aref table p (+ q 4)) (aref table p (+ q 3))) (equal (aref table p (+ 1 q)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table p (+ q 1)) (aref table p (+ q 4)) (aref table p (+ q 3))) (equal (aref table p (+ 2 q)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table p (+ q 1)) (aref table p (+ q 4)) (aref table p (+ q 2))) (equal (aref table p (+ 3 q)) '_) (not (equal (aref table p q) '_))) ) (setf (aref horiz_lines n) (list 4 4 4 4)) ) ) ) ) ;; Vertical cases (setf start_points '(0 0 0 1 0 2 0 3 0 4)) (dotimes (n 5) (setf p (nth (* 2 n) start_points)) (setf q (nth (+ (* 2 n) 1) start_points)) (cond ((or (= n 0) (= n 4)) (if (or (and (equal (aref table p q) (aref table (+ p 1) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) q) (aref table (+ p 2) q)) (equal (aref table p q) '_) (not (equal (aref table (+ p 1) q) '_))) ) (setf (aref vert_lines n) (list 2 2)) (setf (aref vert_lines n) ()) ) ) ) (cond ((or (= n 1) (= n 3)) (if (or (and (equal (aref table p q) (aref table (+ p 1) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) q) (aref table (+ p 2) q)) (or (equal (aref table p q) '_) (equal (aref table (+ p 3) q) '_)) (not (equal (aref table (+ p 1) q) '_))) (and (equal (aref table (+ p 3) q) (aref table (+ p 2) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table (+ p 3) q) '_))) (and (equal (aref table (+ p 1) q) (aref table (+ p 3) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table (+ p 3) q) '_))) ) (setf (aref vert_lines n) (list 2 2)) (setf (aref vert_lines n) ()) ) (if (or (and (3equal (aref table (+ p 1) q) (aref table (+ p 2) q) (aref table p q)) (equal (aref table (+ p 3) q) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 1) q) (aref table (+ p 2) q) (aref table (+ p 3) q)) (equal (aref table p q) '_) (not (equal (aref table (+ p 3) q) '_))) (and (3equal (aref table p q) (aref table (+ p 2) q) (aref table (+ p 3) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table (+ p 1) q) (aref table (+ p 3) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table p q) '_))) ) (setf (aref vert_lines n) (list 3 3 3)) ) ) ) (cond ((= n 2) (if (or (and (equal (aref table p q) (aref table (+ p 1) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) q) (aref table (+ p 2) q)) (or (equal (aref table p q) '_) (equal (aref table (+ p 3) q) '_)) (not (equal (aref table (+ p 1) q) '_))) (and (equal (aref table (+ p 3) q) (aref table (+ p 2) q)) (or (equal (aref table (+ p 1) q) '_) (equal (aref table (+ p 4) q) '_)) (not (equal (aref table (+ p 2) q) '_))) (and (equal (aref table (+ p 1) q) (aref table (+ p 3) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table (+ p 1) q) '_))) (and (equal (aref table (+ p 2) q) (aref table (+ p 4) q)) (equal (aref table (+ p 3) q) '_) (not (equal (aref table (+ p 2) q) '_))) (and (equal (aref table (+ p 3) q) (aref table (+ p 4) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table (+ p 3) q) '_))) ) (setf (aref vert_lines n) (list 2 2)) (setf (aref vert_lines n) ()) ) (if (or (and (3equal (aref table (+ p 1) q) (aref table (+ p 2) q) (aref table p q)) (equal (aref table (+ p 3) q) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 1) q) (aref table (+ p 2) q) (aref table (+ p 3) q)) (or (equal (aref table p q) '_) (equal (aref table (+ p 4) q) '_)) (not (equal (aref table (+ p 3) q) '_))) (and (3equal (aref table p q) (aref table (+ p 2) q) (aref table (+ p 3) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table (+ p 1) q) (aref table (+ p 3) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 4) q) (aref table (+ p 2) q) (aref table (+ p 3) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table (+ p 4) q) '_))) (and (3equal (aref table (+ p 4) q) (aref table (+ p 1) q) (aref table (+ p 3) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table (+ p 4) q) '_))) ) (setf (aref vert_lines n) (list 3 3 3)) ) (if (or (and (4equal (aref table (+ p 1) q) (aref table (+ p 2) q) (aref table p q) (aref table (+ p 3) q)) (equal (aref table (+ p 4) q) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table (+ p 1) q) (aref table (+ p 2) q) (aref table (+ p 4) q) (aref table (+ p 3) q)) (equal (aref table p q) '_) (not (equal (aref table (+ p 4) q) '_))) (and (4equal (aref table p q) (aref table (+ p 2) q) (aref table (+ p 4) q) (aref table (+ p 3) q)) (equal (aref table (+ p 1) q) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table (+ p 1) q) (aref table (+ p 4) q) (aref table (+ p 3) q)) (equal (aref table (+ p 2) q) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table (+ p 1) q) (aref table (+ p 4) q) (aref table (+ p 2) q)) (equal (aref table (+ p 3) q) '_) (not (equal (aref table p q) '_))) ) (setf (aref vert_lines n) (list 4 4 4 4)) ) ) ) ) ;; Major Diagonal cases (setf start_points '(2 0 1 0 0 0 0 1 0 2)) (dotimes (n 5) (setf p (nth (* 2 n) start_points)) (setf q (nth (+ (* 2 n) 1) start_points)) (cond ((or (= n 0) (= n 4)) (if (or (and (equal (aref table p q) (aref table (+ p 1) (+ q 1))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) (+ q 2))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2))) (equal (aref table p q) '_) (not (equal (aref table (+ p 1) (+ q 1)) '_))) ) (setf (aref maj_diag_lines n) (list 2 2)) (setf (aref maj_diag_lines n) ()) ) ) ) (cond ((or (= n 1) (= n 3)) (if (or (and (equal (aref table p q) (aref table (+ p 1) (+ q 1))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) (+ q 2))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2))) (or (equal (aref table p q) '_) (equal (aref table (+ p 3) (+ q 3)) '_)) (not (equal (aref table (+ p 1) (+ q 1)) '_))) (and (equal (aref table (+ p 3) (+ q 3)) (aref table (+ p 2) (+ q 2))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table (+ p 3) (+ q 3)) '_))) (and (equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table (+ p 3) (+ q 3)) '_))) ) (setf (aref maj_diag_lines n) (list 2 2)) (setf (aref maj_diag_lines n) ()) ) (if (or (and (3equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2)) (aref table p q)) (equal (aref table (+ p 3) (+ q 3)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2)) (aref table (+ p 3) (+ q 3))) (equal (aref table p q) '_) (not (equal (aref table (+ p 3) (+ q 3)) '_))) (and (3equal (aref table p q) (aref table (+ p 2) (+ q 2)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table (+ p 1) (+ q 1)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table p q) '_))) ) (setf (aref maj_diag_lines n) (list 3 3 3)) ) ) ) (cond ((= n 2) (if (or (and (equal (aref table p q) (aref table (+ p 1) (+ q 1))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) (+ q 2))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2))) (or (equal (aref table p q) '_) (equal (aref table (+ p 3) (+ q 3)) '_)) (not (equal (aref table (+ p 1) (+ q 1)) '_))) (and (equal (aref table (+ p 3) (+ q 3)) (aref table (+ p 2) (+ q 2))) (or (equal (aref table (+ p 1) (+ q 1)) '_) (equal (aref table (+ p 4) (+ q 4)) '_)) (not (equal (aref table (+ p 2) (+ q 2)) '_))) (and (equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table (+ p 1) (+ q 1)) '_))) (and (equal (aref table (+ p 2) (+ q 2)) (aref table (+ p 4) (+ q 4))) (equal (aref table (+ p 3) (+ q 3)) '_) (not (equal (aref table (+ p 2) (+ q 2)) '_))) (and (equal (aref table (+ p 3) (+ q 3)) (aref table (+ p 4) (+ q 4))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table (+ p 3) (+ q 3)) '_))) ) (setf (aref maj_diag_lines n) (list 2 2)) (setf (aref maj_diag_lines n) ()) ) (if (or (and (3equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2)) (aref table p q)) (equal (aref table (+ p 3) (+ q 3)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2)) (aref table (+ p 3) (+ q 3))) (or (equal (aref table p q) '_) (equal (aref table (+ p 4) (+ q 4)) '_)) (not (equal (aref table (+ p 3) (+ q 3)) '_))) (and (3equal (aref table p q) (aref table (+ p 2) (+ q 2)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table (+ p 1) (+ q 1)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 4) (+ q 4)) (aref table (+ p 2) (+ q 2)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 1) (+ q 1)) '_) (not (equal (aref table (+ p 4) (+ q 4)) '_))) (and (3equal (aref table (+ p 4) (+ q 4)) (aref table (+ p 1) (+ q 1)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 2) (+ q 2)) '_) (not (equal (aref table (+ p 4) (+ q 4)) '_))) ) (setf (aref maj_diag_lines n) (list 3 3 3)) ) (if (or (and (4equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2)) (aref table p q) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 4) (+ q 4)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table (+ p 1) (+ q 1)) (aref table (+ p 2) (+ q 2)) (aref table (+ p 4) (+ q 4)) (aref table (+ p 3) (+ q 3))) (equal (aref table p q) '_) (not (equal (aref table (+ p 4) (+ q 4)) '_))) (and (4equal (aref table p q) (aref table (+ p 2) (+ q 2)) (aref table (+ p 4) (+ q 4)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 1) (+ 1 q)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table (+ p 1) (+ q 1)) (aref table (+ p 4) (+ q 4)) (aref table (+ p 3) (+ q 3))) (equal (aref table (+ p 2) (+ 2 q)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table (+ p 1) (+ q 1)) (aref table (+ p 4) (+ q 4)) (aref table (+ p 2) (+ q 2))) (equal (aref table (+ p 3) (+ 3 q)) '_) (not (equal (aref table p q) '_))) ) (setf (aref maj_diag_lines n) (list 4 4 4 4)) ) ) ) ) ;; Minor Diagonal cases (setf start_points '(0 2 0 3 0 4 1 4 2 4)) (dotimes (n 5) (setf p (nth (* 2 n) start_points)) (setf q (nth (+ (* 2 n) 1) start_points)) (cond ((or (= n 0) (= n 4)) (if (or (and (equal (aref table p q) (aref table (+ p 1) (- q 1))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) (- q 2))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2))) (equal (aref table p q) '_) (not (equal (aref table (+ p 1) (- q 1)) '_))) ) (setf (aref min_diag_lines n) (list 2 2)) (setf (aref min_diag_lines n) ()) ) ) ) (cond ((or (= n 1) (= n 3)) (if (or (and (equal (aref table p q) (aref table (+ p 1) (- q 1))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) (- q 2))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2))) (or (equal (aref table p q) '_) (equal (aref table (+ p 3) (- q 3)) '_)) (not (equal (aref table (+ p 1) (- q 1)) '_))) (and (equal (aref table (+ p 3) (- q 3)) (aref table (+ p 2) (- q 2))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table (+ p 3) (- q 3)) '_))) (and (equal (aref table (+ p 1) (- q 1)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table (+ p 3) (- q 3)) '_))) ) (setf (aref min_diag_lines n) (list 2 2)) (setf (aref min_diag_lines n) ()) ) (if (or (and (3equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2)) (aref table p q)) (equal (aref table (+ p 3) (- q 3)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2)) (aref table (+ p 3) (- q 3))) (equal (aref table p q) '_) (not (equal (aref table (+ p 3) (- q 3)) '_))) (and (3equal (aref table p q) (aref table (+ p 2) (- q 2)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table (+ p 1) (- q 1)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table p q) '_))) ) (setf (aref min_diag_lines n) (list 3 3 3)) ) ) ) (cond ((= n 2) (if (or (and (equal (aref table p q) (aref table (+ p 1) (- q 1))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table p q) (aref table (+ p 2) (- q 2))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table p q) '_))) (and (equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2))) (or (equal (aref table p q) '_) (equal (aref table (+ p 3) (- q 3)) '_)) (not (equal (aref table (+ p 1) (- q 1)) '_))) (and (equal (aref table (+ p 3) (- q 3)) (aref table (+ p 2) (- q 2))) (or (equal (aref table (+ p 1) (- q 1)) '_) (equal (aref table (+ p 4) (- q 4)) '_)) (not (equal (aref table (+ p 2) (- q 2)) '_))) (and (equal (aref table (+ p 1) (- q 1)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table (+ p 1) (- q 1)) '_))) (and (equal (aref table (+ p 2) (- q 2)) (aref table (+ p 4) (- q 4))) (equal (aref table (+ p 3) (- q 3)) '_) (not (equal (aref table (+ p 2) (- q 2)) '_))) (and (equal (aref table (+ p 3) (- q 3)) (aref table (+ p 4) (- q 4))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table (+ p 3) (- q 3)) '_))) ) (setf (aref min_diag_lines n) (list 2 2)) (setf (aref min_diag_lines n) ()) ) (if (or (and (3equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2)) (aref table p q)) (equal (aref table (+ p 3) (- q 3)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2)) (aref table (+ p 3) (- q 3))) (or (equal (aref table p q) '_) (equal (aref table (+ p 4) (- q 4)) '_)) (not (equal (aref table (+ p 3) (- q 3)) '_))) (and (3equal (aref table p q) (aref table (+ p 2) (- q 2)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table p q) (aref table (+ p 1) (- q 1)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table p q) '_))) (and (3equal (aref table (+ p 4) (- q 4)) (aref table (+ p 2) (- q 2)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table (+ p 4) (- q 4)) '_))) (and (3equal (aref table (+ p 4) (- q 4)) (aref table (+ p 1) (- q 1)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table (+ p 4) (- q 4)) '_))) ) (setf (aref min_diag_lines n) (list 3 3 3)) ) (if (or (and (4equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2)) (aref table p q) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 4) (- q 4)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table (+ p 1) (- q 1)) (aref table (+ p 2) (- q 2)) (aref table (+ p 4) (- q 4)) (aref table (+ p 3) (- q 3))) (equal (aref table p q) '_) (not (equal (aref table (+ p 4) (- q 4)) '_))) (and (4equal (aref table p q) (aref table (+ p 2) (- q 2)) (aref table (+ p 4) (- q 4)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 1) (- q 1)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table (+ p 1) (- q 1)) (aref table (+ p 4) (- q 4)) (aref table (+ p 3) (- q 3))) (equal (aref table (+ p 2) (- q 2)) '_) (not (equal (aref table p q) '_))) (and (4equal (aref table p q) (aref table (+ p 1) (- q 1)) (aref table (+ p 4) (- q 4)) (aref table (+ p 2) (- q 2))) (equal (aref table (+ p 3) (- q 3)) '_) (not (equal (aref table p q) '_))) ) (setf (aref min_diag_lines n) (list 4 4 4 4)) ) ) ) ) (dotimes (n 5) (setf table_value (+ table_value (length (aref horiz_lines n)) (length (aref vert_lines n)) (length (aref maj_diag_lines n)) (length (aref min_diag_lines n))) ) ) (setf count (count_pieces table)) (setf table_value (- count (/ table_value 1000))) table_value )