summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chess-announce.el45
-rw-r--r--chess-display.el6
-rw-r--r--chess-engine.el35
-rw-r--r--chess-ics.el10
-rw-r--r--chess-network.el15
-rw-r--r--chess-transport.el3
-rw-r--r--chess.el20
7 files changed, 87 insertions, 47 deletions
diff --git a/chess-announce.el b/chess-announce.el
index 873531c..ba3e052 100644
--- a/chess-announce.el
+++ b/chess-announce.el
@@ -14,33 +14,37 @@
(?r . "rook")
(?p . "pawn")))
-(defvar chess-announce-function 'chess-announce-festival
- "The function to call for announcing moves audially.
-It is passed the string of English text to announce.")
+(autoload 'festival-start-process "festival")
+(autoload 'festival-kill-process "festival")
-(defun chess-announce-for-game (game perspective)
- "Announce moves in GAME on behalf of PERSPECTIVE.
-This means that if PERSPECTIVE is t (for white), only black's moves
-will be announced."
- (chess-game-add-hook game 'chess-announce-event-handler perspective))
+(defvar chess-announce-functions
+ (if (executable-find "festival")
+ (if (fboundp 'festival-say-string)
+ '(festival-start-process festival-say-string festival-kill-process)
+ '(ignore chess-announce-festival ignore))
+ '(ignore message ignore))
+ "These three functions are used to for announcing moves.
+The first is called one start of the announcer. The second is called
+with the string to announce each time. The third is called to
+shutdown the announcer process, if necessary.")
-(defun chess-announce-change-perspective (game perspective)
- "Change the announce perspective in GAME to PERSPECTIVE."
- (let ((cell (assq 'chess-announce-event-handler (chess-game-hooks game))))
- (if cell
- (setcdr cell perspective))))
+(defun chess-announce-for-game (game)
+ "Announce the opponent's moves in GAME."
+ (chess-game-add-hook game 'chess-announce-event-handler)
+ (funcall (nth 0 chess-announce-functions)))
-(defun chess-announce-event-handler (game perspective event &rest args)
+(defun chess-announce-event-handler (game ignore event &rest args)
"This display module presents a standard chessboard.
See `chess-display-type' for the different kinds of displays."
(cond
- ((eq event 'pass)
- (chess-announce-change-perspective game (not perspective)))
+ ((eq event 'shutdown)
+ (funcall (nth 2 chess-announce-functions)))
((memq event '(move game-over))
(let* ((ply (chess-game-ply game (1- (chess-game-index game))))
(pos (chess-ply-pos ply)))
- (unless (eq perspective (chess-pos-side-to-move pos))
+ (unless (eq (chess-game-get-data game 'my-color)
+ (chess-pos-side-to-move pos))
(let* ((changes (chess-ply-changes ply))
(source (car changes))
(target (cadr changes))
@@ -69,10 +73,13 @@ See `chess-display-type' for the different kinds of displays."
(if (memq :stalemate changes)
(setq text (concat text ", stalemate")))
- (funcall chess-announce-function text)))))))
+ (funcall (nth 1 chess-announce-functions) text)))))))
(defun chess-announce-festival (text)
- "Announce the given text using festival."
+ "Announce the given text using festival.
+This is less efficient than festival.el, which should be installed if
+possible. Debian installs it automatically when you apt-get install
+festival."
(let ((proc (start-process "announce" nil "/usr/bin/festival" "--tts")))
(when (and proc (eq (process-status proc) 'run))
(process-send-string proc (concat text "\n"))
diff --git a/chess-display.el b/chess-display.el
index 0bcd022..c7cd835 100644
--- a/chess-display.el
+++ b/chess-display.el
@@ -290,10 +290,12 @@ See `chess-display-type' for the different kinds of displays."
((eq event 'pass)
(let ((my-color (if chess-display-game
- (chess-game-get-data chess-display-game 'my-color)
+ (chess-game-get-data chess-display-game
+ 'my-color)
(chess-display-perspective nil))))
(if chess-display-game
- (chess-game-set-data chess-display-game 'my-color (not my-color)))
+ (chess-game-set-data chess-display-game 'my-color
+ (not my-color)))
(chess-display-set-perspective nil (not my-color))))
((memq event '(move game-over resign))
diff --git a/chess-engine.el b/chess-engine.el
index 396b6c4..219bf34 100644
--- a/chess-engine.el
+++ b/chess-engine.el
@@ -76,13 +76,35 @@
;; if no one else flipped my-color, we'll do it
(if (chess-game-get-data game 'my-color)
(chess-game-set-data game 'my-color nil))))
- (chess-engine-do-move ply))))
+ (chess-engine-do-move ply)))
+ t)
((eq event 'pass)
- (message "Your opponent has passed the first move to you"))
+ (if (and (chess-game-get-data (chess-engine-game nil) 'active)
+ (= (chess-game-index game) 0))
+ (message "Your opponent has passed the first move to you"))
+ t)
((eq event 'connect)
- (message "Your opponent, %s, is now ready to play" (car args)))
+ (unless (chess-game-get-data (chess-engine-game nil) 'active)
+ (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? ")))
+ (progn
+ (chess-game-set-data (chess-engine-game nil) 'active t)
+ (chess-engine-send nil (format "accept %s" (user-full-name))))
+ (chess-engine-send nil "decline"))
+ t))
+
+ ((eq event 'accept)
+ (unless (chess-game-get-data (chess-engine-game nil) '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-game-set-data (chess-engine-game nil) 'active t)
+ t))
((eq event 'quit)
(message "Your opponent has quit playing"))
@@ -245,10 +267,9 @@
(while triggers
;; this could be accelerated by joining
;; together the regexps
- (if (looking-at (caar triggers))
- (progn
- (funcall (cdar triggers))
- (setq triggers nil))
+ (if (and (looking-at (caar triggers))
+ (funcall (cdar triggers)))
+ (setq triggers nil)
(setq triggers (cdr triggers)))))
(forward-line)))
(setq chess-engine-last-pos (point)
diff --git a/chess-ics.el b/chess-ics.el
index a6226ec..cadc955 100644
--- a/chess-ics.el
+++ b/chess-ics.el
@@ -118,7 +118,8 @@ who is black."
(list (car info)))
(unless (string= (cadr info) ics-handle)
(chess-game-run-hooks (chess-engine-game nil) 'pass)))
- (delete-region begin end)))
+ (delete-region begin end)
+ t))
(defvar chess-ics-regexp-alist
(list (cons "\\(<12> \\(.+\\)\\)" 'chess-ics-handle-move)
@@ -203,10 +204,9 @@ who is black."
(while triggers
;; this could be accelerated by joining together the
;; regexps
- (if (looking-at (concat "[^\n\r]*" (caar triggers)))
- (progn
- (funcall (cdar triggers))
- (setq triggers nil))
+ (if (and (looking-at (concat "[^\n\r]*" (caar triggers)))
+ (funcall (cdar triggers)))
+ (setq triggers nil)
(setq triggers (cdr triggers)))))
(forward-line))
(setq chess-engine-last-pos (point))))
diff --git a/chess-network.el b/chess-network.el
index 21005eb..39d9d33 100644
--- a/chess-network.el
+++ b/chess-network.el
@@ -14,20 +14,25 @@
(lambda ()
(funcall chess-engine-response-handler 'move
(match-string 0)))))
- (cons "pass$"
+ (cons "chess match\\(\\s-+\\(.+\\)\\)?$"
(function
(lambda ()
- (funcall chess-engine-response-handler 'pass))))
- (cons "name\\s-+\\(.+\\)"
+ (funcall chess-engine-response-handler 'connect
+ (match-string 2)))))
+ (cons "accept\\(\\s-+\\(.+\\)\\)?$"
(function
(lambda ()
- (funcall chess-engine-response-handler 'connect
- (match-string 1)))))
+ (funcall chess-engine-response-handler 'accept
+ (match-string 2)))))
(cons "fen\\s-+\\(.+\\)"
(function
(lambda ()
(funcall chess-engine-response-handler 'setup
(match-string 1)))))
+ (cons "pass$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'pass))))
(cons "quit$"
(function
(lambda ()
diff --git a/chess-transport.el b/chess-transport.el
index 1262817..dcec224 100644
--- a/chess-transport.el
+++ b/chess-transport.el
@@ -21,6 +21,9 @@
;; kind of transport might collide. For example:
;;
;; (set (make-local-variable 'chess-transport-data) (car args))
+ ;;
+ ;; NOTE: Be sure not to return a process, or else chess-engine
+ ;; will do all the transport work!
)
((eq event 'send)
diff --git a/chess.el b/chess.el
index 76f26be..ed80fea 100644
--- a/chess.el
+++ b/chess.el
@@ -98,10 +98,11 @@ a0 243
"Default engine to be used when starting a chess session."
:type 'sexp
:group 'chess)
-(defcustom chess-announce-moves (and (executable-find "festival") t)
- "If non-nil, announce your opponent's moves verbally.
-This requires the utility 'festival' to be installed. If it is
-installed, this variable will default to true."
+(defcustom chess-announce-moves t
+(defcustom chess-announce-moves t
+This happens verbally if 'festival' is installed, otherwise it just
+prints a message in your minibuffer, which works well for Emacspeak
+users."
minibuffer, which works well for Emacspeak users."
:type 'boolean
:group 'chess)
@@ -110,25 +111,26 @@ minibuffer, which works well for Emacspeak users."
"Start a game of chess."
(interactive "P")
(let ((game (chess-game-create)) ; start out as white always
+ (my-color t)
display engine)
(game (chess-game-create)))
- (chess-game-set-data game 'my-color t)
+
(require chess-default-display)
(chess-display-set-game
- (chess-display-create chess-default-display t) game)
+ (chess-display-create chess-default-display my-color) game)
(chess-display-set-main display)
(let ((engine-module
(if arg
(intern (or (read-string "Engine module to play against: ")
"chess-none"))
chess-default-engine)))
- (when (and engine-module
- (require engine-module nil t))
+ (let ((engine-module (or engine chess-default-engine)))
(chess-engine-set-game (chess-engine-create engine-module) game)
+ (chess-engine-command engine 'ready))
(when chess-announce-moves
(require 'chess-announce)
- (chess-announce-for-game game t))))))
+ (chess-announce-for-game game))))))
(cons display engine)))
;;;###autoload