summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chess-engine.el69
-rw-r--r--chess-game.el14
-rw-r--r--chess-ics.el7
-rw-r--r--chess-link.el2
-rw-r--r--chess-network.el71
5 files changed, 150 insertions, 13 deletions
diff --git a/chess-engine.el b/chess-engine.el
index 2551bf7..b94ca98 100644
--- a/chess-engine.el
+++ b/chess-engine.el
@@ -113,11 +113,11 @@
(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-engine-command nil 'accept)
+ (chess-engine-command nil 'accept-connect)
(chess-engine-send nil 'decline)))
t)
- ((eq event 'accept)
+ ((eq event 'accept-connect)
(unless (and game (chess-game-data game 'active))
(if (and (car args) (> (length (car args)) 0))
(message "Your opponent, %s, is now ready to play" (car args))
@@ -163,8 +163,65 @@
((eq event 'abort)
(when game
- (message "Your opponent has aborted the game")
+ (if (y-or-n-p "Your opponent wants to abort this game, accept? ")
+ (progn
+ (chess-game-set-data game 'active nil)
+ (chess-engine-command nil 'accept-abort))
+ (chess-engine-command nil 'decline-abort))
+ t))
+
+ ((eq event 'accept-abort)
+ (when game
+ (message "Your offer to abort was accepted")
(chess-game-set-data game 'active nil)
+ t))
+
+ ((eq event 'decline-abort)
+ (when game
+ (message "Your offer to abort was declined")
+ t))
+
+ ((eq event 'undo)
+ (when game
+ (if (y-or-n-p (format "Your opponent wants to take back %d moves, accept? "
+ (car args)))
+ (progn
+ (chess-game-undo game (car args))
+ (chess-engine-command nil 'accept-undo))
+ (chess-engine-command nil 'decline-undo))
+ t))
+
+ ((eq event 'accept-undo)
+ (when game
+ (message "Undo of %d moves accepted" (car args))
+ (chess-game-undo game (car args))
+ t))
+
+ ((eq event 'decline-undo)
+ (when game
+ (message "Undo of %d moves declined" (car args))
+ t))
+
+ ((eq event 'draw)
+ (when game
+ (if (y-or-n-p "Your opponent offers a draw, accept? ")
+ (progn
+ (chess-game-draw game (car args))
+ (chess-engine-command nil 'accept-draw)
+ (chess-game-set-data game 'active nil))
+ (chess-engine-command nil 'decline-draw))
+ t))
+
+ ((eq event 'accept-draw)
+ (when game
+ (message "Your draw offer was accepted")
+ (chess-game-draw game (car args))
+ (chess-game-set-data game 'active nil)
+ t))
+
+ ((eq event 'decline-draw)
+ (when game
+ (message "Your draw offer was declined")
t)))))
(defun chess-engine-create (module &optional response-handler &rest args)
@@ -189,7 +246,7 @@
(defun chess-engine-on-kill ()
"Function called when the buffer is killed."
- (chess-engine-command (current-buffer) 'shutdown))
+ (chess-engine-command nil 'shutdown))
(defun chess-engine-destroy (engine)
(let ((buf (or engine (current-buffer))))
@@ -321,6 +378,10 @@ function in all cases; this is merely a bandwidth-saver."
(chess-with-current-buffer engine
(chess-engine-command engine 'abort)))
+(defun chess-engine-undo (engine count)
+ (chess-with-current-buffer engine
+ (chess-engine-command engine 'undo count)))
+
(defun chess-engine-send (engine string)
"Send the given STRING to ENGINE."
(chess-with-current-buffer engine
diff --git a/chess-game.el b/chess-game.el
index 35e41ce..3b55556 100644
--- a/chess-game.el
+++ b/chess-game.el
@@ -165,6 +165,14 @@ matches."
(nconc plies (list ply))
(chess-game-set-plies game (list ply)))))
+(defun chess-game-undo (game count)
+ "Undo the last COUNT plies of GAME."
+ (if (> count (chess-game-index game))
+ (error "Cannot undo %d plies from a game with only %d plies"
+ count (chess-game-index game))
+ (chess-game-set-plies game (nbutlast (chess-game-plies game) count))
+ (chess-game-run-hooks game 'undo count)))
+
(defsubst chess-game-over-p (game)
"Return the position related to GAME's INDEX position."
@@ -205,7 +213,7 @@ progress (nil), if it is drawn, resigned, mate, etc."
(error "Cannot add moves to a completed game"))
(unless (equal position (chess-ply-pos current-ply))
(error "Positions do not match"))
- (unless (or (chess-ply-has-keyword ply :resign)
+ (unless (or (chess-ply-has-keyword ply :resign :draw)
(chess-search-position
position (cadr (chess-ply-changes ply))
(chess-pos-piece position (car (chess-ply-changes ply)))))
@@ -232,6 +240,10 @@ progress (nil), if it is drawn, resigned, mate, etc."
"Resign the current game."
(chess-game-move game (list (chess-game-pos game) :resign)))
+(defsubst chess-game-draw (game)
+ "Draw the current game."
+ (chess-game-move game (list (chess-game-pos game) :draw)))
+
(provide 'chess-game)
;;; chess-game.el ends here
diff --git a/chess-ics.el b/chess-ics.el
index cd47b44..42bd3ef 100644
--- a/chess-ics.el
+++ b/chess-ics.el
@@ -189,10 +189,10 @@ who is black."
(chess-engine-send nil (concat (chess-ply-to-algebraic (car args))
"\n")))
- ((eq event 'accept)
+ ((memq event '(accept-connect accept-undo accept-draw accept-abort))
(chess-engine-send nil "accept\n"))
- ((eq event 'decline)
+ ((memq event '(decline-connect decline-undo decline-draw decline-abort))
(chess-engine-send nil "decline\n"))
((eq event 'resign)
@@ -201,6 +201,9 @@ who is black."
((eq event 'abort)
(chess-engine-send nil "abort\n"))
+ ((eq event 'undo)
+ (chess-engine-send nil (format "takeback %d\n" (car args))))
+
((eq event 'send)
(comint-send-string (get-buffer-process (current-buffer)) (car args)))))
diff --git a/chess-link.el b/chess-link.el
index a65a583..321686d 100644
--- a/chess-link.el
+++ b/chess-link.el
@@ -18,7 +18,7 @@
return-value)
(cond
((eq event 'connect)
- (chess-engine-command nil 'accept)
+ (chess-engine-command nil 'accept-connect)
t)
(t
diff --git a/chess-network.el b/chess-network.el
index 32dc70b..3468abd 100644
--- a/chess-network.el
+++ b/chess-network.el
@@ -20,10 +20,10 @@
(lambda ()
(funcall chess-engine-response-handler 'connect
(match-string 2)))))
- (cons "accept\\(\\s-+\\(.+\\)\\)?$"
+ (cons "accept match\\(\\s-+\\(.+\\)\\)?$"
(function
(lambda ()
- (funcall chess-engine-response-handler 'accept
+ (funcall chess-engine-response-handler 'accept-connect
(match-string 2)))))
(cons "fen\\s-+\\(.+\\)"
(function
@@ -47,10 +47,44 @@
(function
(lambda ()
(funcall chess-engine-response-handler 'resign))))
+ (cons "draw$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'draw))))
+ (cons "accept draw$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'accept-draw))))
+ (cons "decline draw$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'decline-draw))))
(cons "abort$"
(function
(lambda ()
- (funcall chess-engine-response-handler 'abort))))))
+ (funcall chess-engine-response-handler 'abort))))
+ (cons "accept abort$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'accept-abort))))
+ (cons "decline abort$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'decline-abort))))
+ (cons "takeback\\s-+\\([0-9]+\\)$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'undo
+ (string-to-int (match-string 1))))))
+ (cons "accept takeback\\s-+\\([0-9]+\\)$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'accept-undo
+ (string-to-int (match-string 1))))))
+ (cons "decline takeback$"
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'decline-undo))))))
(defun chess-network-handler (event &rest args)
"Initialize the network chess engine."
@@ -89,8 +123,11 @@
((eq event 'busy)
(chess-engine-send nil "playing\n"))
- ((eq event 'accept)
- (chess-engine-send nil (format "accept %s\n" chess-full-name)))
+ ((eq event 'connect)
+ (chess-engine-send nil (format "chess match %s\n" chess-full-name)))
+
+ ((eq event 'accept-connect)
+ (chess-engine-send nil (format "accept match %s\n" chess-full-name)))
((eq event 'decline)
(chess-engine-send nil "decline\n"))
@@ -98,9 +135,33 @@
((eq event 'resign)
(chess-engine-send nil "resign\n"))
+ ((eq event 'draw)
+ (chess-engine-send nil "draw\n"))
+
+ ((eq event 'accept-draw)
+ (chess-engine-send nil "accept draw\n"))
+
+ ((eq event 'decline-draw)
+ (chess-engine-send nil "decline draw\n"))
+
((eq event 'abort)
(chess-engine-send nil "abort\n"))
+ ((eq event 'accept-abort)
+ (chess-engine-send nil "accept abort\n"))
+
+ ((eq event 'decline-abort)
+ (chess-engine-send nil "decline abort\n"))
+
+ ((eq event 'undo)
+ (chess-engine-send nil (format "takeback %d\n" (car args))))
+
+ ((eq event 'accept-undo)
+ (chess-engine-send nil (format "accept takeback %d\n" (car args))))
+
+ ((eq event 'decline-undo)
+ (chess-engine-send nil "decline takeback\n"))
+
((eq event 'move)
(chess-engine-send nil (concat (chess-ply-to-algebraic (car args))
"\n")))))