diff options
| -rw-r--r-- | chess-fen.el | 2 | ||||
| -rw-r--r-- | chess-gnuchess.el | 6 | ||||
| -rw-r--r-- | chess-pgn.el | 9 | ||||
| -rw-r--r-- | chess-pos.el | 2 | ||||
| -rw-r--r-- | chess.el | 74 |
5 files changed, 81 insertions, 12 deletions
diff --git a/chess-fen.el b/chess-fen.el index 8ef7ccb..8dca4f6 100644 --- a/chess-fen.el +++ b/chess-fen.el @@ -84,7 +84,7 @@ If FULL is non-nil, represent trailing spaces as well." (if (= p ? ) (setq blank (1+ blank)) (if (> blank 0) - (setq blank 0 str (concat str (int-to-string blank)))) + (setq str (concat str (int-to-string blank)) blank 0)) (setq str (concat str (char-to-string p)))))) (if (and full (> blank 0)) (setq str (concat str (int-to-string blank)))) diff --git a/chess-gnuchess.el b/chess-gnuchess.el index 1151291..6eb26c0 100644 --- a/chess-gnuchess.el +++ b/chess-gnuchess.el @@ -41,8 +41,10 @@ (chess-engine-send nil "quit\n")) ((eq event 'setup) - (chess-engine-send nil (format "setboard %s\n" - (chess-pos-to-fen (car args))))) + (let ((file (make-temp-file "gch"))) + (with-temp-file file + (insert (chess-pos-to-fen (car args)) ?\n)) + (chess-engine-send nil (format "epdload %s\n" file)))) ((eq event 'pass) (chess-engine-send nil "go\n")) diff --git a/chess-pgn.el b/chess-pgn.el index ae0adc3..930edc5 100644 --- a/chess-pgn.el +++ b/chess-pgn.el @@ -64,10 +64,11 @@ (goto-char (match-end 0))) (let ((fen (chess-game-tag game "FEN"))) (chess-game-set-plies - game (chess-pgn-read-plies - game (if fen - (chess-fen-to-pos fen) - (chess-pos-copy chess-starting-position)) t))) + game (or (chess-pgn-read-plies + game (if fen + (chess-fen-to-pos fen) + (chess-pos-copy chess-starting-position)) t) + (list (chess-ply-create (chess-fen-to-pos fen)))))) game))) (defun chess-pgn-insert-annotations (game index ply) diff --git a/chess-pos.el b/chess-pos.el index 6d1dae2..286047e 100644 --- a/chess-pos.el +++ b/chess-pos.el @@ -177,7 +177,7 @@ If BLANK is non-nil, all of the squares will be empty. The current side-to-move is always white." (if blank (vconcat (make-vector 64 ? ) - [nil t t t t nil t nil]) + [nil nil nil nil nil nil t nil]) (chess-pos-copy chess-starting-position))) (defsubst chess-rf-to-index (rank file) @@ -76,6 +76,7 @@ a0 243 (require 'chess-game) (require 'chess-display) +(require 'chess-engine) (require 'chess-pgn) (defgroup chess nil @@ -99,14 +100,79 @@ a0 243 (defun chess (&optional arg) "Start a game of chess." (interactive "P") - (require chess-default-display) - (require chess-default-engine) (let ((game (chess-game-create)) ; start out as white always display engine) + (require chess-default-display) (chess-display-set-game (chess-display-create chess-default-display t) game) - (chess-engine-set-game - (chess-engine-create chess-default-engine) game))) + (let ((engine-module + (if arg + (intern-soft (read-string "Engine module to play against: ")) + chess-default-engine))) + (require engine-module) + (chess-engine-set-game (chess-engine-create engine-module) game)))) + (cons display engine))) + +;;;###autoload +(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))) + (setq file (read-file-name "Read a PGN game from file: "))) + (if file + (find-file file)) + (let ((game (chess-pgn-to-game))) + (when game + (require chess-default-display) + (chess-display-set-game + (chess-display-create chess-default-display + (chess-game-side-to-move game)) 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)))) + +;;;###autoload +(defun chess-puzzle (file) + "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 + (or (and (buffer-live-p (aref chess-puzzle-locations 2)) + (aref chess-puzzle-locations 2)) + (chess-display-create chess-default-display + (chess-game-side-to-move game))))) + (chess-display-set-game puzzle-display 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) + (let ((puzzle-engine + (or (and (buffer-live-p (aref chess-puzzle-locations 3)) + (aref chess-puzzle-locations 3)) + (chess-engine-create chess-default-engine)))) + (chess-engine-set-game puzzle-engine game) (aset chess-puzzle-locations 3 puzzle-engine))))))) (provide 'chess) |
