1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: reversi -*-
2 ;;;;***************************************************************************
4 ;;;; FILE IDENTIFICATION
7 ;;;; Purpose: Basic Input-Output for reversi
8 ;;;; Programer: Kevin Rosenberg based on code by Peter Norvig
9 ;;;; Date Started: 1 Nov 2001
11 ;;;; $Id: io.lisp,v 1.3 2003/05/06 15:51:20 kevin Exp $
13 ;;;; This file is Copyright (c) 2001-2002 by Kevin M. Rosenberg
14 ;;;; and Copyright (c) 1998-2002 Peter Norvig
16 ;;;; Reversi users are granted the rights to distribute and use this software
17 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
18 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
19 ;;;;***************************************************************************
21 (in-package #:reversi)
23 (eval-when (:compile-toplevel)
24 (declaim (optimize (safety 1) (space 0) (speed 3) (compilation-speed 0))))
27 (eval-when (:compile-toplevel :load-toplevel :execute)
29 (cross-product #'concat-symbol
30 '(? A B C D E F G H ?)
31 '(? 1 2 3 4 5 6 7 8 ?))))
34 "Convert from alphanumeric to numeric square notation."
35 (or (position (string str) square-names :test #'string-equal)
39 "Convert from numeric to alphanumeric square notation."
41 (elt square-names num)
44 (defun moves-to-string (moves)
46 (dotimes (i (length moves))
47 (push (format nil "~2d: ~a ~a~%"
49 (title-of (nth 1 (elt moves i)))
50 (symbol-name (88->h8 (nth 0 (elt moves i)))))
52 (setq move-list (nreverse move-list))
53 (list-to-delimited-string move-list #\space))))
55 (defun human (player board)
56 "A human player for the game of Reversi"
57 (format t "~&~c to move ~a: " (name-of player)
58 (mapcar #'88->h8 (legal-moves player board)))
62 (defun print-board (&optional (board *board*) clock)
63 "Print a board, along with some statistics."
64 ;; First print the header and the current score
65 (format t "~2& A B C D E F G H [~c=~2a ~c=~2a (~@d)]"
66 (name-of black) (count black board)
67 (name-of white) (count white board)
68 (count-difference black board))
69 ;; Print the board itself
70 (loop for row from 1 to 8 do
71 (format t "~& ~d " row)
72 (loop for col from 1 to 8
73 for piece = (bref board (+ col (* 10 row)))
74 do (format t "~c " (name-of piece))))
75 ;; Finally print the time remaining for each player
77 (format t " [~c=~a ~c=~a]~2&"
78 (name-of black) (time-string (elt clock black))
79 (name-of white) (time-string (elt clock white)))))
82 (defun time-string (time)
83 "Return a string representing this internal time in min:secs."
84 (multiple-value-bind (min sec)
85 (floor (round time internal-time-units-per-second) 60)
86 (format nil "~2d:~2,'0d" min sec)))