]> code.delx.au - gnu-emacs-elpa/blob - chess.el
Add a sentence about chess-network to package long description.
[gnu-emacs-elpa] / chess.el
1 ;;; chess.el --- Play chess in Emacs
2
3 ;; Copyright (C) 2001, 2014 Free Software Foundation, Inc.
4
5 ;; Emacs Lisp Archive Entry
6 ;; Filename: chess.el
7 ;; Version: 0
8 ;; Package-Requires: ((cl-lib "0.5"))
9 ;; Keywords: games
10 ;; Author: John Wiegley <johnw@gnu.org>
11 ;; Maintainer: Mario Lang <mlang@delysid.org>
12 ;; Description: Play chess in Emacs
13 ;; URL: https://github.com/jwiegley/emacs-chess/
14 ;; Compatibility: Emacs24
15
16 ;; This program is free software; you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation, either version 3 of the License, or
19 ;; (at your option) any later version.
20
21 ;; This program is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
25
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
28
29 ;;; Commentary:
30
31 ;; Welcome to Emacs Chess, a chess playing module for GNU Emacs.
32 ;;
33 ;; chess.el is an Emacs Lisp library and several clients on top of the
34 ;; underlying library functionality for performing various activities
35 ;; related to the game of chess.
36 ;;
37 ;; Type `M-x chess', and play chess against one of the default engine modules.
38 ;;
39 ;; Type `C-u M-x chess' to select a specific engine.
40 ;; You can play against various external chess computer programs, like
41 ;; crafty, fruit, glaurung, gnuchess, phalanx, sjeng and stockfish.
42 ;; There is also an Emacs based chess computer module (ai) which does not
43 ;; require any external programs. However, the internal AI is not very strong.
44 ;;
45 ;; To play against another human on a different machine running GNU Emacs,
46 ;; type `C-u M-x chess RET network RET'.
47 ;; To play on one of the internet chess servers, type `M-x chess-ics'.
48 ;;
49 ;; If you'd like to view or edit Portable Game Notation (PGN) files,
50 ;; `chess-pgn-mode' provides a text-mode derived mode which can display the
51 ;; chess position at point.
52 ;;
53 ;; To improve your chessaility, `M-x chess-tutorial' provides a simple knight
54 ;; movement exercise to get you started, and `M-x chess-puzzle' can be used
55 ;; to solve puzzle collections in EPD or PGN format.
56 ;;
57 ;; There are some different types of chessboard display modules available.
58 ;; * A simple character based display (chess-plain).
59 ;; * A more verbose ASCII chessboard (chess-ics1).
60 ;; * A graphical chessboard display which uses images (chess-images).
61 ;;
62 ;; The variable `chess-default-display' controls which display modules
63 ;; are tried when a chessboard should be displayed. By default, chess-images
64 ;; is tried first. If Emacs is not running in a graphical environment,
65 ;; chess-ics1 is used instead. To enable the chess-plain display module,
66 ;; customize `chess-default-display' accordingly.
67 ;;
68 ;; Once this is working, the next thing to do is to customize
69 ;; `chess-default-modules'. This is a list of functionality modules used
70 ;; by chess.el to provide additional functionality. You can enable or
71 ;; disable modules so that Emacs Chess better suites your tastes.
72 ;; Those modules in turn often have configuration variables, and
73 ;; appropriate documentation at the top of the related file.
74 ;;
75 ;; Emacs Chess is designed in a highly modular fashion, using loosely
76 ;; coupled modules that respond to events on the chess board. This
77 ;; makes it very easy for programmers to add their own types of
78 ;; displays, opponents, analysis programs, etc. See the documentation
79 ;; in chess-module.el to learn more.
80 ;;
81 ;; Most people will probably also be interested in reading the top
82 ;; of chess-display.el and chess-pgn.el, which describe the user
83 ;; interface commands available in each of those buffer types.
84
85 ;;; Code:
86
87 (require 'chess-game)
88 (require 'chess-display)
89 (require 'chess-engine)
90
91 (defgroup chess nil
92 "An Emacs chess playing program."
93 :group 'games)
94
95 (defconst chess-version "2.0b6"
96 "The version of the Emacs chess program.")
97
98 (defcustom chess-default-display
99 '(chess-images chess-ics1 chess-plain)
100 "Default display to be used when starting a chess session.
101 A list indicates a series of alternatives if the first display is
102 not available."
103 :type '(choice symbol (repeat symbol))
104 :group 'chess)
105
106 (defcustom chess-default-modules
107 '((chess-sound chess-announce)
108 chess-autosave
109 chess-clock
110 ;;chess-kibitz jww (2002-04-30): not fully supported yet
111 ;;chess-chat
112 )
113 "Modules to be used when starting a chess session.
114 A sublist indicates a series of alternatives, if the first is not
115 available.
116 These can do just about anything."
117 :type '(repeat (choice symbol (repeat symbol)))
118 :group 'chess)
119
120 (defcustom chess-default-engine
121 '(chess-crafty
122 chess-stockfish chess-glaurung chess-fruit
123 chess-gnuchess chess-phalanx
124 chess-ai)
125 "Default engine to be used when starting a chess session.
126 A list indicates a series of alternatives if the first engine is not
127 available."
128 :type '(choice symbol (repeat symbol))
129 :group 'chess)
130
131 (defcustom chess-full-name (user-full-name)
132 "The full name to use when playing chess."
133 :type 'string
134 :group 'chess)
135
136 (and (fboundp 'font-lock-add-keywords)
137 (font-lock-add-keywords
138 'emacs-lisp-mode
139 '(("(\\(chess-error\\)\\>" 1 font-lock-warning-face)
140 ("(\\(chess-with-current-buffer\\)\\>" 1 font-lock-keyword-face))))
141
142 (defun chess--create-display (module game my-color disable-popup)
143 (let ((display (chess-display-create game module my-color)))
144 (when display
145 (chess-game-set-data game 'my-color my-color)
146 (if disable-popup
147 (chess-display-disable-popup display))
148 display)))
149
150 (defun chess--create-engine (module game response-handler ctor-args)
151 (let ((engine (apply 'chess-engine-create module game
152 response-handler ctor-args)))
153 (when engine
154 ;; for the sake of engines which are ready to play now, and
155 ;; which don't need connect/accept negotiation (most
156 ;; computerized engines fall into this category), we need to
157 ;; let them know we're ready to begin
158 (chess-engine-command engine 'ready)
159 engine)))
160
161 (defun chess-create-modules (module-list create-func &rest args)
162 "Create modules from MODULE-LIST with CREATE-FUNC and ARGS.
163 If an element of MODULE-LIST is a sublist, treat it as alternatives."
164 (let (objects)
165 (dolist (module module-list)
166 (let (object)
167 (if (symbolp module)
168 (if (setq object (apply create-func module args))
169 (push object objects))
170 ;; this module is actually a list, which means keep trying
171 ;; until we find one that works
172 (while module
173 (if (setq object (condition-case nil
174 (apply create-func (car module) args)
175 (error nil)))
176 (progn
177 (push object objects)
178 (setq module nil))
179 (setq module (cdr module)))))))
180 (nreverse objects)))
181
182 (chess-message-catalog 'english
183 '((no-engines-found
184 . "Could not find any chess engines to play against; install gnuchess!")))
185
186 ;;;###autoload
187 (defun chess (&optional engine disable-popup engine-response-handler
188 &rest engine-ctor-args)
189 "Start a game of chess, playing against ENGINE (a module name).
190 With prefix argument, prompt for the engine to play against.
191 Otherwise use `chess-default-engine' to determine the engine."
192 (interactive
193 (list
194 (if current-prefix-arg
195 (intern
196 (concat "chess-"
197 (let ((str (read-string "Engine to play against: ")))
198 (if (> (length str) 0)
199 str
200 "none"))))
201 chess-default-engine)))
202
203 (let ((game (chess-game-create))
204 (my-color t) ; we start out as white always
205 objects)
206
207 ;; all these odd calls are so that `objects' ends up looking like:
208 ;; (ENGINE FIRST-DISPLAY...)
209
210 (setq objects (chess-create-modules (list chess-default-display)
211 'chess--create-display
212 game my-color disable-popup))
213 (when (car objects)
214 (mapc 'chess-display-update objects)
215 (chess-module-set-leader (car objects))
216 (unless disable-popup
217 (chess-display-popup (car objects))))
218
219 (nconc objects (chess-create-modules chess-default-modules
220 'chess-module-create game))
221
222 (push (unless (eq engine 'none)
223 (car ;(condition-case nil
224 (chess-create-modules (list (or engine chess-default-engine))
225 'chess--create-engine game
226 engine-response-handler
227 engine-ctor-args)
228 ; (error nil))
229 ))
230 objects)
231
232 (unless (car objects)
233 (chess-message 'no-engines-found))
234
235 objects))
236
237 ;;;###autoload
238 (defalias 'chess-session 'chess)
239
240 ;;;###autoload
241 (defun chess-create-display (perspective &optional modules-too)
242 "Create a display, letting the user's customization decide the style.
243 If MODULES-TOO is non-nil, also create and associate the modules
244 listed in `chess-default-modules'."
245 (if modules-too
246 (let ((display (cadr (chess-session 'none))))
247 (chess-display-set-perspective* display perspective))
248 (car (chess-create-modules (list chess-default-display)
249 'chess--create-display
250 (chess-game-create) perspective nil))))
251
252 (provide 'chess)
253
254 ;;; chess.el ends here