summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Lang <mlang@delysid.org>2014-03-24 14:44:39 +0100
committerMario Lang <mlang@delysid.org>2014-03-24 14:44:39 +0100
commit6b148f8d5cb39ee047db85fb5788abe8c9cd7f2b (patch)
tree6fa611d5b4d8c84f10aeaab31f9d86af87bcc103
parent5130570807b16e7fceccaefb2d6b34502e31c1bb (diff)
Parse UCI long algebraic moves correctly.
-rw-r--r--chess-fruit.el13
-rw-r--r--chess-glaurung.el13
-rw-r--r--chess-stockfish.el23
-rw-r--r--chess-uci.el44
4 files changed, 59 insertions, 34 deletions
diff --git a/chess-fruit.el b/chess-fruit.el
index 1067470..6c35445 100644
--- a/chess-fruit.el
+++ b/chess-fruit.el
@@ -34,17 +34,8 @@
:type 'file
:group 'chess-fruit)
-(defvar chess-fruit-regexp-alist
- (list
- (cons (concat "^bestmove\\s-+\\(" chess-algebraic-regexp "\\)")
- (function
- (lambda ()
- (funcall chess-engine-response-handler 'move
- (chess-engine-convert-algebraic (match-string 1) t)))))
- (cons "^id\\s-+name\\s-+\\(.+\\)$"
- (function
- (lambda ()
- (setq-local chess-engine-opponent-name (match-string 1)))))))
+(defvar chess-fruit-regexp-alist chess-uci-regexp-alist
+ "Patterns used to match engine output.")
(defun chess-fruit-handler (game event &rest args)
(unless chess-engine-handling-event
diff --git a/chess-glaurung.el b/chess-glaurung.el
index 5ce6042..f3ff03e 100644
--- a/chess-glaurung.el
+++ b/chess-glaurung.el
@@ -34,17 +34,8 @@
:type 'file
:group 'chess-glaurung)
-(defvar chess-glaurung-regexp-alist
- (list
- (cons (concat "^bestmove\\s-+\\(" chess-algebraic-regexp "\\)")
- (function
- (lambda ()
- (funcall chess-engine-response-handler 'move
- (chess-engine-convert-algebraic (match-string 1) t)))))
- (cons "^id\\s-+name\\s-+\\(.+\\)$"
- (function
- (lambda ()
- (setq-local chess-engine-opponent-name (match-string 1)))))))
+(defvar chess-glaurung-regexp-alist chess-uci-regexp-alist
+ "Patterns used to match engine output.")
(defun chess-glaurung-handler (game event &rest args)
(unless chess-engine-handling-event
diff --git a/chess-stockfish.el b/chess-stockfish.el
index f01c75b..21dc6a6 100644
--- a/chess-stockfish.el
+++ b/chess-stockfish.el
@@ -35,17 +35,18 @@
:group 'chess-stockfish)
(defvar chess-stockfish-regexp-alist
- (list
- (cons (concat "^bestmove\\s-+\\(" chess-algebraic-regexp "\\)")
- (function
- (lambda ()
- (message "move")
- (funcall chess-engine-response-handler 'move
- (chess-engine-convert-algebraic (match-string 1) t)))))
- (cons "^id\\s-+name\\s-+\\(.+\\)$"
- (function
- (lambda ()
- (setq-local chess-engine-opponent-name (match-string 1)))))))
+ (append
+ chess-uci-regexp-alist
+ (list
+ (cons (concat "^info\\s-+.*nps\\s-+\\([0-9]+\\).*pv\\s-+\\("
+ chess-uci-long-algebraic-regexp
+ "\\(\\s-+" chess-uci-long-algebraic-regexp "\\)+\\)")
+ (function
+ (lambda ()
+ (setq-local chess-stockfish-nps (string-to-number (match-string 1)))
+ (setq-local chess-stockfish-pv
+ (split-string (match-string 2) " ")))))))
+ "Patterns used to match stockfish output.")
(defun chess-stockfish-handler (game event &rest args)
(unless chess-engine-handling-event
diff --git a/chess-uci.el b/chess-uci.el
index befdaaa..faf77ef 100644
--- a/chess-uci.el
+++ b/chess-uci.el
@@ -24,9 +24,51 @@
(require 'chess-common)
-(defvar chess-uci-move-regexp "[a-h][1-8][a-h][1-8][nbrq]?"
+(defvar chess-uci-long-algebraic-regexp "\\([a-h][1-8]\\)\\([a-h][1-8]\\)\\([nbrq]\\)?"
"A regular expression matching a UCI move.")
+(defun chess-uci-long-algebraic-to-ply (position move)
+ "Convert the long algebraic notation MOVE for POSITION to a ply."
+ (assert (vectorp position))
+ (assert (stringp move))
+ (let ((case-fold-search nil))
+ (when (string-match chess-uci-long-algebraic-regexp move)
+ (let ((color (chess-pos-side-to-move position))
+ (from (chess-coord-to-index (match-string 1 move)))
+ (to (chess-coord-to-index (match-string 2 move)))
+ (promotion (match-string 3 move)))
+ (apply #'chess-ply-create position nil
+ (if (and (= from (chess-pos-king-index position color))
+ (= (chess-index-rank from) (chess-index-rank to))
+ (> (abs (- (chess-index-file from)
+ (chess-index-file to))) 1))
+ (chess-ply-castling-changes
+ position
+ (< (- (chess-index-file to) (chess-index-file from)) 0))
+ (nconc (list from to)
+ (when promotion
+ (list :promote (upcase (aref promotion 0)))))))))))
+
+(defsubst chess-uci-convert-long-algebraic (move)
+ "Convert long algebraic MOVE to a ply in reference to the engine position.
+If conversion fails, this function fired an 'illegal event."
+ (or (chess-uci-long-algebraic-to-ply (chess-engine-position nil) move)
+ (chess-engine-command nil 'illegal)))
+
+(defvar chess-uci-regexp-alist
+ (list
+ (cons "^id\\s-+name\\s-+\\(.+\\)$"
+ (function
+ (lambda ()
+ (setq-local chess-engine-opponent-name (match-string 1))
+ 'once)))
+ (cons (concat "^bestmove\\s-+\\(" chess-uci-long-algebraic-regexp "\\)")
+ (function
+ (lambda ()
+ (funcall chess-engine-response-handler 'move
+ (chess-uci-convert-long-algebraic (match-string 1)))))))
+ "Patterns matching responses of a standard UCI chess engine.")
+
(defun chess-uci-position (game)
(concat "position fen " (chess-pos-to-fen (chess-game-pos game 0) t)
" moves " (mapconcat (lambda (ply)