1 ;;; chess-epd.el --- Extended Position Description Format
3 ;; Copyright (C) 2004 Free Software Foundation, Inc.
5 ;; Author: Mario Lang <mlang@delysid.org>
7 ;; This file is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; This file is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
25 ;; EPD is the "Extended Position Description" format. It is a standard for
26 ;; describing chess positions along with an extended set of structured
27 ;; attribute values using the ASCII character set. It is intended for data and
28 ;; command interchange among chessplaying programs. It is also intended
29 ;; for the representation of portable opening library repositories and for
30 ;; problem test suites.
32 ;; A single EPD record uses one text line of variable length composed of
33 ;; four data fields followed by zero or more operations. A text file
34 ;; composed exclusively of EPD data records should have a file name with
44 (defun chess-epd-annotation-to-string (annotation)
45 (let ((opcode (car annotation))
46 (value (cdr annotation)))
48 ((or (eq opcode 'am) (eq opcode 'bm))
49 (assert (consp value))
51 opcode (mapconcat #'chess-ply-to-string value " ")))
53 (assert (integerp value))
54 (format "%S %d;" opcode value))
55 ((or (eq opcode 'pv) (eq opcode 'sv))
57 opcode (chess-var-to-algebraic value)))
59 (format "%S%s;" opcode (if (eq value t) "" (format " %s" value)))))))
61 (defun chess-pos-to-epd (position)
62 "Convert a chess POSITION to a string representation in extended
63 position description format."
65 (concat (chess-pos-to-fen position)
66 (when (consp (chess-pos-annotations position))
68 (mapconcat #'chess-epd-annotation-to-string
69 (chess-pos-annotations position)
72 (defun chess-epd-to-pos (&optional string)
73 "Convert extended position description to a chess position.
74 If STRING is not specified, look for an EPD string in the current buffer,
75 and advance point after the correctly parsed position."
82 (defun chess-epd-read-file (file)
83 "Return a list of positions contained in FILE."
84 (let ((positions (list t)) pos)
86 (insert-file-literally file)
87 (goto-char (point-min))
88 (while (setq pos (chess-epd-parse))
89 (nconc positions (list pos))))
92 (defsubst chess-game-to-epd (game &optional to-string index)
94 (chess-pos-to-epd (chess-game-pos game index))
95 (insert (chess-pos-to-epd (chess-game-pos game index)) ?\n)))
97 (defsubst chess-epd-to-game (&optional string)
98 (chess-game-create (chess-epd-to-pos string)))
100 (defun chess-epd-parse ()
101 (when (re-search-forward chess-fen-regexp nil t)
102 (let ((pos (chess-fen-to-pos (match-string 0))))
103 (while (= 1 (skip-chars-forward " "))
104 (if (looking-at "[A-Za-z]")
105 (let ((opcode (intern (buffer-substring
106 (point) (+ (point) (skip-chars-forward
108 (if (= 1 (skip-chars-forward ";"))
109 (chess-pos-set-epd pos opcode)
110 (if (= (skip-chars-forward " ") 1)
111 (let ((val (buffer-substring
114 (skip-chars-forward "^;"))
115 (skip-chars-forward ";")))))
119 ((or (eq opcode 'am) (eq opcode 'bm))
120 (mapcar (lambda (move)
121 (chess-ply-from-string pos move))
122 (split-string val " ")))
125 ((or (eq opcode 'pm) (eq opcode 'sm)) ;predicted/supplied move
126 (chess-ply-from-string pos val))
127 ((or (eq opcode 'pv) (eq opcode 'sv)) ; predicted/supplied variation
128 (let ((var (chess-var-create pos)))
130 (let ((changes (chess-ply-from-string
131 (chess-var-pos var) ply)))
133 (chess-var-move var changes)
134 (error "Unable to convert ply '%s'" ply))))
135 (split-string val " "))
138 (error "Illegal char following identifier"))))
139 (error "Illegal Identifier")))
140 (skip-chars-forward "\n")
144 ;;; chess-epd.el ends here