summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2002-04-13 11:13:33 +0000
committerJohn Wiegley <johnw@newartisans.com>2002-04-13 11:13:33 +0000
commit7e960384fa89c02c2fc2be1f61fe18645f8a13fe (patch)
tree66d17d5fb9a7f73a3291e6261f1df2e12612eb2e
parentf4639c9095c34caa60b4122e2cf4d6b1402508e3 (diff)
added message catalog support
-rw-r--r--TODO2
-rw-r--r--chess-algebraic.el20
-rw-r--r--chess-announce.el67
-rw-r--r--chess-common.el15
-rw-r--r--chess-display.el124
-rw-r--r--chess-engine.el88
-rw-r--r--chess-game.el8
-rw-r--r--chess-gnuchess.el2
-rw-r--r--chess-ics.el18
-rw-r--r--chess-images.el13
-rw-r--r--chess-irc.el22
-rw-r--r--chess-message.el47
-rw-r--r--chess-network.el11
-rw-r--r--chess-pgn.el8
-rw-r--r--chess-ply.el67
-rw-r--r--chess-pos.el34
-rw-r--r--chess-var.el5
-rw-r--r--chess.el8
18 files changed, 381 insertions, 178 deletions
diff --git a/TODO b/TODO
index 51ca7a9..0fb441a 100644
--- a/TODO
+++ b/TODO
@@ -27,8 +27,6 @@ laptop.
----------------------------------------------------------------------
-- test making an en passant capture
-
- the game should go inactive once I lose by stalemate/checkmate
- detect draw/resign/abort/retract, etc., from ICS and common engines
diff --git a/chess-algebraic.el b/chess-algebraic.el
index 0960a35..7a430fc 100644
--- a/chess-algebraic.el
+++ b/chess-algebraic.el
@@ -55,6 +55,12 @@ This regexp handles both long and short form.")
(defconst chess-algebraic-regexp-entire
(concat chess-algebraic-regexp "$"))
+(chess-message-catalog 'english
+ '((clarify-piece . "Clarify piece to move by rank or file")
+ (could-not-clarify . "Could not determine which piece to use")
+ (could-not-diff . "Could not differentiate piece")
+ (no-candidates . "There are no candidate moves for '%s'")))
+
(defun chess-algebraic-to-ply (position move &optional trust)
"Convert the algebraic notation MOVE for POSITION to a ply."
(when (string-match chess-algebraic-regexp-entire move)
@@ -89,7 +95,7 @@ This regexp handles both long and short form.")
(if (= (length candidates) 1)
(list (car candidates) target)
(if (null source)
- (error "Clarify piece to move by rank or file")
+ (chess-error 'clarify-piece)
(nconc changes (list :which source))
(while candidates
(if (if (>= source ?a)
@@ -101,10 +107,9 @@ This regexp handles both long and short form.")
candidates nil)
(setq candidates (cdr candidates))))
(if (null which)
- (error "Could not determine which piece to use")
+ (chess-error could-not-clarify)
(list which target))))
- (error "There are no candidate moves for '%s'"
- move))))))
+ (chess-error no-candidates move))))))
(if promotion
(nconc changes (list :promote (aref promotion 0))))))
@@ -145,7 +150,7 @@ If LONG is non-nil, render the move into long notation."
(setq differentiator (+ from-file ?a)))
((= rank 1)
(setq differentiator (+ (- 7 from-rank) ?1)))
- (t (error "Could not differentiate piece"))))))
+ (t (chess-error 'could-not-diff))))))
(concat
(unless (= (upcase from-piece) ?P)
(char-to-string (upcase from-piece)))
@@ -157,10 +162,11 @@ If LONG is non-nil, render the move into long notation."
(/= (chess-index-file from)
(chess-index-file to)))
(char-to-string (+ (chess-index-file from) ?a)))))
- (if (/= ? (chess-pos-piece pos to))
+ (if (or (/= ? (chess-pos-piece pos to))
+ (chess-ply-keyword ply :en-passant))
"x" (if long "-"))
(chess-index-to-coord to)
- (let ((promote (memq :promote (chess-ply-changes ply))))
+ (let ((promote (chess-ply-keyword ply :promote)))
(if promote
(concat "=" (char-to-string
(upcase (cadr promote))))))
diff --git a/chess-announce.el b/chess-announce.el
index f4c8f11..ff1a331 100644
--- a/chess-announce.el
+++ b/chess-announce.el
@@ -6,13 +6,28 @@
(require 'chess-game)
+(chess-message-catalog 'english
+ '((queen . "queen")
+ (king . "king")
+ (bishop . "bishop")
+ (knight . "knight")
+ (rook . "rook")
+ (pawn . "pawn")
+ (short-castle . "short castle")
+ (long-castle . "long castle")
+ (check . "check")
+ (checkmate . "checkmate")
+ (stalemate . "stalemate")
+ (piece-moves . "%s to %s")
+ (piece-takes . "%s takes %s at %s")))
+
(defvar chess-announce-names
- '((?q . "queen")
- (?k . "king")
- (?b . "bishop")
- (?n . "knight")
- (?r . "rook")
- (?p . "pawn")))
+ '((?q . queen)
+ (?k . king)
+ (?b . bishop)
+ (?n . knight)
+ (?r . rook)
+ (?p . pawn)))
(autoload 'festival-start-process "festival")
(autoload 'festival-kill-process "festival")
@@ -58,31 +73,35 @@ See `chess-display-type' for the different kinds of displays."
(setq which (char-to-string which)))
(cond
((chess-ply-keyword ply :castle)
- (setq text "short castle"))
+ (setq text (chess-string 'short-castle)))
((chess-ply-keyword ply :long-castle)
- (setq text "long castle"))
+ (setq text (chess-string 'long-castle)))
((= t-piece ? )
- (setq text (concat which
- (cdr (assq (downcase s-piece)
- chess-announce-names))
- " to "
- (chess-index-to-coord target))))
+ (setq text
+ (concat which
+ (chess-string 'piece-moves
+ (chess-string
+ (cdr (assq (downcase s-piece)
+ chess-announce-names)))
+ (chess-index-to-coord target)))))
(t
- (setq text (concat which
- (cdr (assq (downcase s-piece)
- chess-announce-names))
- " takes "
- (cdr (assq (downcase t-piece)
- chess-announce-names))
- " at "
- (chess-index-to-coord target)))))
+ (setq text
+ (concat which
+ (chess-string 'piece-takes
+ (chess-string
+ (cdr (assq (downcase s-piece)
+ chess-announce-names)))
+ (chess-string
+ (cdr (assq (downcase t-piece)
+ chess-announce-names)))
+ (chess-index-to-coord target))))))
(if (chess-ply-keyword ply :check)
- (setq text (concat text ", check")))
+ (setq text (concat text ", " (chess-string 'check))))
(if (chess-ply-keyword ply :checkmate)
- (setq text (concat text ", checkmate")))
+ (setq text (concat text ", " (chess-string 'checkmate))))
(if (chess-ply-keyword ply :stalemate)
- (setq text (concat text ", stalemate")))
+ (setq text (concat text ", " (chess-string 'stalemate))))
(funcall (nth 1 chess-announce-functions) text)))))))
diff --git a/chess-common.el b/chess-common.el
index 66a4b99..f468dca 100644
--- a/chess-common.el
+++ b/chess-common.el
@@ -21,6 +21,13 @@
(put 'chess-with-temp-file 'lisp-indent-function 1)
+(chess-message-catalog 'english
+ '((starting-engine . "Starting chess program '%s'...")
+ (starting-engine-done . "Starting chess program '%s'...done")
+ (could-not-find-engine . "Cannot find %s executable; check `%s'")
+ (draw-offer-declined . "Your draw offer was declined")
+ (illegal-move . "Illegal move")))
+
(defun chess-common-handler (event &rest args)
"Initialize the network chess engine."
(cond
@@ -28,12 +35,12 @@
(let* ((name (car args))
(path (intern (concat "chess-" name "-path")))
proc)
- (message "Starting chess program '%s'..." name)
+ (chess-message 'starting-engine name)
(unless (boundp path)
- (error "Cannot find %s executable; check `%s'" name path))
+ (chess-error 'could-not-find-engine name path))
(setq proc (start-process (concat "chess-" name)
(current-buffer) (symbol-value path)))
- (message "Starting chess program '%s'...done" name)
+ (chess-message 'starting-engine-done name)
proc))
((eq event 'ready)
@@ -53,7 +60,7 @@
(chess-engine-send nil "resign\n"))
((eq event 'draw)
- (message "Your draw offer was declined"))
+ (chess-message 'draw-offer-declined))
((memq event '(resign abort))
(chess-engine-send nil "new\n")
diff --git a/chess-display.el b/chess-display.el
index ca75eeb..cc0106a 100644
--- a/chess-display.el
+++ b/chess-display.el
@@ -4,8 +4,6 @@
;;
;; $Revision$
-;;; Code:
-
(require 'chess-game)
(require 'chess-var)
(require 'chess-algebraic)
@@ -64,6 +62,9 @@
,@body)
,@body)))
+(chess-message-catalog 'english
+ '((no-such-style . "There is no such chessboard display style '%s'")))
+
(defun chess-display-create (game style perspective &optional main read-only)
"Create a chess display, for displaying chess objects.
The display is drawn using the given STYLE, from the PERSPECTIVE
@@ -75,7 +76,7 @@ makes moves, or any other changes to the underlying game."
(let* ((name (symbol-name style))
(handler (intern-soft (concat name "-handler"))))
(unless handler
- (error "There is no such chessboard display style '%s'" name))
+ (chess-error 'no-such-style name))
(with-current-buffer (generate-new-buffer "*Chessboard*")
(chess-display-mode read-only)
(funcall handler 'initialize)
@@ -549,6 +550,9 @@ Basically, it means we are playing, not editing or reviewing."
(chess-game-run-hooks chess-display-game 'shutdown)
(chess-display-destroy nil)))
+(chess-message-catalog 'english
+ '((illegal-notation . "Illegal move notation: %s")))
+
(defun chess-display-manual-move (move)
"Move a piece manually, using chess notation."
(interactive
@@ -559,7 +563,7 @@ Basically, it means we are playing, not editing or reviewing."
(1+ (/ (or chess-display-index 0) 2))))))
(let ((ply (chess-algebraic-to-ply (chess-display-position nil) move)))
(unless ply
- (error "Illegal move notation: %s" move))
+ (chess-error 'illegal-notation move))
(chess-display-move nil ply)))
(defun chess-display-remote (display)
@@ -616,12 +620,15 @@ Basically, it means we are playing, not editing or reviewing."
(chess-game-run-hooks chess-display-game 'abort)
(ding)))
+(chess-message-catalog 'english
+ '((draw-offer . "You offer a draw")))
+
(defun chess-display-draw ()
"Offer to draw the current game."
(interactive)
(if (chess-display-active-p)
(progn
- (message "You offer a draw")
+ (chess-message 'draw-offer)
(chess-game-run-hooks chess-display-game 'draw))
(ding)))
@@ -663,6 +670,9 @@ Basically, it means we are playing, not editing or reviewing."
(call-interactively lb-command))
(fset 'buffer-list buffer-list-func))))
+(chess-message-catalog 'english
+ '((return-to-current . "Use '>' to return to the current position")))
+
(defun chess-display-set-current (dir)
"Change the currently displayed board.
Direction may be - or +, to move forward or back, or t or nil to jump
@@ -674,7 +684,7 @@ to the end or beginning."
(chess-display-set-index
nil (or index (chess-game-index chess-display-game)))
(unless (chess-display-active-p)
- (message "Use '>' to return to the current position"))))
+ (chess-message 'return-to-current))))
(defun chess-display-move-backward ()
(interactive)
@@ -713,6 +723,10 @@ to the end or beginning."
map)
"The mode map used for editing a chessboard position.")
+(chess-message-catalog 'english
+ '((editing-directly
+ . "Now editing position directly, use S when complete...")))
+
(defun chess-display-edit-board ()
"Setup the current board for editing."
(interactive)
@@ -722,7 +736,7 @@ to the end or beginning."
;; for which purpose the movement keys can still be used.
(chess-display-set-position nil (chess-display-position nil))
;; jww (2002-03-28): setup edit-mode keymap here
- (message "Now editing position directly, use S when complete..."))
+ (chess-message 'editing-directly))
(defun chess-display-send-board ()
"Send the current board configuration to the user."
@@ -804,17 +818,21 @@ to the end or beginning."
(make-variable-buffer-local 'chess-legal-moves-pos)
(make-variable-buffer-local 'chess-legal-moves)
+(chess-message-catalog 'english
+ '((not-your-move . "It is not your turn to move")
+ (game-is-over . "This game is over")))
+
(defun chess-display-assert-can-move ()
(if (and (chess-display-active-p)
;; `active' means we're playing against an engine
(chess-game-data chess-display-game 'active)
(not (eq (chess-game-data chess-display-game 'my-color)
(chess-pos-side-to-move position))))
- (error "It is not your turn to move")
+ (chess-error 'not-your-move)
(if (and (= chess-display-index
(chess-game-index chess-display-game))
(chess-game-over-p chess-display-game))
- (error "This game is over"))))
+ (chess-error 'game-is-over))))
(defun chess-keyboard-test-move (move-ply)
"Return the given MOVE if it matches the user's current input."
@@ -929,49 +947,63 @@ to the end or beginning."
(make-variable-buffer-local 'chess-display-last-selected)
+(chess-message-catalog 'english
+ '((cannot-mount . "You cannot move pieces on top of each other")
+ (move-not-legal . "That is not a legal move")
+ (wrong-color . "You cannot move your opponent's pieces")
+ (selected-empty . "You cannot select an empty square")
+ (piece-immobile . "That piece cannot move now")))
+
(defun chess-display-select-piece ()
"Select the piece under the cursor.
Clicking once on a piece selects it; then click on the target location."
(interactive)
(let ((coord (get-text-property (point) 'chess-coord))
- (position (chess-display-position nil)))
+ (position (chess-display-position nil))
+ message)
(when coord
- (condition-case err
- (if chess-display-last-selected
- (let ((last-sel chess-display-last-selected))
- ;; if they select the same square again, just deselect it
- (if (= (point) (car last-sel))
- (error "")
- (let ((s-piece (chess-pos-piece position (cadr last-sel)))
- (t-piece (chess-pos-piece position coord)) ply)
- (if (and (/= t-piece ? )
- (or (and (< t-piece ?a)
- (< s-piece ?a))
- (and (> t-piece ?a)
- (> s-piece ?a))))
- (error "You cannot move pieces on top of each other"))
- (unless (setq ply (chess-ply-create position
- (cadr last-sel) coord))
- (error "That is not a legal move"))
- (chess-display-move nil ply)))
- (setq chess-display-last-selected nil))
- (chess-display-assert-can-move)
- (let ((piece (chess-pos-piece position coord)))
- (cond
- ((eq piece ? )
- (error "You cannot select an empty square"))
- ((if (chess-pos-side-to-move position)
- (> piece ?a)
- (< piece ?a))
- (error "You cannot move your opponent's pieces")))
- (setq chess-display-last-selected (list (point) coord))
- (chess-display-highlight nil coord)
- (if chess-display-highlight-legal
- (chess-display-highlight-legal nil coord))))
- (error
- (setq chess-display-last-selected nil)
- (chess-display-update nil)
- (message (error-message-string err)))))))
+ (setq message
+ (catch 'message
+ (if chess-display-last-selected
+ (let ((last-sel chess-display-last-selected))
+ ;; if they select the same square again, just deselect
+ ;; it by redrawing the display and removing all
+ ;; highlights
+ (if (= (point) (car last-sel))
+ (chess-display-update nil)
+ (let ((s-piece (chess-pos-piece position
+ (cadr last-sel)))
+ (t-piece (chess-pos-piece position coord)) ply)
+ (if (and (/= t-piece ? )
+ (or (and (< t-piece ?a)
+ (< s-piece ?a))
+ (and (> t-piece ?a)
+ (> s-piece ?a))))
+ (throw 'message (chess-string 'cannot-mount)))
+ (unless (setq ply (chess-ply-create position
+ (cadr last-sel) coord))
+ (throw 'message (chess-string 'move-not-legal)))
+ (chess-display-move nil ply)))
+ (setq chess-display-last-selected nil))
+ (chess-display-assert-can-move)
+ (let ((piece (chess-pos-piece position coord)))
+ (cond
+ ((eq piece ? )
+ (throw 'message (chess-string 'selected-empty)))
+ ((if (chess-pos-side-to-move position)
+ (> piece ?a)
+ (< piece ?a))
+ (throw 'message (chess-string 'wrong-color)))
+ ((null (chess-legal-plies position :index coord))
+ (throw 'message (chess-string 'piece-immobile))))
+ (setq chess-display-last-selected (list (point) coord))
+ (chess-display-highlight nil coord)
+ (if chess-display-highlight-legal
+ (chess-display-highlight-legal nil coord))))))
+ (when message
+ (setq chess-display-last-selected nil)
+ (chess-display-update nil)
+ (error message)))))
(defun chess-display-mouse-select-piece (event)
"Select the piece the user clicked on."
diff --git a/chess-engine.el b/chess-engine.el
index f05ff56..3f2a8a0 100644
--- a/chess-engine.el
+++ b/chess-engine.el
@@ -48,6 +48,32 @@
;; User interface
;;
+(chess-message-catalog 'english
+ '((invalid-fen . "Received invalid FEN string: %s")
+ (invalid-pgn . "Received invalid PGN text")
+ (now-black . "Your opponent played the first move, you are now black")
+ (move-passed . "Your opponent has passed the move to you")
+ (want-to-play . "Do you wish to play a chess game against %s? ")
+ (want-to-play-a . "Do you wish to play a chess game against an anonymous opponent? ")
+ (opp-quit . "Your opponent has quit playing")
+ (opp-resigned . "Your opponent has resigned")
+ (opp-draw . "Your opponent offers a draw, accept? ")
+ (opp-abort . "Your opponent wants to abort this game, accept? ")
+ (opp-undo . "Your opponent wants to take back %d moves, accept? ")
+ (opp-ready . "Your opponent, %s, is now ready to play")
+ (opp-ready-a . "Your opponent is now ready to play")
+ (opp-draw-acc . "Your draw offer was accepted")
+ (opp-abort-acc . "Your offer to abort was accepted")
+ (opp-undo-acc . "Request to undo %d moves was accepted")
+ (opp-draw-dec . "Your draw offer was declined")
+ (opp-abort-dec . "Your offer to abort was declined")
+ (opp-undo-dec . "Your request to undo %d moves was decline")
+ (opp-draw-ret . "Your opponent has retracted their draw offer")
+ (opp-abort-ret . "Your opponent has retracted their offer to abort")
+ (opp-undo-ret . "Your opponent has retracted their request to undo %d moves")
+ (opp-illegal . "Your opponent states your last command was illegal")
+ (failed-start . "Failed to start chess engine process")))
+
(defmacro chess-with-current-buffer (buffer &rest body)
`(let ((buf ,buffer))
(if buf
@@ -62,12 +88,12 @@
(defsubst chess-engine-convert-fen (fen)
(or (chess-fen-to-pos fen)
(ignore
- (message "Received invalid FEN string: %s" fen))))
+ (chess-message 'invalid-fen fen))))
(defsubst chess-engine-convert-pgn (pgn)
(or (chess-pgn-to-game pgn)
(ignore
- (message "Received invalid PGN text"))))
+ (chess-message 'invalid-pgn))))
(defun chess-engine-default-handler (event &rest args)
(cond
@@ -81,7 +107,7 @@
(when (and (not chess-engine-inhibit-auto-pass)
(chess-game-data chess-engine-game 'my-color)
(= (chess-game-index chess-engine-game) 0))
- (message "Your opponent played the first move, you are now black")
+ (chess-message 'now-black)
(chess-game-run-hooks chess-engine-game 'pass)
;; if no one else flipped my-color, we'll do it
(if (chess-game-data chess-engine-game 'my-color)
@@ -91,7 +117,7 @@
((eq event 'pass)
(when (chess-game-data chess-engine-game 'active)
- (message "Your opponent has passed the move to you")
+ (chess-message 'move-passed)
t))
((eq event 'match)
@@ -99,9 +125,8 @@
(chess-engine-command nil 'busy)
(if (y-or-n-p
(if (and (car args) (> (length (car args)) 0))
- (format "Do you wish to play a chess game against %s? "
- (car args))
- (format "Do you wish to play a chess game against an anonymous opponent? ")))
+ (chess-string 'want-to-play (car args))
+ (chess-string 'want-to-play-a)))
(progn
(let ((chess-engine-handling-event t))
(chess-engine-set-position nil))
@@ -130,20 +155,20 @@
t))
((eq event 'quit)
- (message "Your opponent has quit playing")
+ (chess-message 'opp-quit)
(let ((chess-engine-handling-event t))
(chess-game-set-data chess-engine-game 'active nil))
t)
((eq event 'resign)
(let ((chess-engine-handling-event t))
- (message "Your opponent has resigned")
+ (chess-message 'opp-resigned)
(chess-game-end chess-engine-game :resign)
(chess-game-set-data chess-engine-game 'active nil)
t))
((eq event 'draw)
- (if (y-or-n-p "Your opponent offers a draw, accept? ")
+ (if (y-or-n-p (chess-string 'opp-draw))
(progn
(let ((chess-engine-handling-event t))
(chess-game-end chess-engine-game :draw)
@@ -153,7 +178,7 @@
t)
((eq event 'abort)
- (if (y-or-n-p "Your opponent wants to abort this game, accept? ")
+ (if (y-or-n-p (chess-string 'opp-abort))
(progn
(let ((chess-engine-handling-event t))
(chess-game-set-data chess-engine-game 'active nil))
@@ -162,9 +187,7 @@
t)
((eq event 'undo)
- (if (y-or-n-p
- (format "Your opponent wants to take back %d moves, accept? "
- (car args)))
+ (if (y-or-n-p (chess-string 'opp-undo (car args)))
(progn
(let ((chess-engine-handling-event t))
(chess-game-undo chess-engine-game (car args)))
@@ -177,25 +200,23 @@
(if (eq chess-engine-pending-offer 'match)
(unless (chess-game-data chess-engine-game 'active)
(if (and (car args) (> (length (car args)) 0))
- (message "Your opponent, %s, is now ready to play"
- (car args))
- (message "Your opponent is now ready to play"))
+ (chess-message 'opp-ready (car args))
+ (chess-message 'opp-ready-a))
(let ((chess-engine-handling-event t))
(chess-engine-set-position nil)))
(let ((chess-engine-handling-event t))
(cond
((eq chess-engine-pending-offer 'draw)
- (message "Your draw offer was accepted")
+ (chess-message 'opp-draw-acc)
(chess-game-end chess-engine-game :draw)
(chess-game-set-data chess-engine-game 'active nil))
((eq chess-engine-pending-offer 'abort)
- (message "Your offer to abort was accepted")
+ (chess-message 'opp-abort-acc)
(chess-game-set-data chess-engine-game 'active nil))
((eq chess-engine-pending-offer 'undo)
- (message "Request to undo %d moves was accepted"
- chess-engine-pending-arg)
+ (chess-message 'opp-undo-acc chess-engine-pending-arg)
(chess-game-undo chess-engine-game (car args))))))
(setq chess-engine-pending-offer nil
chess-engine-pending-arg nil)
@@ -205,14 +226,13 @@
(when chess-engine-pending-offer
(cond
((eq chess-engine-pending-offer 'draw)
- (message "Your draw offer was declined"))
+ (chess-message 'opp-draw-dec))
((eq chess-engine-pending-offer 'abort)
- (message "Your offer to abort was declined"))
+ (chess-message 'opp-abort-dec))
((eq chess-engine-pending-offer 'undo)
- (message "Your request to undo %d moves was decline"
- chess-engine-pending-arg)))
+ (chess-message 'opp-undo-dec chess-engine-pending-arg)))
(setq chess-engine-pending-offer nil
chess-engine-pending-arg nil)
@@ -222,21 +242,20 @@
(when chess-engine-pending-offer
(cond
((eq chess-engine-pending-offer 'draw)
- (message "Your opponent has retracted their draw offer"))
+ (chess-message 'opp-draw-ret))
((eq chess-engine-pending-offer 'abort)
- (message "Your opponent has retracted their offer to abort"))
+ (chess-message 'opp-abort-ret))
((eq chess-engine-pending-offer 'undo)
- (message "Your opponent has retracted their request to undo %d moves"
- chess-engine-pending-arg)))
+ (chess-message 'opp-undo-ret chess-engine-pending-arg)))
(setq chess-engine-pending-offer nil
chess-engine-pending-arg nil)
t))
((eq event 'illegal)
- (message "Your opponent states your last command was illegal"))))
+ (chess-message 'opp-illegal))))
(defun chess-engine-create (game module &optional response-handler
&rest handler-ctor-args)
@@ -252,7 +271,7 @@
(chess-engine-set-game* nil game t)
(when (processp proc)
(unless (memq (process-status proc) '(run open))
- (error "Failed to start chess engine process"))
+ (chess-error 'failed-engine-start))
(setq chess-engine-process proc)
(set-process-buffer proc (current-buffer))
(set-process-filter proc 'chess-engine-filter))
@@ -350,6 +369,9 @@
(chess-game-move chess-engine-game ply)
(chess-engine-command engine 'move ply)))
+(chess-message-catalog 'english
+ '((engine-not-running . "The engine you were using is no longer running")))
+
(defun chess-engine-send (engine string)
"Send the given STRING to ENGINE."
(chess-with-current-buffer engine
@@ -357,7 +379,7 @@
(if proc
(if (memq (process-status proc) '(run open))
(process-send-string proc string)
- (message "The engine you were using is no longer running")
+ (chess-message 'engine-not-running)
(chess-engine-command nil 'destroy))
(chess-engine-command nil 'send string)))))
@@ -367,7 +389,7 @@
(let ((proc chess-engine-process))
(when (and (processp proc)
(not (memq (process-status proc) '(run open))))
- (message "The engine you were using is no longer running")
+ (chess-message 'engine-not-running)
(chess-engine-command nil 'destroy))
(chess-engine-filter nil string))))
diff --git a/chess-game.el b/chess-game.el
index 25d089d..c3d281a 100644
--- a/chess-game.el
+++ b/chess-game.el
@@ -163,10 +163,14 @@ matches."
(let ((chess-game-inhibit-events t))
(chess-game-set-plies game (list ply))))))
+(chess-message-catalog 'english
+ '((undo-limit-reached . "Cannot undo further")
+ (add-to-completed . "Cannot add moves to a completed game")))
+
(defun chess-game-undo (game count)
"Undo the last COUNT plies of GAME."
(if (> count (chess-game-index game))
- (error "Cannot undo further"))
+ (chess-error 'undo-limit-reached))
(let ((chess-game-inhibit-events t))
(chess-game-set-plies game (nbutlast (chess-game-plies game) count)))
(chess-game-run-hooks game 'update))
@@ -208,7 +212,7 @@ progress (nil), if it is drawn, resigned, mate, etc."
(changes (chess-ply-changes ply))
(position (chess-ply-pos ply)))
(if (chess-ply-final-p current-ply)
- (error "Cannot add moves to a completed game"))
+ (chess-error 'add-to-completed))
(assert (equal position (chess-ply-pos current-ply)))
(chess-ply-set-changes current-ply changes)
(chess-game-add-ply game (chess-ply-create
diff --git a/chess-gnuchess.el b/chess-gnuchess.el
index 8f08b3a..225ee30 100644
--- a/chess-gnuchess.el
+++ b/chess-gnuchess.el
@@ -29,7 +29,7 @@
(cons "Illegal move:"
(function
(lambda ()
- (error "Illegal move"))))
+ (chess-error 'illegal-move))))
(cons "Board is wrong!"
(function
(lambda ()
diff --git a/chess-ics.el b/chess-ics.el
index 3df958c..2ca62a2 100644
--- a/chess-ics.el
+++ b/chess-ics.el
@@ -161,6 +161,12 @@ who is black."
(funcall chess-engine-response-handler 'match
(match-string 1)))))))
+(chess-message-catalog 'english
+ '((ics-server-prompt . "Connect to chess server: ")
+ (ics-connecting . "Connecting to Internet Chess Server '%s'...")
+ (ics-connected . "Connecting to Internet Chess Server '%s'...done")
+ (challenge-whom . "Whom would you like challenge? ")))
+
(defun chess-ics-handler (event &rest args)
(cond
((eq event 'initialize)
@@ -169,20 +175,19 @@ who is black."
(let ((server
(if (= (length chess-ics-server-list) 1)
(car chess-ics-server-list)
- (assoc (completing-read "Connect to chess server: "
+ (assoc (completing-read (chess-string 'ics-server-prompt)
chess-ics-server-list
nil t (caar chess-ics-server-list))
chess-ics-server-list))))
- (message "Connecting to Internet Chess Server '%s'..." (car server))
+ (chess-message 'ics-connecting (car server))
(let ((buf (apply 'make-comint "chess-ics"
(if (nth 3 server)
(cons (nth 4 server) (nth 5 server))
(list (cons (nth 0 server) (nth 1 server)))))))
- (message "Connecting to Internet Chess Server '%s'...done"
- (car server))
+ (chess-message 'ics-connected (car server))
(display-buffer buf)
(set-buffer buf)
@@ -210,8 +215,9 @@ who is black."
((eq event 'match)
(setq chess-engine-pending-offer 'match)
- (chess-engine-send nil (format "match %s\n"
- (read-string "Whom would you like challenge? "))))
+ (chess-engine-send
+ nil (format "match %s\n"
+ (read-string (chess-string 'challenge-whom)))))
((eq event 'move)
(unless chess-ics-ensure-ics12
diff --git a/chess-images.el b/chess-images.el
index ff90c49..d8dfba9 100644
--- a/chess-images.el
+++ b/chess-images.el
@@ -181,9 +181,12 @@ called."
(x-display-pixel-width display)
(display-pixel-width)) 20)))))
+(chess-message-catalog 'english
+ '((no-images . "Cannot find any piece images; check `chess-images-directory'")))
+
(defun chess-images-popup ()
(unless chess-images-size
- (error "Cannot find any piece images; check `chess-images-directory'"))
+ (chess-error 'no-images))
(if chess-images-separate-frame
(let* ((size (float (+ (* (or chess-images-border-width 0) 8)
(* chess-images-size 8))))
@@ -411,9 +414,13 @@ This is necessary for bizzare Emacs reasons."
(create-image file nil (string-match "\\`/\\* XPM \\*/" file)
:color-symbols syms))))
+(chess-message-catalog 'english
+ '((piece-images-loading . "Loading chess piece images...")
+ (piece-images-loaded . "Loading chess piece images...done")))
+
(defun chess-images-init-cache ()
"Initialize the display image cache."
- (message "Loading chess piece images...")
+ (chess-message 'piece-images-loading)
;; Make a vector of two vectors of 6-item vectors: each piece of
;; each color on each color square; and lastly two slots for the
;; blank squares
@@ -496,7 +503,7 @@ This is necessary for bizzare Emacs reasons."
chess-images-border-width)
nil t :color-symbols
(list (cons "background" chess-images-border-color))))))
- (message "Loading chess piece images...done"))
+ (chess-message 'piece-images-loaded))
(provide 'chess-images)
diff --git a/chess-irc.el b/chess-irc.el
index 1934037..2f284cb 100644
--- a/chess-irc.el
+++ b/chess-irc.el
@@ -25,13 +25,22 @@
:type 'string
:group 'chess-irc)
+;;; Code:
+
+(chess-message-catalog 'english
+ '((opponent-says . "Your opponent says: %s")
+ (irc-connecting . "Connecting to IRC server '%s:%d'...")
+ (irc-logging-in . "Connected, now logging in as '%s'...")
+ (irc-waiting . "Now waiting for 'name USER' via /msg, or `M-x chess-irc-engage'")
+ (irc-challenge . "IRC nick of user to challenge: ")))
+
(defvar chess-irc-regexp-alist
(append chess-network-regexp-alist
(list (cons ".+"
(function
(lambda ()
- (message "Your opponent says: %s"
- (match-string 0))))))))
+ (chess-message 'opponent-says
+ (match-string 0))))))))
(defvar chess-irc-process)
(defvar chess-irc-engine)
@@ -51,14 +60,13 @@
"This is an example of a generic transport engine."
(cond
((eq event 'initialize)
- (message "Connecting to IRC server '%s:%d'..."
- chess-irc-server chess-irc-port)
+ (chess-message 'irc-connecting chess-irc-server chess-irc-port)
(let ((engine (current-buffer)) proc)
(with-current-buffer (generate-new-buffer " *chess-irc*")
(setq chess-irc-engine engine
proc (open-network-stream "*chess-irc*" (current-buffer)
chess-irc-server chess-irc-port))
- (message "Connected, now logging in as '%s'..." chess-irc-nick)
+ (chess-message 'irc-logging-in chess-irc-nick)
(when (and proc (eq (process-status proc) 'open))
(process-send-string proc (format "USER %s 0 * :%s\n"
(user-login-name)
@@ -67,12 +75,12 @@
(set-process-filter proc 'chess-irc-filter)
(set-process-buffer proc (current-buffer))
(set-marker (process-mark proc) (point))
- (message "Now waiting for 'name USER' via /msg, or `M-x chess-irc-engage'")))
+ (chess-message 'irc-waiting)))
(setq chess-irc-process proc))
nil)
((eq event 'match)
- (setq chess-irc-opponent (read-string "IRC nick of user to challenge: "))
+ (setq chess-irc-opponent (read-string (chess-string 'irc-challenge)))
(chess-network-handler 'match chess-irc-opponent))
((eq event 'shutdown)
diff --git a/chess-message.el b/chess-message.el
new file mode 100644
index 0000000..79786ff
--- /dev/null
+++ b/chess-message.el
@@ -0,0 +1,47 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Code shared by all chess displays
+;;
+;; $Revision$
+
+(defgroup chess-message nil
+ "Support for message catalogs in chess.el."
+ :group 'chess)
+
+(defcustom chess-message-language 'english
+ "The language to use when reporting messages."
+ :type 'symbol
+ :group 'chess-message)
+
+;;; Code:
+
+(defvar chess-message-catalog nil)
+
+(defun chess-message-catalog (catalog definitions)
+ (let ((entry (assq catalog chess-message-catalog)))
+ (if entry
+ (dolist (def definitions)
+ (let ((str (assq (car def) (cdr entry))))
+ (if str
+ (setcdr str (cdr def))
+ (push def (cdr entry)))))
+ (push (cons catalog definitions) chess-message-catalog))))
+
+(defun chess-string (key &rest arguments)
+ (let* ((entry (assq chess-message-language chess-message-catalog))
+ (msg (and entry (cdr (assq key (cdr entry))))))
+ (if msg
+ (apply 'format msg arguments)
+ "message not found")))
+
+(defsubst chess-message (key &rest arguments)
+ (message (apply 'chess-string key arguments)))
+
+(defsubst chess-error (key &rest arguments)
+ (error (apply 'chess-string key arguments)))
+
+(put 'chess-message-catalog 'lisp-indent-function 1)
+
+(provide 'chess-message)
+
+;;; chess-message.el ends here
diff --git a/chess-network.el b/chess-network.el
index b4456d8..f44d4b0 100644
--- a/chess-network.el
+++ b/chess-network.el
@@ -69,13 +69,18 @@
(lambda ()
(funcall chess-engine-response-handler 'retract))))))
+(chess-message-catalog 'english
+ '((network-starting . "Starting network client/server...")
+ (network-waiting . "Now waiting for your opponent to connect...")
+ (network-connected ."You have connected; pass now or make your move.")))
+
(defun chess-network-handler (event &rest args)
"Initialize the network chess engine."
(cond
((eq event 'initialize)
(let ((which (read-char "Are you the c)lient or s)erver? "))
proc)
- (message "Starting network client/server...")
+ (chess-message 'network-starting)
(setq proc (if (eq which ?s)
(start-process "*chess-network*"
(current-buffer) "/usr/bin/nc"
@@ -84,9 +89,9 @@
(read-string "Host: ")
(read-string "Port: "))))
(if (eq which ?s)
- (message "Now waiting for your opponent to connect...")
+ (chess-message 'network-waiting)
(chess-network-handler 'match)
- (message "You have connected; pass now or make your move."))
+ (chess-message 'network-connected))
proc))
((eq event 'shutdown)
diff --git a/chess-pgn.el b/chess-pgn.el
index 9d0ebf5..67ec901 100644
--- a/chess-pgn.el
+++ b/chess-pgn.el
@@ -11,6 +11,10 @@
(defvar chess-pgn-fill-column 60)
+(chess-message-catalog 'english
+ '((pgn-read-error . "Error reading move: %s")
+ (pgn-parse-error . "Error parsing PGN syntax")))
+
(defun chess-pgn-read-plies (game position &optional top-level)
(let ((plies (list t)) prevpos done)
(while (not (or done (eobp)))
@@ -23,7 +27,7 @@
(let* ((move (match-string 0))
(ply (chess-algebraic-to-ply position (match-string 0))))
(unless ply
- (error "Error reading move: %s" move))
+ (chess-error 'pgn-read-error move))
(setq position (chess-ply-next-pos ply))
(nconc plies (list ply))))
((and top-level
@@ -49,7 +53,7 @@
(looking-at ")"))
(forward-char)
(setq done t))
- (t (error "Error parsing PGN syntax")))
+ (t (chess-error 'pgn-parse-error)))
(skip-chars-forward " \t\n"))
(cdr plies)))
diff --git a/chess-ply.el b/chess-ply.el
index 7e44a04..22e22d7 100644
--- a/chess-ply.el
+++ b/chess-ply.el
@@ -44,7 +44,6 @@
;;; Code:
-(require 'cl)
(require 'chess-pos)
(defgroup chess-ply nil
@@ -158,19 +157,25 @@ maneuver."
(chess-ply-create-castle position long)))
(setcdr ply new-changes))))
- ;; is this a pawn move to the ultimate rank? if so, and we
- ;; haven't already been told, ask for the piece to promote it to
- (if (and (= piece (if color ?P ?p))
- (not (memq :promote changes))
- (= (if color 0 7) (chess-index-rank (cadr changes))))
- (let ((new-piece (completing-read
- "Promote pawn to queen/rook/knight/bishop? "
- chess-piece-name-table nil t "queen")))
- (setq new-piece
- (cdr (assoc new-piece chess-piece-name-table)))
- (if color
- (setq new-piece (upcase new-piece)))
- (nconc changes (list :promote new-piece))))
+ (when (= piece (if color ?P ?p))
+ ;; is this a pawn move to the ultimate rank? if so, and we
+ ;; haven't already been told, ask for the piece to promote
+ ;; it to
+ (if (and (not (memq :promote changes))
+ (= (if color 0 7) (chess-index-rank (cadr changes))))
+ (let ((new-piece (completing-read
+ "Promote pawn to queen/rook/knight/bishop? "
+ chess-piece-name-table nil t "queen")))
+ (setq new-piece
+ (cdr (assoc new-piece chess-piece-name-table)))
+ (if color
+ (setq new-piece (upcase new-piece)))
+ (nconc changes (list :promote new-piece))))
+
+ ;; is this an en-passant capture?
+ (if (= (or (chess-pos-en-passant position) 100)
+ (or (chess-incr-index (cadr changes) (if color 1 -1) 0) 200))
+ (nconc changes (list :en-passant))))
(unless (or (memq :check changes)
(memq :checkmate changes)
@@ -258,9 +263,10 @@ criteria."
(let* ((piece (cadr (memq :piece keywords)))
(color (if piece (< piece ?a)
(chess-pos-side-to-move position)))
- (test-piece (if piece (upcase piece)
- (chess-pos-piece position
- (cadr (memq :index keywords)))))
+ (test-piece
+ (upcase (or piece
+ (chess-pos-piece position
+ (cadr (memq :index keywords))))))
pos plies file)
;; since we're looking for moves of a particular piece, do a
;; more focused search
@@ -289,12 +295,20 @@ criteria."
(if (and (= (if color 6 1) (chess-index-rank candidate))
(chess-pos-piece-p position 2ahead ? ))
(chess-ply--add (if color -2 2) 0)))
- (if (and (setq pos (chess-incr-index candidate bias -1))
- (chess-pos-piece-p position pos (not color)))
- (chess-ply--add nil nil pos))
- (if (and (setq pos (chess-incr-index candidate bias 1))
- (chess-pos-piece-p position pos (not color)))
- (chess-ply--add nil nil pos))))
+ (when (setq pos (chess-incr-index candidate bias -1))
+ (if (chess-pos-piece-p position pos (not color))
+ (chess-ply--add nil nil pos))
+ ;; check for en passant capture toward queenside
+ (if (= (or (chess-pos-en-passant position) 100)
+ (or (chess-incr-index pos (if color 1 -1) 0) 200))
+ (chess-ply--add nil nil pos)))
+ (when (setq pos (chess-incr-index candidate bias 1))
+ (if (chess-pos-piece-p position pos (not color))
+ (chess-ply--add nil nil pos))
+ ;; check for en passant capture toward kingside
+ (if (= (or (chess-pos-en-passant position) 100)
+ (or (chess-incr-index pos (if color 1 -1) 0) 200))
+ (chess-ply--add nil nil pos)))))
;; the rook, bishop and queen are the easiest; just look along
;; rank and file and/or diagonal for the nearest pieces!
@@ -302,7 +316,7 @@ criteria."
(dolist (dir (cond
((= test-piece ?R)
'( (-1 0)
- (0 -1) (0 1)
+ (0 -1) (0 1)
(1 0)))
((= test-piece ?B)
'((-1 -1) (-1 1)
@@ -354,8 +368,9 @@ criteria."
(chess-pos-piece-p position pos (not color))))
(chess-ply--add nil nil pos))))
- (t (error "Unrecognized piece identifier"))))
- plies))))
+ (t (chess-error 'piece-unrecognized))))
+
+ (delq nil plies)))))
(provide 'chess-ply)
diff --git a/chess-pos.el b/chess-pos.el
index 4390072..fb8516c 100644
--- a/chess-pos.el
+++ b/chess-pos.el
@@ -71,6 +71,9 @@
;;; Code:
+(require 'cl)
+(require 'chess-message)
+
(defgroup chess-pos nil
"Routines for manipulating chess positions."
:group 'chess)
@@ -250,6 +253,9 @@ color will do."
chess-pos-piece-values)))))
value))
+(chess-message-catalog 'english
+ '((move-from-blank . "Attempted piece move from blank square %s")))
+
(defun chess-pos-move (position &rest changes)
"Move a piece on the POSITION directly, using the indices FROM and TO.
This function does not check any rules, it only makes sure you are not
@@ -263,8 +269,7 @@ trying to move a blank square."
(to (cadr ch))
(piece (chess-pos-piece position from)))
(if (= piece ? )
- (error "Attempted piece move from blank square %s"
- (chess-index-to-coord from)))
+ (chess-error 'move-from-blank (chess-index-to-coord from)))
(chess-pos-set-piece position from ? )
(chess-pos-set-piece position to piece))
(setq ch (cddr ch)))))
@@ -272,6 +277,12 @@ trying to move a blank square."
;; now fix up the resulting position
(let ((color (chess-pos-side-to-move position)))
+ ;; if the move was en-passant, remove the captured pawn
+ (if (memq :en-passant changes)
+ (chess-pos-set-piece position (chess-incr-index (cadr changes)
+ (if color 1 -1) 0)
+ ? ))
+
;; once a piece is moved, en passant is no longer available
(chess-pos-set-en-passant position nil)
@@ -321,6 +332,9 @@ trying to move a blank square."
;; return the final position
position))
+(chess-message-catalog 'english
+ '((piece-unrecognized . "Unrecognized piece identifier")))
+
(defun chess-search-position (position target piece)
"Look on POSITION from TARGET for a PIECE that can move there.
This routine looks along legal paths of movement for PIECE. It
@@ -362,11 +376,17 @@ indices which indicate where a piece may have moved from."
(if (if (= p ? )
;; check for en passant
(and (= (chess-index-rank target) (if color 2 5))
- (setq pos (chess-incr-index target bias 0))
- (chess-pos-piece-p position pos (if color ?p ?P))
;; make this fail if no en-passant is possible
- (= (or (chess-pos-en-passant position) 100) target)
- (setq candidates (list pos)))
+ (= (or (chess-pos-en-passant position) 100)
+ (chess-incr-index target (if color 1 -1) 0))
+ (or (and (setq pos (chess-incr-index target
+ (if color 1 -1) -1))
+ (chess-pos-piece-p position pos
+ (if color ?P ?p)))
+ (and (setq pos (chess-incr-index target
+ (if color 1 -1) 1))
+ (chess-pos-piece-p position pos
+ (if color ?P ?p)))))
(if color (> p ?a) (< p ?a)))
(let ((cands (list t)))
(setq pos (chess-incr-index target (- bias) -1))
@@ -470,7 +490,7 @@ indices which indicate where a piece may have moved from."
(nconc candidates (list pos))))
(setq candidates (cdr candidates)))
- (t (error "Unrecognized piece identifier")))
+ (t (chess-error 'piece-unrecognized)))
;; prune from the discovered candidates list any moves which would
;; leave the king in check; castling through check has already
diff --git a/chess-var.el b/chess-var.el
index c33b243..f5c789a 100644
--- a/chess-var.el
+++ b/chess-var.el
@@ -59,9 +59,8 @@ progress (nil), if it is drawn, resigned, mate, etc."
(changes (chess-ply-changes ply))
(position (chess-ply-pos ply)))
(if (chess-ply-final-p current-ply)
- (error "Cannot add moves to a completed game"))
- (unless (equal position (chess-ply-pos current-ply))
- (error "Positions do not match"))
+ (chess-error 'add-to-completed))
+ (assert (equal position (chess-ply-pos current-ply)))
(chess-ply-set-changes current-ply changes)
(chess-var-add-ply var (chess-ply-create
(chess-ply-next-pos current-ply)))))
diff --git a/chess.el b/chess.el
index 26ec076..b79bab5 100644
--- a/chess.el
+++ b/chess.el
@@ -111,6 +111,9 @@ minibuffer, which works well for Emacspeak users."
:type 'string
:group 'chess)
+(chess-message-catalog 'english
+ '((no-images-fallback . "Could not find suitable chess images; using ics1 display")))
+
;;;###autoload
(defun chess (&optional engine disable-popup engine-response-handler
&rest engine-ctor-args)
@@ -135,7 +138,7 @@ minibuffer, which works well for Emacspeak users."
(when (and (eq chess-default-display 'chess-images)
(with-current-buffer display
(null chess-images-size)))
- (message "Could not find suitable chess images; using ics1 display")
+ (chess-message 'no-images-fallback)
(chess-display-destroy display)
(require 'chess-ics1)
(setq display (chess-display-create game 'chess-ics1 my-color)))
@@ -155,7 +158,8 @@ minibuffer, which works well for Emacspeak users."
;; let them know we're ready to begin
(chess-engine-command engine 'ready))
- (when chess-announce-moves
+ (when (and (not (eq engine-module 'chess-none))
+ chess-announce-moves)
(if (and (not (eq chess-announce-moves t))
(symbolp chess-announce-moves))
(let ((name (symbol-name chess-announce-moves)))