* 2.0
+** Breakdown
+
+*** Core library
+*** Display modules
+*** Chess engines
+
+** Finished writing `define-chess-module'
+
+** Call `chess-game-move' in chess-display to move the pieces
+
** Keyboard shortcuts
*** Right now "nf, nf", causes an error
;; $Revision$
-(require 'chess-pos)
(require 'chess-ply)
(defconst chess-algebraic-pieces-regexp "[RNBKQ]")
"A regular expression that matches all possible algebraic moves.
This regexp handles both long and short form.")
-(defun chess-algebraic-to-ply (position move)
+(defun chess-algebraic-to-ply (position move &optional search-func)
"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))
;; move, to determine which piece is meant by the
;; piece indicator
(when (setq candidates
- (funcall (car chess-modules) nil nil
- 'search position target
- (if color piece
- (downcase piece))))
+ (funcall (or search-func chess-standard-search)
+ position target (if color piece
+ (downcase piece))))
(if (= (length candidates) 1)
(list (car candidates) target)
(if (null source)
':check))))
(apply 'chess-ply-create position changes))))
-(defun chess-ply-to-algebraic (ply &optional long)
+(defun chess-ply-to-algebraic (ply &optional long search-func)
"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)))
"O-O-O"))))
str
(let ((candidates
- (funcall (car chess-modules)
- nil nil 'search pos to from-piece))
+ (funcall (or search-func chess-standard-search)
+ pos to from-piece))
(rank 0) (file 0)
(from-rank (/ from 8))
(from-file (mod from 8))
+++ /dev/null
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Play against the crafty engine
-;;
-;; $Revision$
-
-(require 'chess-process)
-
-(defgroup chess-crafty nil
- "Interface code for playing against crafty. Uses `chess-process'."
- :group 'chess)
-
-(defcustom chess-crafty-command (and (require 'executable)
- (executable-find "crafty"))
- "The name of the crafty program."
- :type 'string
- :group 'chess-crafty)
-
-;;; Code:
-
-;;;###autoload
-(defun chess-crafty (session buffer event &rest args)
- (if (not (eq event 'initialize))
- (apply 'chess-process session buffer event args)
- (with-current-buffer
- (chess-process session buffer event chess-process-triggers
- chess-crafty-command)
- (process-send-string (get-buffer-process (current-buffer))
- (concat "display nogeneral\n"
- "display nochanges\n"
- "display noextstats\n"
- "display nohashstats\n"
- "display nomoves\n"
- "display nonodes\n"
- "display noply1\n"
- "display nostats\n"
- "display notime\n"
- "display novariation\n"
- "alarm off\n"
- "ansi off\n"))
- (current-buffer))))
-
-(provide 'chess-crafty)
-
-;;; chess-crafty.el ends here
" " (int-to-string (if (> index 1)
(/ index 2) (1+ (/ index 2))))
". " (if color "... ")
- (chess-ply-to-algebraic
- (chess-game-ply chess-display-game (1- index))))))))
+ (chess-game-ply-to-algebraic chess-display-game))))))
(defsubst chess-display-current-p ()
"Return non-nil if the displayed chessboard reflects the current game.
"Send the current board configuration to the user."
(interactive)
(chess-session-event chess-current-session 'setup
- (chess-game-create nil chess-display-position)))
+ (chess-game-create chess-display-position)))
(defun chess-display-copy-board ()
"Send the current board configuration to the user."
"White" "Black")
(1+ (/ chess-display-game-index 2))))))
(chess-session-event chess-current-session 'move
- (chess-algebraic-to-ply chess-display-position move)))
+ (chess-game-algebraic-to-ply chess-display-game move)))
(defun chess-display-set-current (dir)
"Change the currently displayed board.
(char-to-string (downcase last-command-char)))))
(unless (and chess-legal-moves
(eq chess-display-position chess-legal-moves-pos))
- (setq chess-legal-moves-pos chess-display-position
- chess-legal-moves
- (sort (mapcar 'chess-ply-to-algebraic
- (chess-legal-plies chess-display-position
- (chess-pos-side-to-move
- chess-display-position)))
- 'string-lessp)))
+ (let ((search-func (chess-game-search-func chess-display-game)))
+ (setq chess-legal-moves-pos chess-display-position
+ chess-legal-moves
+ (sort (mapcar (function
+ (lambda (ply)
+ (chess-ply-to-algebraic ply nil search-func)))
+ (chess-legal-plies chess-display-position search-func))
+ 'string-lessp))))
(let ((moves
(mapcar (function
(lambda (move)
(setq moves (delq nil moves))
(cond
((= (length moves) 1)
- (chess-session-event chess-current-session 'move
- (chess-algebraic-to-ply chess-display-position
- (car moves)))
+ (chess-session-event
+ chess-current-session 'move
+ (chess-algebraic-to-ply chess-display-position (car moves)
+ (chess-game-search-func chess-display-game)))
(setq chess-move-string nil
chess-legal-moves nil
chess-legal-moves-pos nil))
--- /dev/null
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Play against popular chess engines
+;;
+;; $Revision$
+
+(require 'chess-process)
+
+(define-chess-engine crafty (&rest args)
+ (list (list
+ (concat "\\s-*\\(White\\|Black\\)\\s-*([0-9]+):\\s-+\\("
+ chess-algebraic-regexp "\\)\\s-*$")
+ (function
+ (lambda (color move)
+ (if (string= (if (chess-game-side-to-move chess-process-game)
+ "White" "Black")
+ color)
+ (chess-session-event
+ chess-current-session 'move
+ (chess-algebraic-to-ply
+ (chess-game-pos chess-process-game) move)))))
+ 1 2)
+ '("Illegal move:\\s-*\\(.*\\)"
+ (signal 'chess-illegal (match-string 1))))
+ (init (concat "display nogeneral\n"
+ "display nochanges\n"
+ "display noextstats\n"
+ "display nohashstats\n"
+ "display nomoves\n"
+ "display nonodes\n"
+ "display noply1\n"
+ "display nostats\n"
+ "display notime\n"
+ "display novariation\n"
+ "alarm off\n"
+ "ansi off"))
+ (shutdown "quit")
+ (move (chess-game-ply-to-algebraic chess-process-game (car args)))
+ (pass "go"))
+
+(define-chess-engine gnuchess (&rest args)
+ (list (list
+ (concat "My move is : \\(" chess-algebraic-regexp "\\)")
+ (function
+ (lambda (move)
+ (chess-session-event chess-current-session 'move
+ (chess-algebraic-to-ply
+ (chess-game-pos chess-process-game) move))))
+ 1)
+ '("Illegal move:\\s-*\\(.*\\)"
+ (signal 'chess-illegal (match-string 1))))
+ (shutdown "quit")
+ (move (chess-game-ply-to-algebraic chess-process-game (car args)))
+ (pass "go"))
+
+;;; chess-engines.el ends here
;; game, and a list of plies representing the main variation.
(require 'chess-ply)
+(require 'chess-algebraic)
(defconst chess-game-default-tags
- (list '("Event" . "Computer chess game")
- '("Round" . "-")
- (cons "Site" (system-name))
- '("White" . "?")
- '("Black" . "?")
- '("Result" . "*")
- '("TimeControl" . "-")))
+ `(("Event" . "Computer chess game")
+ ("Round" . "-")
+ ("Site" . ,(system-name))
+ ("White" . "?")
+ ("Black" . "?")
+ ("Result" . "*")
+ ("TimeControl" . "-")))
(defsubst chess-game-tags (game)
"Return the tags alist associated with GAME."
(defsubst chess-game-plies (game)
"Return the tags alist associated with GAME."
- (cdr game))
+ (cddr game))
(defsubst chess-game-set-plies (game plies)
"Return the tags alist associated with GAME."
- (setcdr game plies))
+ (setcdr (cdr game) plies))
+
+(defsubst chess-game-validation-func (game)
+ "Return the tags alist associated with GAME."
+ (car (cadr game)))
+
+(defsubst chess-game-set-validation-func (game func)
+ "Return the tags alist associated with GAME."
+ (setcar (cadr game) func))
+
+(defsubst chess-game-search-func (game)
+ "Return the tags alist associated with GAME."
+ (cdr (cadr game)))
+
+(defsubst chess-game-set-search-func (game func)
+ "Return the tags alist associated with GAME."
+ (setcdr (cadr game) func))
(defsubst chess-game-tag (game tag)
"Return the value for TAG in GAME."
(defsubst chess-game-index (game)
"Return the GAME's current position index."
- (length (cdr game)))
+ (length (chess-game-plies game)))
(defsubst chess-game-seq (game)
"Return the current GAME sequence."
(defun chess-game-ply (game &optional index)
"Return the position related to GAME's INDEX position."
(if index
- (nth index (cdr game))
- (car (last (cdr game)))))
+ (nth index (chess-game-plies game))
+ (car (last (chess-game-plies game)))))
+
+(defsubst chess-game-add-ply (game ply)
+ "Return the position related to GAME's INDEX position."
+ (nconc (chess-game-plies game) (list ply)))
(defun chess-game-pos (game &optional index)
"Return the position related to GAME's INDEX position."
(car (chess-game-ply game index)))
-(defun chess-game-create (&optional tags position)
+(defun chess-game-create (&rest keywords)
"Create a new chess game object.
-If TAGS is non-nil, it is a list of cons cell that define starting
-tags to use. If POSITION is non-nil, the game starts at that
-position."
- (let ((game (cons nil nil)))
- (dolist (tag chess-game-default-tags)
- (chess-game-set-tag game (car tag) (cdr tag)))
- (chess-game-set-tag game "Date" (format-time-string "%Y.%m.%d"))
- (dolist (tag tags)
- (chess-game-set-tag game (car tag) (cdr tag)))
- (setcdr game (list (chess-ply-create
- (or position (chess-pos-create)))))
+Keywords may be specified to customize the game object. The supported
+keywords are:
+
+ :position POS ; set the start position
+ :search FUNC ; function used to search chess positions
+ :validate FUNC ; function used to validate chess moves
+ :tags ALIST"
+ (let ((game (list (cdr (assq ':tags keywords))
+ (cons (or (cdr (assq ':validate keywords))
+ chess-standard-validate)
+ (or (cdr (assq ':search keywords))
+ chess-standard-search)))))
+ (dolist (tag (cons (cons "Date" (format-time-string "%Y.%m.%d"))
+ chess-game-default-tags))
+ (unless (chess-game-tag game (car tag))
+ (chess-game-set-tag game (car tag) (cdr tag))))
+ (chess-game-add-ply game (chess-ply-create
+ (or (cdr (assq ':position keywords))
+ (chess-pos-create))))
game))
(defun chess-game-move (game ply)
progress (nil), if it is drawn, resigned, mate, etc."
(let ((current-ply (chess-game-ply game))
(changes (chess-ply-changes ply)))
- (assert (equal (chess-ply-pos current-ply) (chess-ply-pos ply)))
+ (unless (equal (chess-ply-pos current-ply)
+ (chess-ply-pos ply))
+ (error "Positions do not match"))
+ (funcall (chess-game-validation-func game) ply)
(chess-ply-set-changes current-ply changes)
(cond
((or (memq ':draw changes)
(chess-game-set-tag game "Result" "1/2-1/2"))
((or (memq ':resign changes)
(memq ':checkmate changes))
- (chess-game-set-tag game "Result"
- (if (chess-game-side-to-move game)
- "0-1" "1-0")))
- (t (nconc (cdr game)
- (list (chess-ply-create
- (chess-ply-next-pos current-ply))))))))
+ (chess-game-set-tag game "Result" (if (chess-game-side-to-move game)
+ "0-1" "1-0")))
+ (t
+ (chess-game-add-ply game (chess-ply-create
+ (chess-ply-next-pos current-ply)))))))
+
+;; A few convenience functions
+
+(defsubst chess-game-legal-plies (game)
+ "Return all legal plies from GAME's current position."
+ (chess-legal-plies (chess-game-pos game)
+ (chess-game-search-func game)))
+
+(defsubst chess-game-algebraic-to-ply (game move)
+ (chess-algebraic-to-ply (chess-game-pos game) move
+ (chess-game-search-func game)))
+
+(defsubst chess-game-ply-to-algebraic (game &optional ply long)
+ (chess-ply-to-algebraic (or ply (chess-game-ply game)) long
+ (chess-game-search-func game)))
(provide 'chess-game)
+++ /dev/null
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Play against the gnuchess engine
-;;
-;; $Revision$
-
-(require 'chess-process)
-
-(defgroup chess-gnuchess nil
- "Interface code for playing against gnuchess. Uses `chess-process'."
- :group 'chess)
-
-(defcustom chess-gnuchess-command (and (require 'executable)
- (executable-find "gnuchess"))
- "The name of the gnuchess program."
- :type 'string
- :group 'chess-gnuchess)
-
-;;;###autoload
-(defun chess-gnuchess (session buffer event &rest args)
- (if (not (eq event 'initialize))
- (apply 'chess-process session buffer event args)
- (chess-process session buffer event
- (list (list
- (concat "My move is : \\("
- chess-algebraic-regexp "\\)")
- (function
- (lambda (move)
- (chess-session-event
- chess-current-session 'move
- (chess-algebraic-to-ply
- (chess-game-pos chess-process-game) move)))) 1)
- '("Illegal move:" (error "Illegal move")))
- chess-gnuchess-command)))
-
-(provide 'chess-gnuchess)
-
-;;; chess-gnuchess.el ends here
((looking-at chess-algebraic-regexp)
(goto-char (match-end 0))
(setq prevpos position)
- (let ((ply (chess-algebraic-to-ply position (match-string 0))))
+ (let ((ply (chess-game-algebraic-to-ply game (match-string 0))))
(setq position (chess-ply-next-pos ply))
(nconc plies (list ply))))
((and top-level
(chess-pos-copy chess-starting-position)) t)))
game)))
-(defun chess-pgn-insert-annotations (index ply)
+(defun chess-pgn-insert-annotations (game index ply)
(dolist (ann (chess-pos-annotations (chess-ply-pos ply)))
(if (stringp ann)
(insert (format " {%s}" ann))
(assert (listp ann))
- (chess-pgn-insert-plies index ann))))
+ (chess-pgn-insert-plies game index ann))))
-(defun chess-pgn-insert-plies (index plies &optional
+(defun chess-pgn-insert-plies (game index plies &optional
for-black indented no-annotations)
"NYI: Still have to implement INDENTED argument."
(while plies
(unless for-black
(insert (format "%d. %s" index
- (chess-ply-to-algebraic (car plies))))
+ (chess-game-ply-to-algebraic game (car plies))))
(unless no-annotations
- (chess-pgn-insert-annotations index (car plies)))
+ (chess-pgn-insert-annotations game index (car plies)))
(setq plies (cdr plies) index (1+ index)))
(when plies
(when for-black
(insert (format "%d. ..." index))
(setq for-black nil))
- (insert (format " %s" (chess-ply-to-algebraic (car plies))))
+ (insert (format " %s" (chess-game-ply-to-algebraic game (car plies))))
(unless no-annotations
- (chess-pgn-insert-annotations index (car plies)))
+ (chess-pgn-insert-annotations game index (car plies)))
(setq plies (cdr plies)))
(if plies
(insert ? ))))
(insert (format "[%s \"%s\"]\n" (car tag) (cdr tag))))
(insert ?\n)
(let ((begin (point)))
- (chess-pgn-insert-plies 1 (chess-game-plies game))
+ (chess-pgn-insert-plies game 1 (chess-game-plies game))
(insert (or (chess-game-tag game "Result") "*") ?\n)
(fill-region begin (point))))
;; PGN-mode for editing and browsing PGN files.
;;
-(defvar chess-pgn-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [??] 'describe-mode)
- (define-key map [?T] 'text-mode)
- (define-key map [return] 'chess-pgn-move)
- (define-key map [(control ?m)] 'chess-pgn-move)
- map)
- "Keymap used by Chess PGN mode.")
-
-(define-derived-mode chess-pgn-mode text-mode "Chess"
- "A mode for editing Chess PGN files.")
-
-(defun chess-pgn-move ()
- "Make a move from a PGN buffer."
- (interactive)
- (let ((end (point))
- coords move)
- (save-excursion
- (skip-chars-backward "^ ")
- (setq move (buffer-substring-no-properties (point) end)
- coords (chess-algebraic-to-ply chess-display-position move))
- ;; it will just get reinserted again
- (delete-region (point) end))
- (chess-session-event chess-current-session 'move
- (chess-algebraic-to-ply chess-display-position))))
-
-(defun chess-pgn-insert-move (move &optional color sequence)
- "Insert an algebraic move description into a PGN buffer.
-If move is the symbol `wait', it means reflect that we are now waiting
-for the opponent to make his move. If move is the symbol `ready', it
-means our opponent is now waiting for us to move our move. Otherwise,
-move should be a string representing the algebraic notation for the
-move."
- (while (= (char-before) ?.)
- (delete-backward-char 1))
- (cond
- ((eq move 'wait)
- (insert "..."))
- ((eq move 'ready) t)
- (t
- (if (= (char-syntax (char-before)) ? )
- (insert move))
- (if color
- (move-to-column 11 t)
- (insert ?\n (format "%d. " (1+ sequence))))))
- (let ((wind (get-buffer-window (current-buffer))))
- (if wind
- (set-window-point wind (point)))))
+;; (defvar chess-pgn-mode-map
+;; (let ((map (make-sparse-keymap)))
+;; (define-key map [??] 'describe-mode)
+;; (define-key map [?T] 'text-mode)
+;; (define-key map [return] 'chess-pgn-move)
+;; (define-key map [(control ?m)] 'chess-pgn-move)
+;; map)
+;; "Keymap used by Chess PGN mode.")
+;;
+;; (define-derived-mode chess-pgn-mode text-mode "Chess"
+;; "A mode for editing Chess PGN files.")
+;;
+;; (defun chess-pgn-move ()
+;; "Make a move from a PGN buffer."
+;; (interactive)
+;; (let ((end (point))
+;; coords move)
+;; (save-excursion
+;; (skip-chars-backward "^ ")
+;; (setq move (buffer-substring-no-properties (point) end)
+;; coords (chess-algebraic-to-ply chess-display-position move))
+;; ;; it will just get reinserted again
+;; (delete-region (point) end))
+;; (chess-session-event chess-current-session 'move
+;; (chess-algebraic-to-ply chess-display-position))))
+;;
+;; (defun chess-pgn-insert-move (move &optional color sequence)
+;; "Insert an algebraic move description into a PGN buffer.
+;; If move is the symbol `wait', it means reflect that we are now waiting
+;; for the opponent to make his move. If move is the symbol `ready', it
+;; means our opponent is now waiting for us to move our move. Otherwise,
+;; move should be a string representing the algebraic notation for the
+;; move."
+;; (while (= (char-before) ?.)
+;; (delete-backward-char 1))
+;; (cond
+;; ((eq move 'wait)
+;; (insert "..."))
+;; ((eq move 'ready) t)
+;; (t
+;; (if (= (char-syntax (char-before)) ? )
+;; (insert move))
+;; (if color
+;; (move-to-column 11 t)
+;; (insert ?\n (format "%d. " (1+ sequence))))))
+;; (let ((wind (get-buffer-window (current-buffer))))
+;; (if wind
+;; (set-window-point wind (point)))))
(provide 'chess-pgn)
;;; Code:
(require 'chess-pos)
+(require 'chess-standard)
(defgroup chess-ply nil
"Routines for manipulating chess plies."
(defsubst chess-ply-create (position &rest changes)
(cons position changes))
-(defun chess-legal-plies (position color)
- "Return a list of all legal plies in POSITION for COLOR."
+(defun chess-legal-plies (position &optional search-func)
+ "Return a list of all legal plies in POSITION."
(let (plies)
(dotimes (rank 8)
(dotimes (file 8)
(let* ((to (chess-rf-to-index rank file))
(piece (chess-pos-piece position to)))
(when (or (eq piece ? )
- (if color
+ (if (chess-pos-side-to-move position)
(> piece ?a)
(< piece ?a)))
- (dolist (candidate (funcall (car chess-modules)
- nil nil 'search position to t))
+ (dolist (candidate (funcall (or search-func
+ chess-standard-search)
+ position to t))
(push (chess-ply-create position candidate to)
plies))))))
plies))
(make-variable-buffer-local 'chess-process-last-pos)
(make-variable-buffer-local 'chess-process-working)
-(defvar chess-process-triggers
- (list (list
- (concat "\\s-*\\(white\\|black\\)\\s-*([0-9]+):\\s-+\\("
- chess-algebraic-regexp "\\)\\s-*$")
- (function
- (lambda (color move)
- (if (if (chess-game-side-to-move chess-process-game)
- (string= (downcase color) "white")
- (string= (downcase color) "black"))
- (chess-session-event
- chess-current-session 'move
- (chess-algebraic-to-ply
- (chess-game-pos chess-process-game) move)))))
- 1 2)
- '(".*illegal move:\\s-*\\(.*\\)"
- (signal 'chess-illegal (match-string 1)))
- '(".+?\015" (replace-match "")))
+(defvar chess-process-triggers nil
"A list of regexps and the commands that they trigger.
The alist should be of the form:
(set-process-filter proc 'chess-process-filter))
buf)))
((eq event 'shutdown)
- (when (buffer-live-p buffer)
- (ignore-errors
- (process-send-string (get-buffer-process buffer) "quit\n"))
- (kill-buffer buffer)))
+ (if (buffer-live-p buffer)
+ (kill-buffer buffer)))
(t
(ignore
(with-current-buffer buffer
- (let (cmdstr)
- (cond
- ((eq event 'setup)
- (setq chess-process-game (car args)
- chess-process-last-pos (point-min)))
- ((eq event 'move)
- (setq cmdstr (concat (chess-ply-to-algebraic (car args)) "\n")))
- ((eq event 'pass)
- (setq cmdstr "go\n")))
- (if (and cmdstr (not chess-process-working))
- (process-send-string (get-buffer-process (current-buffer))
- cmdstr))))))))
+ (cond
+ ((eq event 'setup)
+ (setq chess-process-game (car args)
+ chess-process-last-pos (point-min)))))))))
(defun chess-process-filter (proc string)
"Process filter for receiving text from a chess process."
(setq chess-process-last-pos (point)
chess-process-working nil)))))))
+(defun chess-process-let (forms)
+ `(let ((str (progn ,@forms)))
+ (if (stringp str)
+ (ignore
+ (process-send-string (get-buffer-process (current-buffer))
+ (concat str "\n")))
+ str)))
+
+(defun chess-process-insert-forms (event)
+ (if (assq event forms)
+ (chess-process-let
+ (prog1
+ (cdr (assq event forms))
+ (setq forms (assq-delete-all event forms))))))
+
+(defmacro define-chess-engine (name ignored triggers &rest forms)
+ "Define a chess engine.
+NAME is an unquoted symbol name that denotes the engine. This name is
+used as the default string for the chess engine's external command
+name.
+TRIGGERS is a list of process triggers, which fire when the output
+from the process matches certain regexps. See
+`chess-process-triggers' for more information.
+FORMS is an alist of event symbols, and forms to evaluate when such an
+event is received by the module. If these forms return a string, this
+string will be sent to the engine process.
+See the file chess-engines.el for code examples."
+ (let ((namestr (symbol-name name)))
+ `(progn
+ (defcustom ,(intern (concat "chess-" namestr "-command"))
+ (and (require 'executable)
+ (executable-find ,namestr))
+ ,(concat "The name of the " namestr " program.")
+ :type 'file
+ :group 'chess-process)
+
+ (defun ,(intern (concat "chess-" namestr))
+ (session buffer event &rest args)
+ (cond
+ ((eq event 'initialize)
+ (with-current-buffer
+ (chess-process session buffer event ,triggers
+ ,(intern (concat "chess-" namestr "-command")))
+ ,(chess-process-insert-forms 'init)
+ (current-buffer)))
+ ((eq event 'shutdown)
+ (when (buffer-live-p buffer)
+ (ignore-errors
+ ,(chess-process-insert-forms 'shutdown))
+ (kill-buffer buffer)))
+ (t
+ (ignore
+ (with-current-buffer buffer
+ (cond
+ ((eq event 'setup)
+ (apply 'chess-process session buffer event args)
+ ,(chess-process-insert-forms 'setup))
+ ,@(mapcar
+ (function
+ (lambda (entry)
+ `((eq event (quote ,(car entry)))
+ ,(chess-process-let (cdr entry))))) forms)
+ (t
+ (apply 'chess-process session buffer event args)))))))))))
+
(provide 'chess-process)
;;; chess-process.el ends here
(setq listeners (cdr listeners)))
result))
+;; (define-chess-module MODULE (&rest args))
+;; (define-chess-module (MODULE BASES...) (&rest args)
+;; :ctor-args (ARGS...)
+;; :create-buffer
+;; (EVENT
+;; FORMS...)
+;; ...)
+;;
+;; (chess-call-derived args &optional base-module)
+
(provide 'chess-session)
;;; chess-session.el ends here
;; $Revision$
-(require 'chess-session)
-(require 'chess-pos)
-(require 'chess-ply)
-(require 'chess-game)
-
(defgroup chess-standard nil
"The rules of standard chess."
:group 'chess)
;;; Code:
-;;;###autoload
-(defun chess-standard (session var event &rest args)
- (cond
- ((eq event 'move)
- (ignore
- (chess-standard-validate (car args))
- (chess-game-move (chess-session-data session 'current-game)
- (car args))))
- ((eq event 'search)
- (apply 'chess-standard-search args))))
-
(defun chess-standard-validate (ply)
"Validate the given PLY against standard chess rules."
(let* ((pos (chess-ply-pos ply))
(defconst chess-version "2.0a7"
"The version of the Emacs chess program.")
(defcustom chess-modules
- (list 'chess-standard 'chess-crafty
+ (list 'chess-crafty
(if (display-graphic-p)
'chess-images 'chess-ascii))
- "Default module set to be used when starting a chess session.
-Any rules modules, if they are being used, must appear first in this
-list! This usually means `chess-standard' must be the very first
-entry."
+ 'chess-images 'chess-ics1)
:type (list 'radio (apropos-internal "\\`chess-[^-]+\\'" 'functionp))
:type 'sexp
:group 'chess)