r3180: *** empty log message ***
[reversi.git] / io.lisp
1 ;;;;***************************************************************************
2 ;;;;
3 ;;;; FILE IDENTIFICATION
4 ;;;; 
5 ;;;;  Name:           io.cl  
6 ;;;;  Purpose:        Basic Input-Output for reversi
7 ;;;;  Programer:      Kevin M. Rosenberg, M.D.
8 ;;;;  Date Started:   1 Nov 2001
9 ;;;;  CVS Id:         $Id: io.lisp,v 1.1 2002/10/25 08:36:42 kevin Exp $
10 ;;;;
11 ;;;;***************************************************************************
12
13 (in-package :reversi)
14 (declaim (optimize (safety 1) (debug 3) (speed 3)))
15
16
17 (eval-when (:compile-toplevel :load-toplevel :execute)
18 (let ((square-names 
19         (cross-product #'concat-symbol
20                        '(? A B C D E F G H ?)
21                        '(? 1 2 3 4 5 6 7 8 ?))))
22
23   (defun h8->88 (str)
24     "Convert from alphanumeric to numeric square notation."
25     (or (position (string str) square-names :test #'string-equal)
26         str))
27
28   (defun 88->h8 (num)
29     "Convert from numeric to alphanumeric square notation."
30     (if (valid-p num)
31         (elt square-names num)
32       num)))
33
34 (defun moves-to-string (moves)
35   (let (move-list)
36     (dotimes (i (length moves))
37       (push (format nil "~2d: ~a ~a~%"
38                     (1+ i)
39                     (title-of (nth 1 (elt moves i)))
40                     (symbol-name (88->h8 (nth 0 (elt moves i)))))
41             move-list))
42     (setq move-list (nreverse move-list))
43     (list-to-delimited-string move-list #\space))))
44
45 (defun human (player board)
46   "A human player for the game of Reversi"
47   (format t "~&~c to move ~a: " (name-of player)
48           (mapcar #'88->h8 (legal-moves player board)))
49   (h8->88 (read)))
50
51
52 (defun print-board (&optional (board *board*) clock)
53   "Print a board, along with some statistics."
54   ;; First print the header and the current score
55   (format t "~2&    A B C D E F G H   [~c=~2a ~c=~2a (~@d)]"
56           (name-of black) (count black board)
57           (name-of white) (count white board)
58           (count-difference black board))
59   ;; Print the board itself
60   (loop for row from 1 to 8 do
61         (format t "~&  ~d " row)
62         (loop for col from 1 to 8
63               for piece = (bref board (+ col (* 10 row)))
64               do (format t "~c " (name-of piece))))
65   ;; Finally print the time remaining for each player
66   (when clock
67     (format t "  [~c=~a ~c=~a]~2&"
68             (name-of black) (time-string (elt clock black))
69             (name-of white) (time-string (elt clock white)))))
70
71
72 (defun time-string (time)
73   "Return a string representing this internal time in min:secs."
74   (multiple-value-bind (min sec)
75       (floor (round time internal-time-units-per-second) 60)
76     (format nil "~2d:~2,'0d" min sec)))
77
78
79        
80