"A regular expression that matches all possible algebraic moves.
This regexp handles both long and short form.")
-(defun chess-algebraic-to-ply (position move &optional search-func)
+(defun chess-algebraic-to-ply (position move)
"Convert the algebraic notation MOVE for POSITION to a ply."
- (when (string-match chess-algebraic-regexp move)
- (let* ((color (chess-pos-side-to-move position))
- (mate (match-string 10 move))
- (piece (aref move 0))
- (changes
- (if (eq piece ?O)
- (let ((rank (if color 7 0))
- (long (= (length (match-string 1 move)) 5)))
- (list (chess-rf-to-index rank 4)
- (chess-rf-to-index rank (if long 2 6))
- (chess-rf-to-index rank (if long 0 7))
- (chess-rf-to-index rank (if long 3 5))))
- (let ((source (match-string 4 move))
- (target (chess-coord-to-index (match-string 7 move))))
- (if (and source (= (length source) 2))
- (list (chess-coord-to-index source) target)
- (let (candidates which)
- (unless (< piece ?a)
- (setq piece ?P))
- ;; we must use our knowledge of how pieces can
- ;; move, to determine which piece is meant by the
- ;; piece indicator
- (when (setq candidates
- (funcall (or search-func
- 'chess-standard-search-position)
- position target (if color piece
- (downcase piece))))
- (if (= (length candidates) 1)
- (list (car candidates) target)
- (if (null source)
- (error "Clarify piece to move by rank or file")
- (while candidates
- (if (if (>= source ?a)
- (eq (cdar candidates) (- source ?a))
- (eq (caar candidates) (- 7 (- source ?1))))
- (setq which (car candidates) candidates nil)
- (setq candidates (cdr candidates))))
- (if (null which)
- (error "Could not determine which piece to use")
- (list which target)))))))))))
- (if mate
- (nconc changes
- (list (if (equal mate "#")
- ':checkmate
- ':check))))
- (assert changes)
- (apply 'chess-ply-create position changes))))
+ (unless (string-match chess-algebraic-regexp move)
+ (error "Cannot parse non-algebraic move notation: %s" move))
+ (let* ((color (chess-pos-side-to-move position))
+ (mate (match-string 10 move))
+ (piece (aref move 0))
+ (changes
+ (if (eq piece ?O)
+ (let ((rank (if color 7 0))
+ (long (= (length (match-string 1 move)) 5)))
+ (list (chess-rf-to-index rank 4)
+ (chess-rf-to-index rank (if long 2 6))))
+ (let ((source (match-string 4 move))
+ (target (chess-coord-to-index (match-string 7 move))))
+ (if (and source (= (length source) 2))
+ (list (chess-coord-to-index source) target)
+ (if (= (length source) 0)
+ (setq source nil)
+ (setq source (aref source 0)))
+ (let (candidates which)
+ (unless (< piece ?a)
+ (setq piece ?P))
+ ;; we must use our knowledge of how pieces can
+ ;; move, to determine which piece is meant by the
+ ;; piece indicator
+ (when (setq candidates
+ (chess-search-position position target
+ (if color piece
+ (downcase piece))))
+ (if (= (length candidates) 1)
+ (list (car candidates) target)
+ (if (null source)
+ (error "Clarify piece to move by rank or file")
+ (while candidates
+ (if (if (>= source ?a)
+ (eq (chess-index-file (car candidates))
+ (- source ?a))
+ (eq (chess-index-rank (car candidates))
+ (- 7 (- source ?1))))
+ (setq which (car candidates) candidates nil)
+ (setq candidates (cdr candidates))))
+ (if (null which)
+ (error "Could not determine which piece to use")
+ (list which target)))))))))))
+ (if mate
+ (nconc changes
+ (list (if (equal mate "#")
+ :checkmate
+ :check))))
+ (and changes (apply 'chess-ply-create position changes))))
-(defun chess-ply-to-algebraic (ply &optional long search-func)
+(defun chess-ply-to-algebraic (ply &optional long)
"Convert the given PLY to algebraic notation.
If LONG is non-nil, render the move into long notation."
(if (null (car (chess-ply-changes ply)))
(color (chess-pos-side-to-move pos)) str
(notation
(if (setq str
- (and (= (upcase from-piece) ?K)
- (= from (chess-rf-to-index (if color 7 0) 4))
- (if (= to (chess-rf-to-index (if color 7 0) 6))
- "O-O"
- (if (= to (chess-rf-to-index (if color 7 0) 2))
- "O-O-O"))))
+ (if (memq :castle changes) "O-O"
+ (if (memq :long-castle changes) "O-O-O")))
str
- (let ((candidates (funcall (or search-func
- 'chess-standard-search-position)
- pos to from-piece))
+ (let ((candidates (chess-search-position pos to from-piece))
(rank 0) (file 0)
(from-rank (/ from 8))
(from-file (mod from 8))
(if (/= ? (chess-pos-piece pos to))
"x" (if long "-"))
(chess-index-to-coord to)
- (let ((promote (memq ':promote changes)))
+ (let ((promote (memq :promote changes)))
(if promote
(concat "=" (char-to-string (cadr promote))))))))))
(concat notation
- (if (memq ':check changes) "+"
- (if (memq ':checkmate changes) "#"))))))
+ (if (memq :check changes) "+"
+ (if (memq :checkmate changes) "#"))))))
(provide 'chess-algebraic)