summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2002-04-15 02:07:36 +0000
committerJohn Wiegley <johnw@newartisans.com>2002-04-15 02:07:36 +0000
commitb24315b28140dac7cf10828394ff347c4ad3e985 (patch)
tree8fa41f8fc2a953f1c9fcf8c9e11cd290299e265f
parent7365cd3c961dece991bc67017afcc917359be69a (diff)
*** no comment ***
-rw-r--r--chess-display.el33
-rw-r--r--chess-fen.el31
-rw-r--r--chess-file.el2
-rw-r--r--chess-game.el3
-rw-r--r--chess-pgn.el13
-rw-r--r--chess.el99
6 files changed, 99 insertions, 82 deletions
diff --git a/chess-display.el b/chess-display.el
index 67eaa84..c272a4a 100644
--- a/chess-display.el
+++ b/chess-display.el
@@ -23,13 +23,12 @@
:type 'boolean
:group 'chess-display)
-(defcustom chess-display-mode-line-format " %C %N. %M"
+(defcustom chess-display-mode-line-format " %C %M"
"The format of a chess display's modeline.
Special characters include:
%C The color to move, White or Black; if the game is finished,
this will instead be the completion string
- %N Current game sequence
%M Current algebraic move text (prefixed by ... when White)
%E Current position evaluation, if engine supports it
(negative numbers favor black) [NOT WORKING YET]"
@@ -147,7 +146,8 @@ makes moves, or any other changes to the underlying game."
(chess-game-set-data chess-display-game 'my-color my-color))
(chess-game-set-start-position chess-display-game
chess-starting-position)
- (chess-game-set-data chess-display-game 'my-color t))))
+ (chess-game-set-data chess-display-game 'my-color t))
+ (chess-display-set-index nil 0)))
(defun chess-display-position (display)
"Return the position currently viewed."
@@ -204,8 +204,7 @@ also view the same game."
(chess-with-current-buffer display
(chess-game-set-tags chess-display-game (chess-game-tags game))
;; this call triggers `setup-game' for us
- (let ((chess-game-inhibit-events t))
- (chess-game-set-plies chess-display-game (chess-game-plies game)))
+ (chess-game-set-plies chess-display-game (chess-game-plies game))
(chess-display-set-index nil (or index (chess-game-index game)))))
(defun chess-display-detach-game (display)
@@ -232,7 +231,8 @@ modeline."
(defun chess-display-set-index (display index)
(chess-with-current-buffer display
(chess-display-set-index* nil index)
- (chess-display-update nil t)))
+ (chess-display-update nil t)
+ (chess-display-update-modeline)))
(defsubst chess-display-index (display)
(chess-with-current-buffer display
@@ -493,15 +493,13 @@ The key bindings available in this mode are:
(if color (chess-string 'mode-white)
(chess-string 'mode-black)))))))
- ((string= code "N")
- (if (= index 0)
- "START"
- (setq code (int-to-string
- (chess-game-seq chess-display-game)))))
-
((string= code "M")
- (setq code (concat (if color "... ")
- (or (chess-ply-to-algebraic ply) "???"))))
+ (if (= index 0)
+ (setq code (chess-string 'mode-start))
+ (setq code (concat (int-to-string
+ (chess-game-seq chess-display-game))
+ ". "(if color "... ")
+ (or (chess-ply-to-algebraic ply) "???")))))
((string= code "E")
;; jww (2002-04-14): This code is encountering some nasty
@@ -571,7 +569,7 @@ Basically, it means we are playing, not editing or reviewing."
(delete-backward-char 1))
(goto-char (point-min))
(cond
- ((search-forward "[Event" nil t)
+ ((search-forward "[Event " nil t)
(goto-char (match-beginning 0))
(chess-display-copy-game display (chess-pgn-to-game)))
((looking-at (concat chess-algebraic-regexp "$"))
@@ -1043,8 +1041,9 @@ Clicking once on a piece selects it; then click on the target location."
(> piece ?a)
(< piece ?a))
(throw 'message (chess-string 'wrong-color)))
- ((null (chess-legal-plies position :index coord))
- (throw 'message (chess-string 'piece-immobile))))
+ ;((null (chess-legal-plies position :index coord))
+ ; (throw 'message (chess-string 'piece-immobile)))
+ )
(setq chess-display-last-selected (list (point) coord))
(chess-display-highlight nil coord)
(if chess-display-highlight-legal
diff --git a/chess-fen.el b/chess-fen.el
index b104f06..bd540a3 100644
--- a/chess-fen.el
+++ b/chess-fen.el
@@ -46,9 +46,10 @@
(let ((i 0) (l (length fen))
(rank 0) (file 0) (c ?0)
(position (chess-pos-create t))
- error number)
- (while (and (null error) (/= c ? ) (< i l))
- (setq c (aref fen i))
+ error (space-count 0))
+ (setq c (aref fen i))
+ (while (and (null error)
+ (/= c ? ) (< i l))
(cond
((= c ?/)
(setq file 0 rank (1+ rank)))
@@ -57,15 +58,22 @@
((memq (upcase c) '(?K ?Q ?B ?N ?R ?P))
(chess-pos-set-piece position (chess-rf-to-index rank file) c)
(setq file (1+ file)))
- (t (setq error t)))
- (setq i (1+ i)))
+ (t
+ (setq error t)))
+ (setq i (1+ i) c (aref fen i)))
+ (if (= (aref fen i) ? )
+ (setq i (1+ i)))
(if (memq (aref fen i) '(?b ?w))
- (chess-pos-set-side-to-move position (= (aref fen i) ?w))
+ (progn
+ (chess-pos-set-side-to-move position (= (aref fen i) ?w))
+ (setq i (+ i 2)))
(setq error t))
- (setq i (+ i 2) number nil)
- (while (and (null error) (< i l))
- (setq c (aref fen i))
+ (setq c (aref fen i))
+ (while (and (null error)
+ (< space-count 2) (< i l))
(cond
+ ((= c ?-))
+ ((= c ? ) (setq space-count (1+ space-count)))
((= c ?K) (chess-pos-set-can-castle position ?K t))
((= c ?Q) (chess-pos-set-can-castle position ?Q t))
((= c ?k) (chess-pos-set-can-castle position ?k t))
@@ -74,8 +82,9 @@
(chess-pos-set-en-passant position (chess-coord-to-index
(substring fen i (+ i 2))))
(setq i (1+ i)))
- (t (setq error t)))
- (setq i (1+ i)))
+ (t
+ (setq error t)))
+ (setq i (1+ i) c (aref fen i)))
(unless error
position)))
diff --git a/chess-file.el b/chess-file.el
index dacf6b3..ddfeac7 100644
--- a/chess-file.el
+++ b/chess-file.el
@@ -20,7 +20,7 @@
((eq event 'rescan)
(goto-char (point-min))
(setq chess-file-locations nil)
- (while (search-forward "[Event" nil t)
+ (while (search-forward "[Event " nil t)
(goto-char (match-beginning 0))
(push (point) chess-file-locations)
(forward-char 1))
diff --git a/chess-game.el b/chess-game.el
index 9832372..73176b6 100644
--- a/chess-game.el
+++ b/chess-game.el
@@ -98,6 +98,9 @@ matches."
(defsubst chess-game-data-alist (game)
(nth 2 game))
+(defsubst chess-game-set-data-alist (game value)
+ (setcar (nthcdr 2 game) value))
+
(defun chess-game-set-data (game key value)
(let* ((alist (chess-game-data-alist game))
(cell (assq key alist)))
diff --git a/chess-pgn.el b/chess-pgn.el
index 64b1566..463ea65 100644
--- a/chess-pgn.el
+++ b/chess-pgn.el
@@ -16,9 +16,9 @@
(pgn-parse-error . "Error parsing PGN syntax")))
(defun chess-pgn-read-plies (game position &optional top-level)
- (let ((plies (list t)) prevpos done)
+ (let ((plies (list t)) prevpos)
(catch 'done
- (while (not (or done (eobp)))
+ (while (not (eobp))
(cond
((looking-at "[1-9][0-9]*\\.[. ]*")
(goto-char (match-end 0)))
@@ -37,9 +37,10 @@
(looking-at "\\(\\*\\|1-0\\|0-1\\|1/2-1/2\\)"))
(goto-char (match-end 0))
(chess-game-set-tag game "Result" (match-string-no-properties 0))
- (nconc plies (list (chess-ply-create
- (chess-ply-next-pos (car (last plies))))))
- (setq done t))
+ (unless (eq t (car (last plies)))
+ (nconc plies (list (chess-ply-create
+ (chess-ply-next-pos (car (last plies)))))))
+ (throw 'done t))
((looking-at "{")
(forward-char)
@@ -57,7 +58,7 @@
((and (not top-level)
(looking-at ")"))
(forward-char)
- (setq done t))
+ (throw 'done t))
(t
(nconc plies (list (chess-ply-create
diff --git a/chess.el b/chess.el
index 7579ec1..f4c71cc 100644
--- a/chess.el
+++ b/chess.el
@@ -76,7 +76,8 @@
(require 'chess-game)
(require 'chess-display)
(require 'chess-engine)
-(require 'chess-pgn)
+(require 'chess-database)
+(require 'chess-file)
(defgroup chess nil
"An Emacs chess playing program."
@@ -204,62 +205,66 @@ available."
(defun chess-read-pgn (&optional file)
"Read and display a PGN game after point."
(interactive "P")
- (if (or file (not (search-forward "[Event" nil t)))
+ (if (or file (not (search-forward "[Event " nil t)))
(setq file (read-file-name "Read a PGN game from file: ")))
(if file
(find-file file))
- (let ((game (chess-pgn-to-game)))
+ (let ((game (chess-pgn-to-game))
+ display)
(when game
- (require chess-default-display)
- (chess-display-create game chess-default-display
- (chess-game-side-to-move game)))))
-
-(defvar chess-puzzle-locations nil)
-
-(defun chess-puzzle-next ()
- "Play the next puzzle in the collection, selected randomly."
- (interactive)
- (if chess-puzzle-locations
- (chess-puzzle (aref chess-puzzle-locations 0))))
+ (setq display (chess-create-display))
+ (chess-display-set-game display game))))
;;;###autoload
-(defun chess-puzzle (file)
+(defun chess-puzzle (file &optional index)
"Pick a random puzzle from FILE, and solve it against the default engine.
The spacebar in the display buffer is bound to `chess-puzzle-next',
making it easy to go on to the next puzzle once you've solved one."
(interactive "fRead chess puzzles from: ")
- (save-excursion
- (with-current-buffer (find-file-noselect file)
- (when (or (null chess-puzzle-locations)
- (not (equal file (aref chess-puzzle-locations 0))))
- (let (locations)
- (goto-char (point-min))
- (while (search-forward "[Event" nil t)
- (push (point) locations))
- (setq chess-puzzle-locations (vector file locations nil nil)))
- (random t))
- (goto-char (nth (random (length (aref chess-puzzle-locations 1)))
- (aref chess-puzzle-locations 1)))
- (let ((game (chess-pgn-to-game)))
- (when game
- (require chess-default-display)
- (let (puzzle-display)
- (if (buffer-live-p (aref chess-puzzle-locations 2))
- (progn
- (setq puzzle-display (aref chess-puzzle-locations 2))
- (chess-display-set-game puzzle-display game))
- (setq puzzle-display
- (chess-display-create game chess-default-display
- (chess-game-side-to-move game))))
- (aset chess-puzzle-locations 2 puzzle-display)
- ;; setup spacebar as a convenient way to jump to the next puzzle
- (with-current-buffer puzzle-display
- (define-key (current-local-map) [? ] 'chess-puzzle-next)))
- (require chess-default-engine)
- (aset chess-puzzle-locations 3
- (or (and (buffer-live-p (aref chess-puzzle-locations 3))
- (aref chess-puzzle-locations 3))
- (chess-engine-create game chess-default-engine))))))))
+ (random t)
+ (let* ((database (chess-database-open 'chess-file file))
+ (objects (and database (chess-session)))
+ (display (cadr objects)))
+ (when database
+ (with-current-buffer display
+ ;; make sure the database is closed when the display is shutdown
+ (chess-game-add-hook (chess-display-game nil)
+ 'chess-database-event-handler database)
+ (chess-game-set-data (chess-display-game nil) 'database database)
+ (define-key (current-local-map) [? ] 'chess-puzzle-next)
+ (chess-puzzle-next)))))
+
+(defun chess-puzzle-next ()
+ "Play the next puzzle in the collection, selected randomly."
+ (interactive)
+ (let* ((database (chess-game-data chess-display-game 'database))
+ (index (random (chess-database-count database)))
+ (next-game (chess-database-read database index)))
+ (if (null next-game)
+ (error "Error reading game at position %d" index)
+ (chess-display-set-game nil next-game 0)
+ (chess-game-set-data chess-display-game 'my-color
+ (chess-pos-side-to-move
+ (chess-game-pos chess-display-game)))
+ (dolist (key '(database database-index database-count))
+ (chess-game-set-data chess-display-game key
+ (chess-game-data next-game key))))))
+
+(defun chess-write-game (game file)
+ "Write a chess GAME to FILE as raw Lisp."
+ (let ((game-copy (copy-alist game)))
+ (chess-game-set-hooks game-copy nil)
+ (chess-game-set-data-alist game-copy nil)
+ (with-current-buffer (find-file-noselect)
+ (erase-buffer)
+ (prin1 game)
+ (save-buffer))))
+
+(defun chess-read-game (file)
+ "Read a chess game as raw Lisp from FILE."
+ (with-current-buffer (find-file-noselect)
+ (goto-char (point-min))
+ (read)))
(provide 'chess)