Mercurial > emacs
annotate lisp/play/bubbles.el @ 106717:15eb515afd85
* net/browse-url.el (browse-url-encode-url): Don't escape commas.
They are valid characters in URL paths (rfc3986), and at least
Firefox does not understand the encoded version (Bug#3166).
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Sat, 02 Jan 2010 15:14:54 -0500 |
parents | 602967a46594 |
children | 1d1d5d9bd884 |
rev | line source |
---|---|
82921 | 1 ;;; bubbles.el --- Puzzle game for Emacs. |
2 | |
100908 | 3 ;; Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. |
82921 | 4 |
5 ;; Author: Ulf Jasper <ulf.jasper@web.de> | |
6 ;; URL: http://ulf.epplejasper.de/ | |
7 ;; Created: 5. Feb. 2007 | |
82922
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
8 ;; Keywords: games |
82921 | 9 |
82922
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
10 ;; This file is part of GNU Emacs. |
82921 | 11 |
94675
949bd6ad1ba4
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87665
diff
changeset
|
12 ;; GNU Emacs is free software: you can redistribute it and/or modify |
82921 | 13 ;; it under the terms of the GNU General Public License as published by |
94675
949bd6ad1ba4
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87665
diff
changeset
|
14 ;; the Free Software Foundation, either version 3 of the License, or |
949bd6ad1ba4
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87665
diff
changeset
|
15 ;; (at your option) any later version. |
82921 | 16 |
82922
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
17 ;; GNU Emacs is distributed in the hope that it will be useful, |
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
20 ;; GNU General Public License for more details. |
82921 | 21 |
22 ;; You should have received a copy of the GNU General Public License | |
94675
949bd6ad1ba4
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87665
diff
changeset
|
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
82921 | 24 |
25 ;;; Commentary: | |
26 | |
27 ;; Bubbles is a puzzle game. Its goal is to remove as many bubbles as | |
28 ;; possible in as few moves as possible. | |
29 | |
30 ;; Bubbles is an implementation of the "Same Game", similar to "Same | |
82922
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
31 ;; GNOME" and many others, see <http://en.wikipedia.org/wiki/SameGame>. |
82921 | 32 |
33 ;; Installation | |
34 ;; ------------ | |
35 | |
36 ;; Add the following lines to your Emacs startup file (`~/.emacs'). | |
37 ;; (add-to-list 'load-path "/path/to/bubbles/") | |
38 ;; (autoload 'bubbles "bubbles" "Play Bubbles" t) | |
39 | |
40 ;; ====================================================================== | |
41 | |
42 ;;; History: | |
43 | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
44 ;; 0.5 (2007-09-14) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
45 ;; - Minor bugfixes. |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
46 |
82921 | 47 ;; 0.4 (2007-08-27) |
48 ;; - Allow for undoing last move. | |
49 ;; - Bonus for removing all bubbles. | |
50 ;; - Speed improvements. | |
51 ;; - Animation enhancements. | |
52 ;; - Added `bubbles-mode-hook'. | |
53 ;; - Fixes: Don't move point. | |
54 ;; - New URL. | |
55 | |
56 ;; 0.3 (2007-03-11) | |
57 ;; - Renamed shift modes and thus names of score files. All | |
58 ;; highscores are lost, unless you rename the score files from | |
59 ;; bubbles-shift-... to bubbles-...! | |
60 ;; - Bugfixes: Check for successful image creation. | |
61 ;; Disable menus and counter when game is over. | |
62 ;; Tested with GNU Emacs 22.0.93 | |
63 | |
64 ;; 0.2 (2007-02-24) | |
65 ;; - Introduced game themes. | |
66 ;; - Introduced graphics themes (changeable while playing). | |
67 ;; - Added menu. | |
68 ;; - Customization: grid size, colors, chars, shift mode. | |
69 ;; - More keybindings. | |
70 ;; - Changed shift direction from to-right to to-left. | |
71 ;; - Bugfixes: Don't remove single-bubble regions; | |
72 ;; Animation glitches fixed. | |
73 ;; Tested with GNU Emacs 22.0.93 and 21.4.1. | |
74 | |
75 ;; 0.1 (2007-02-11) | |
76 ;; Initial release. Tested with GNU Emacs 22.0.93 and 21.4.1. | |
77 | |
78 ;; ====================================================================== | |
79 | |
80 ;;; Code: | |
81 | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
82 (defconst bubbles-version "0.5" "Version number of bubbles.el.") |
82922
16c56e4babd8
Comments munging; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82921
diff
changeset
|
83 |
82921 | 84 (require 'gamegrid) |
104579
602967a46594
(top-level): Don't require cl at run-time.
Glenn Morris <rgm@gnu.org>
parents:
102731
diff
changeset
|
85 (eval-when-compile (require 'cl)) ; for 'case |
82921 | 86 |
87 ;; User options | |
88 | |
89 ;; Careful with that axe, Eugene! Order does matter in the custom | |
90 ;; section below. | |
91 | |
92 (defcustom bubbles-game-theme | |
93 'easy | |
94 "Overall game theme. | |
95 The overall game theme specifies a grid size, a set of colors, | |
96 and a shift mode." | |
97 :type '(radio (const :tag "Easy" easy) | |
98 (const :tag "Medium" medium) | |
99 (const :tag "Difficult" difficult) | |
100 (const :tag "Hard" hard) | |
101 (const :tag "User defined" user-defined)) | |
102 :group 'bubbles) | |
103 | |
104 (defun bubbles-set-game-easy () | |
105 "Set game theme to 'easy'." | |
106 (interactive) | |
107 (setq bubbles-game-theme 'easy) | |
108 (bubbles)) | |
109 | |
110 (defun bubbles-set-game-medium () | |
111 "Set game theme to 'medium'." | |
112 (interactive) | |
113 (setq bubbles-game-theme 'medium) | |
114 (bubbles)) | |
115 | |
116 (defun bubbles-set-game-difficult () | |
117 "Set game theme to 'difficult'." | |
118 (interactive) | |
119 (setq bubbles-game-theme 'difficult) | |
120 (bubbles)) | |
121 | |
122 (defun bubbles-set-game-hard () | |
123 "Set game theme to 'hard'." | |
124 (interactive) | |
125 (setq bubbles-game-theme 'hard) | |
126 (bubbles)) | |
127 | |
128 (defun bubbles-set-game-userdefined () | |
129 "Set game theme to 'user-defined'." | |
130 (interactive) | |
131 (setq bubbles-game-theme 'user-defined) | |
132 (bubbles)) | |
133 | |
134 (defgroup bubbles nil | |
135 "Bubbles, a puzzle game." | |
136 :group 'games) | |
137 | |
138 (defcustom bubbles-graphics-theme | |
139 'circles | |
140 "Graphics theme. | |
141 It is safe to choose a graphical theme. If Emacs cannot display | |
142 images the `ascii' theme will be used." | |
143 :type '(radio (const :tag "Circles" circles) | |
144 (const :tag "Squares" squares) | |
145 (const :tag "Diamonds" diamonds) | |
146 (const :tag "Balls" balls) | |
147 (const :tag "Emacs" emacs) | |
148 (const :tag "ASCII (no images)" ascii)) | |
149 :group 'bubbles) | |
150 | |
151 (defconst bubbles--grid-small '(10 . 10) | |
152 "Predefined small bubbles grid.") | |
153 | |
154 (defconst bubbles--grid-medium '(15 . 10) | |
155 "Predefined medium bubbles grid.") | |
156 | |
157 (defconst bubbles--grid-large '(20 . 15) | |
158 "Predefined large bubbles grid.") | |
159 | |
160 (defconst bubbles--grid-huge '(30 . 20) | |
161 "Predefined huge bubbles grid.") | |
162 | |
163 (defcustom bubbles-grid-size | |
164 bubbles--grid-medium | |
165 "Size of bubbles grid." | |
166 :type `(radio (const :tag "Small" ,bubbles--grid-small) | |
167 (const :tag "Medium" ,bubbles--grid-medium) | |
168 (const :tag "Large" ,bubbles--grid-large) | |
169 (const :tag "Huge" ,bubbles--grid-huge) | |
170 (cons :tag "User defined" | |
171 (integer :tag "Width") | |
172 (integer :tag "Height"))) | |
173 :group 'bubbles) | |
174 | |
175 (defconst bubbles--colors-2 '("orange" "violet") | |
176 "Predefined bubbles color list with two colors.") | |
177 | |
178 (defconst bubbles--colors-3 '("lightblue" "palegreen" "pink") | |
179 "Predefined bubbles color list with three colors.") | |
180 | |
181 (defconst bubbles--colors-4 '("firebrick" "sea green" "steel blue" "chocolate") | |
182 "Predefined bubbles color list with four colors.") | |
183 | |
184 (defconst bubbles--colors-5 '("firebrick" "sea green" "steel blue" | |
185 "sandy brown" "bisque3") | |
186 "Predefined bubbles color list with five colors.") | |
187 | |
188 (defcustom bubbles-colors | |
189 bubbles--colors-3 | |
190 "List of bubble colors. | |
191 The length of this list determines how many different bubble | |
192 types are present." | |
193 :type `(radio (const :tag "Red, darkgreen" ,bubbles--colors-2) | |
194 (const :tag "Red, darkgreen, blue" ,bubbles--colors-3) | |
195 (const :tag "Red, darkgreen, blue, orange" ,bubbles--colors-4) | |
196 (const :tag "Red, darkgreen, blue, orange, violet" | |
197 ,bubbles--colors-5) | |
198 (repeat :tag "User defined" color)) | |
199 :group 'bubbles) | |
200 | |
201 (defcustom bubbles-chars | |
202 '(?+ ?O ?# ?X ?. ?* ?& ?§) | |
203 "Characters used for bubbles. | |
204 Note that the actual number of different bubbles is determined by | |
205 the number of colors, see `bubbles-colors'." | |
206 :type '(repeat character) | |
207 :group 'bubbles) | |
208 | |
209 (defcustom bubbles-shift-mode | |
210 'default | |
211 "Shift mode. | |
99902
19d0410ccdd2
* play/bubbles.el (bubbles-mode): Define with `define-derived-mode'.
Juanma Barranquero <lekktu@gmail.com>
parents:
96463
diff
changeset
|
212 Available modes are `shift-default' and `shift-always'." |
82921 | 213 :type '(radio (const :tag "Default" default) |
214 (const :tag "Shifter" always) | |
215 ;;(const :tag "Mega Shifter" 'mega) | |
216 ) | |
217 :group 'bubbles) | |
218 | |
219 (defcustom bubbles-mode-hook nil | |
220 "Hook run by Bubbles mode." | |
221 :group 'bubbles | |
222 :type 'hook) | |
223 | |
224 (defun bubbles-customize () | |
225 "Open customization buffer for bubbles." | |
226 (interactive) | |
227 (customize-group 'bubbles)) | |
228 | |
229 ;; ====================================================================== | |
230 ;; internal variables | |
231 | |
232 (defvar bubbles--score 0 | |
233 "Current Bubbles score.") | |
234 | |
235 (defvar bubbles--neighbourhood-score 0 | |
96463
ce09add00a57
American English spelling fixes.
Glenn Morris <rgm@gnu.org>
parents:
95841
diff
changeset
|
236 "Score of active bubbles neighborhood.") |
82921 | 237 |
238 (defvar bubbles--faces nil | |
239 "List of currently used faces.") | |
240 | |
241 (defvar bubbles--playing nil | |
242 "Play status indicator.") | |
243 | |
244 (defvar bubbles--empty-image nil | |
245 "Image used for removed bubbles (empty grid cells).") | |
246 | |
247 (defvar bubbles--images nil | |
248 "List of images for bubbles.") | |
249 | |
250 (defvar bubbles--images-ok nil | |
251 "Indicate whether images have been created successfully.") | |
252 | |
253 (defvar bubbles--col-offset 0 | |
254 "Horizontal offset for centering the bubbles grid.") | |
255 | |
256 (defvar bubbles--row-offset 0 | |
257 "Vertical offset for centering the bubbles grid.") | |
258 | |
259 (defvar bubbles--save-data nil | |
260 "List containing bubbles save data (SCORE BUFFERCONTENTS).") | |
261 | |
262 (defconst bubbles--image-template-circle | |
263 "/* XPM */ | |
264 static char * dot_xpm[] = { | |
265 \"20 20 2 1\", | |
266 \" c None\", | |
267 \". c #FFFFFF\", | |
268 \" ...... \", | |
269 \" .......... \", | |
270 \" .............. \", | |
271 \" ................ \", | |
272 \" ................ \", | |
273 \" .................. \", | |
274 \" .................. \", | |
275 \"....................\", | |
276 \"....................\", | |
277 \"....................\", | |
278 \"....................\", | |
279 \"....................\", | |
280 \"....................\", | |
281 \" .................. \", | |
282 \" .................. \", | |
283 \" ................ \", | |
284 \" ................ \", | |
285 \" .............. \", | |
286 \" .......... \", | |
287 \" ...... \"};") | |
288 | |
289 (defconst bubbles--image-template-square | |
290 "/* XPM */ | |
291 static char * dot_xpm[] = { | |
292 \"20 20 2 1\", | |
293 \"0 c None\", | |
294 \"1 c #FFFFFF\", | |
295 \"00000000000000000000\", | |
296 \"01111111111111111110\", | |
297 \"01111111111111111110\", | |
298 \"01111111111111111110\", | |
299 \"01111111111111111110\", | |
300 \"01111111111111111110\", | |
301 \"01111111111111111110\", | |
302 \"01111111111111111110\", | |
303 \"01111111111111111110\", | |
304 \"01111111111111111110\", | |
305 \"01111111111111111110\", | |
306 \"01111111111111111110\", | |
307 \"01111111111111111110\", | |
308 \"01111111111111111110\", | |
309 \"01111111111111111110\", | |
310 \"01111111111111111110\", | |
311 \"01111111111111111110\", | |
312 \"01111111111111111110\", | |
313 \"01111111111111111110\", | |
314 \"00000000000000000000\"};") | |
315 | |
316 (defconst bubbles--image-template-diamond | |
317 "/* XPM */ | |
318 static char * dot_xpm[] = { | |
319 \"20 20 2 1\", | |
320 \"0 c None\", | |
321 \"1 c #FFFFFF\", | |
322 \"00000000011000000000\", | |
323 \"00000000111100000000\", | |
324 \"00000001111110000000\", | |
325 \"00000011111111000000\", | |
326 \"00000111111111100000\", | |
327 \"00001111111111110000\", | |
328 \"00011111111111111000\", | |
329 \"00111111111111111100\", | |
330 \"01111111111111111110\", | |
331 \"11111111111111111111\", | |
332 \"01111111111111111110\", | |
333 \"00111111111111111100\", | |
334 \"00011111111111111000\", | |
335 \"00001111111111110000\", | |
336 \"00000111111111100000\", | |
337 \"00000011111111000000\", | |
338 \"00000001111110000000\", | |
339 \"00000000111100000000\", | |
340 \"00000000011000000000\", | |
341 \"00000000000000000000\"};") | |
342 | |
343 (defconst bubbles--image-template-emacs | |
344 "/* XPM */ | |
345 static char * emacs_24_xpm[] = { | |
346 \"24 24 129 2\", | |
347 \" c None\", | |
348 \". c #837DA4\", | |
349 \"+ c #807AA0\", | |
350 \"@ c #9894B2\", | |
351 \"# c #CCCAD9\", | |
352 \"$ c #C2C0D2\", | |
353 \"% c #B6B3C9\", | |
354 \"& c #A19DB9\", | |
355 \"* c #8681A5\", | |
356 \"= c #7D779B\", | |
357 \"- c #B6B3C7\", | |
358 \"; c #ABA7BE\", | |
359 \"> c #9792AF\", | |
360 \", c #AAA6BD\", | |
361 \"' c #CBC9D7\", | |
362 \") c #AAA7BE\", | |
363 \"! c #908BAA\", | |
364 \"~ c #797397\", | |
365 \"{ c #948FAC\", | |
366 \"] c #9A95B1\", | |
367 \"^ c #EBEAEF\", | |
368 \"/ c #F1F1F5\", | |
369 \"( c #BCB9CB\", | |
370 \"_ c #A9A5BD\", | |
371 \": c #757093\", | |
372 \"< c #918DA9\", | |
373 \"[ c #DDDBE4\", | |
374 \"} c #FFFFFF\", | |
375 \"| c #EAE9EF\", | |
376 \"1 c #A7A4BA\", | |
377 \"2 c #716C8F\", | |
378 \"3 c #8D89A5\", | |
379 \"4 c #9C98B1\", | |
380 \"5 c #DBDAE3\", | |
381 \"6 c #A4A1B7\", | |
382 \"7 c #6E698A\", | |
383 \"8 c #8B87A1\", | |
384 \"9 c #928EA7\", | |
385 \"0 c #C5C3D1\", | |
386 \"a c #F8F8F9\", | |
387 \"b c #CCCAD6\", | |
388 \"c c #A29FB4\", | |
389 \"d c #6A6585\", | |
390 \"e c #88849D\", | |
391 \"f c #B5B2C2\", | |
392 \"g c #F0F0F3\", | |
393 \"h c #E1E0E6\", | |
394 \"i c #A5A2B5\", | |
395 \"j c #A09DB1\", | |
396 \"k c #676281\", | |
397 \"l c #85819A\", | |
398 \"m c #9591A7\", | |
399 \"n c #E1E0E5\", | |
400 \"o c #F0EFF2\", | |
401 \"p c #B3B0C0\", | |
402 \"q c #9D9AAE\", | |
403 \"r c #635F7C\", | |
404 \"s c #827F96\", | |
405 \"t c #9997AA\", | |
406 \"u c #F7F7F9\", | |
407 \"v c #C8C7D1\", | |
408 \"w c #89869D\", | |
409 \"x c #9B99AB\", | |
410 \"y c #5F5B78\", | |
411 \"z c #7F7C93\", | |
412 \"A c #CFCDD6\", | |
413 \"B c #B7B5C2\", | |
414 \"C c #9996A9\", | |
415 \"D c #5C5873\", | |
416 \"E c #7A778D\", | |
417 \"F c #F5F5F6\", | |
418 \"G c #8E8C9E\", | |
419 \"H c #7D798F\", | |
420 \"I c #58546F\", | |
421 \"J c #6C6981\", | |
422 \"K c #D5D4DB\", | |
423 \"L c #F5F4F6\", | |
424 \"M c #9794A5\", | |
425 \"N c #625F78\", | |
426 \"O c #79768C\", | |
427 \"P c #55516A\", | |
428 \"Q c #605C73\", | |
429 \"R c #CAC9D1\", | |
430 \"S c #EAE9EC\", | |
431 \"T c #B4B3BE\", | |
432 \"U c #777488\", | |
433 \"V c #514E66\", | |
434 \"W c #DEDEE2\", | |
435 \"X c #F4F4F5\", | |
436 \"Y c #9D9BA9\", | |
437 \"Z c #747185\", | |
438 \"` c #4E4B62\", | |
439 \" . c #DEDDE1\", | |
440 \".. c #A6A5B0\", | |
441 \"+. c #716F81\", | |
442 \"@. c #4A475D\", | |
443 \"#. c #A4A3AE\", | |
444 \"$. c #F4F3F5\", | |
445 \"%. c #777586\", | |
446 \"&. c #6E6C7D\", | |
447 \"*. c #464358\", | |
448 \"=. c #514E62\", | |
449 \"-. c #B9B8C0\", | |
450 \";. c #D1D0D5\", | |
451 \">. c #747282\", | |
452 \",. c #6B6979\", | |
453 \"'. c #434054\", | |
454 \"). c #5A5769\", | |
455 \"!. c #D0CFD4\", | |
456 \"~. c #5B5869\", | |
457 \"{. c #696676\", | |
458 \"]. c #403D50\", | |
459 \"^. c #DBDADE\", | |
460 \"/. c #F3F3F4\", | |
461 \"(. c #646271\", | |
462 \"_. c #666473\", | |
463 \":. c #3D3A4C\", | |
464 \"<. c #555362\", | |
465 \"[. c #9E9DA6\", | |
466 \"}. c #9E9CA5\", | |
467 \"|. c #646170\", | |
468 \"1. c #393647\", | |
469 \"2. c #514E5D\", | |
470 \"3. c #83818C\", | |
471 \"4. c #A8A7AE\", | |
472 \"5. c #E6E6E8\", | |
473 \"6. c #DAD9DC\", | |
474 \"7. c #353343\", | |
475 \"8. c #32303E\", | |
476 \" . . . . . . . . . . . . . . . . . . \", | |
477 \" + @ # $ % % % % % % % % % % % % % % & * + + \", | |
478 \" = - ; > > > > > > > > , ' ) > > > > > > ! = \", | |
479 \"~ ~ { { { { { { { { { { { ] ^ / ( { { { { _ ~ ~ \", | |
480 \": : < < < < < < < < < < < < [ } } | < < < 1 : : \", | |
481 \"2 2 3 3 3 3 3 3 3 3 3 3 4 5 } } } 5 3 3 3 6 2 2 \", | |
482 \"7 7 8 8 8 8 8 8 8 8 9 0 a } } } b 8 8 8 8 c 7 7 \", | |
483 \"d d e e e e e e e f g } } } h i e e e e e j d d \", | |
484 \"k k l l l l l m n } } } o p l l l l l l l q k k \", | |
485 \"r r s s s s t u } } } v w s s s s s s s s x r r \", | |
486 \"y y z z z z A } } } B z z z z z z z z z z C y y \", | |
487 \"D D D D D D E F } } G D D D D D D D D D D H D D \", | |
488 \"I I I I I I I J K } L M N I I I I I I I I O I I \", | |
489 \"P P P P P P Q R } } } S T P P P P P P P P U P P \", | |
490 \"V V V V V V W } } X Y V V V V V V V V V V Z V V \", | |
491 \"` ` ` ` ` ` .} } ..` ` ` ` ` ` ` ` ` ` ` +.` ` \", | |
492 \"@.@.@.@.@.@.@.#.$.$.%.@.@.@.@.@.@.@.@.@.@.&.@.@.\", | |
493 \"*.*.*.*.*.*.*.*.=.-.} ;.>.*.*.*.*.*.*.*.*.,.*.*.\", | |
494 \"'.'.'.'.'.'.'.'.'.'.).!.} !.~.'.'.'.'.'.'.{.'.'.\", | |
495 \"].].].].].].].].].].].].^.} /.(.].].].].]._.].].\", | |
496 \":.:.:.:.:.:.:.:.:.:.<.[./.} } }.:.:.:.:.:.|.:.:.\", | |
497 \" 1.1.1.1.1.1.1.1.2.3.4.5.6.3.1.1.1.1.1.1.1.1. \", | |
498 \" 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7. \", | |
499 \" 8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8. \"};") | |
500 | |
501 (defconst bubbles--image-template-ball | |
502 "/* XPM */ | |
503 static char * dot3d_xpm[] = { | |
504 \"20 20 190 2\", | |
505 \" c None\", | |
506 \". c #F9F6F6\", | |
507 \"+ c #D6D0D0\", | |
508 \"@ c #BFBBBB\", | |
509 \"# c #AAA4A4\", | |
510 \"$ c #ABAAAB\", | |
511 \"% c #A8A8A8\", | |
512 \"& c #A29D9D\", | |
513 \"* c #B5B2B2\", | |
514 \"= c #CDC9C9\", | |
515 \"- c #D7D0D0\", | |
516 \"; c #B3AFAF\", | |
517 \"> c #B5B5B5\", | |
518 \", c #B7B7B7\", | |
519 \"' c #B8B8B8\", | |
520 \") c #B6B6B6\", | |
521 \"! c #B3B3B3\", | |
522 \"~ c #AFAFAF\", | |
523 \"{ c #A9A9A9\", | |
524 \"] c #A2A2A2\", | |
525 \"^ c #9C9A9A\", | |
526 \"/ c #C9C5C5\", | |
527 \"( c #FDFBFB\", | |
528 \"_ c #C3BCBC\", | |
529 \": c #BBBBBB\", | |
530 \"< c #C0C0C0\", | |
531 \"[ c #C3C2C2\", | |
532 \"} c #C3C3C3\", | |
533 \"| c #C2C2C2\", | |
534 \"1 c #BEBEBE\", | |
535 \"2 c #B9B9B9\", | |
536 \"3 c #B2B2B2\", | |
537 \"4 c #ABAAAA\", | |
538 \"5 c #999999\", | |
539 \"6 c #ACA7A7\", | |
540 \"7 c #C2BBBB\", | |
541 \"8 c #C5C5C5\", | |
542 \"9 c #CACBCB\", | |
543 \"0 c #CECECE\", | |
544 \"a c #CFCFCF\", | |
545 \"b c #CDCDCD\", | |
546 \"c c #C8C9C9\", | |
547 \"d c #9F9F9F\", | |
548 \"e c #959595\", | |
549 \"f c #A9A5A5\", | |
550 \"g c #D5CFCE\", | |
551 \"h c #BDBDBD\", | |
552 \"i c #C6C6C6\", | |
553 \"j c #D5D5D5\", | |
554 \"k c #D9D9D9\", | |
555 \"l c #DADADA\", | |
556 \"m c #D8D8D8\", | |
557 \"n c #D2D2D2\", | |
558 \"o c #CBCBCB\", | |
559 \"p c #A4A4A5\", | |
560 \"q c #9A9A9A\", | |
561 \"r c #8F8F8F\", | |
562 \"s c #C3BFBF\", | |
563 \"t c #AFACAB\", | |
564 \"u c #CCCCCC\", | |
565 \"v c #D6D6D6\", | |
566 \"w c #DEDEDE\", | |
567 \"x c #E4E4E4\", | |
568 \"y c #E5E5E5\", | |
569 \"z c #E2E2E2\", | |
570 \"A c #DBDBDB\", | |
571 \"B c #C9C8C8\", | |
572 \"C c #A8A9A8\", | |
573 \"D c #9D9E9D\", | |
574 \"E c #929292\", | |
575 \"F c #8A8888\", | |
576 \"G c #D3CECE\", | |
577 \"H c #B0B0B0\", | |
578 \"I c #D1D1D1\", | |
579 \"J c #DCDCDC\", | |
580 \"K c #E6E6E6\", | |
581 \"L c #EEEEEE\", | |
582 \"M c #F1F1F0\", | |
583 \"N c #EBEBEB\", | |
584 \"O c #D7D7D8\", | |
585 \"P c #ABABAB\", | |
586 \"Q c #A0A0A0\", | |
587 \"R c #949494\", | |
588 \"S c #898989\", | |
589 \"T c #C0BDBD\", | |
590 \"U c #B9B6B6\", | |
591 \"V c #B1B1B1\", | |
592 \"W c #BCBCBC\", | |
593 \"X c #C8C8C8\", | |
594 \"Y c #D3D3D3\", | |
595 \"Z c #DFDFDE\", | |
596 \"` c #EAEAEA\", | |
597 \" . c #F5F5F5\", | |
598 \".. c #FAFAFA\", | |
599 \"+. c #F1F1F1\", | |
600 \"@. c #CECFCF\", | |
601 \"#. c #ACACAC\", | |
602 \"$. c #A1A1A1\", | |
603 \"%. c #8A8A8A\", | |
604 \"&. c #9B9999\", | |
605 \"*. c #C7C7C7\", | |
606 \"=. c #DDDDDD\", | |
607 \"-. c #E8E8E8\", | |
608 \";. c #F2F2F2\", | |
609 \">. c #898A89\", | |
610 \",. c #7A7878\", | |
611 \"'. c #AEAEAE\", | |
612 \"). c #C4C4C4\", | |
613 \"!. c #CBCBCA\", | |
614 \"~. c #AAAAAA\", | |
615 \"{. c #939393\", | |
616 \"]. c #888888\", | |
617 \"^. c #7C7C7C\", | |
618 \"/. c #AAAAAB\", | |
619 \"(. c #BFBFBF\", | |
620 \"_. c #C9C9C9\", | |
621 \":. c #DFDEDF\", | |
622 \"<. c #A6A6A6\", | |
623 \"[. c #9B9B9B\", | |
624 \"}. c #909191\", | |
625 \"|. c #858586\", | |
626 \"1. c #797979\", | |
627 \"2. c #989494\", | |
628 \"3. c #A5A6A5\", | |
629 \"4. c #B9B9B8\", | |
630 \"5. c #C1C1C1\", | |
631 \"6. c #CFCFCE\", | |
632 \"7. c #979797\", | |
633 \"8. c #8D8D8D\", | |
634 \"9. c #828282\", | |
635 \"0. c #747171\", | |
636 \"a. c #ADAAAA\", | |
637 \"b. c #A9A8A9\", | |
638 \"c. c #B8B9B9\", | |
639 \"d. c #A5A5A5\", | |
640 \"e. c #9C9C9C\", | |
641 \"f. c #7E7E7D\", | |
642 \"g. c #929191\", | |
643 \"h. c #C9C4C4\", | |
644 \"i. c #989898\", | |
645 \"j. c #ADADAD\", | |
646 \"k. c #9D9D9D\", | |
647 \"l. c #8C8C8C\", | |
648 \"m. c #787878\", | |
649 \"n. c #B8B6B6\", | |
650 \"o. c #939191\", | |
651 \"p. c #A5A5A6\", | |
652 \"q. c #ABABAA\", | |
653 \"r. c #A8A8A9\", | |
654 \"s. c #A3A3A3\", | |
655 \"t. c #858585\", | |
656 \"u. c #757474\", | |
657 \"v. c #C5C1C1\", | |
658 \"w. c #969696\", | |
659 \"x. c #9B9B9C\", | |
660 \"y. c #A4A4A4\", | |
661 \"z. c #9E9E9E\", | |
662 \"A. c #939394\", | |
663 \"B. c #7D7D7D\", | |
664 \"C. c #747474\", | |
665 \"D. c #B7B5B5\", | |
666 \"E. c #A5A1A1\", | |
667 \"F. c #919191\", | |
668 \"G. c #9A9999\", | |
669 \"H. c #838383\", | |
670 \"I. c #757575\", | |
671 \"J. c #939090\", | |
672 \"K. c #A29E9E\", | |
673 \"L. c #868686\", | |
674 \"M. c #8D8D8C\", | |
675 \"N. c #8E8E8E\", | |
676 \"O. c #8D8D8E\", | |
677 \"P. c #8B8C8C\", | |
678 \"Q. c #848485\", | |
679 \"R. c #7F7F80\", | |
680 \"S. c #7A7A7A\", | |
681 \"T. c #737373\", | |
682 \"U. c #929090\", | |
683 \"V. c #828080\", | |
684 \"W. c #818181\", | |
685 \"X. c #808080\", | |
686 \"Y. c #7E7E7E\", | |
687 \"Z. c #737272\", | |
688 \"`. c #B7B4B4\", | |
689 \" + c #BCBABA\", | |
690 \".+ c #959494\", | |
691 \"++ c #747172\", | |
692 \"@+ c #767676\", | |
693 \"#+ c #6F6D6D\", | |
694 \"$+ c #8F8E8E\", | |
695 \" . + @ # $ % & * = . \", | |
696 \" - ; > , ' ) ! ~ { ] ^ / \", | |
697 \" ( _ > : < [ } | 1 2 3 4 ] 5 6 ( \", | |
698 \" 7 ) 1 8 9 0 a b c | : 3 { d e f \", | |
699 \" g ! h i 0 j k l m n o | 2 ~ p q r s \", | |
700 \". t ' | u v w x y z A n B 1 ! C D E F . \", | |
701 \"G H : i I J K L M N z O b | ) P Q R S T \", | |
702 \"U V W X Y Z ` ...+.y l @.} ' #.$.e %.&.\", | |
703 \"& H W *.n =.-.;. .L x k 0 [ , #.Q e >.,.\", | |
704 \"] '.2 ).a k z -.` K w j !.< > ~.d {.].^.\", | |
705 \"d /.> (._.I k =.:.J v 0 8 : V <.[.}.|.1.\", | |
706 \"2.3.~ 4.5._.6.n Y I u i 1 > P $.7.8.9.0.\", | |
707 \"a.d b.V c.(.).*.X i | h ) '.d.e.E ].f.g.\", | |
708 \"h.i.$.C ~ > 2 W W : ' ! j.d.k.e l.9.m.n.\", | |
709 \". o.i.d p.q.'.H V H j.r.s.k.e 8.t.^.u.. \", | |
710 \" v.r w.x.Q s.d.d.y.] z.5 A.8.t.B.C.D. \", | |
711 \" E.l.F.e i.G.q 5 7.{.r %.H.^.I.J. \", | |
712 \" ( K.L.%.M.N.N.O.P.S Q.R.S.T.U.( \", | |
713 \" @ V.W.H.H.9.X.Y.S.I.Z.`. \", | |
714 \" . +.+++@+C.#+$+D.. \"};") | |
715 | |
716 ;; ====================================================================== | |
717 ;; Functions | |
718 | |
719 (defsubst bubbles--grid-width () | |
720 "Return the grid width for the current game theme." | |
721 (car (case bubbles-game-theme | |
722 ('easy | |
723 bubbles--grid-small) | |
724 ('medium | |
725 bubbles--grid-medium) | |
726 ('difficult | |
727 bubbles--grid-large) | |
728 ('hard | |
729 bubbles--grid-huge) | |
730 ('user-defined | |
731 bubbles-grid-size)))) | |
732 | |
733 (defsubst bubbles--grid-height () | |
734 "Return the grid height for the current game theme." | |
735 (cdr (case bubbles-game-theme | |
736 ('easy | |
737 bubbles--grid-small) | |
738 ('medium | |
739 bubbles--grid-medium) | |
740 ('difficult | |
741 bubbles--grid-large) | |
742 ('hard | |
743 bubbles--grid-huge) | |
744 ('user-defined | |
745 bubbles-grid-size)))) | |
746 | |
747 (defsubst bubbles--colors () | |
748 "Return the color list for the current game theme." | |
749 (case bubbles-game-theme | |
750 ('easy | |
751 bubbles--colors-2) | |
752 ('medium | |
753 bubbles--colors-3) | |
754 ('difficult | |
755 bubbles--colors-4) | |
756 ('hard | |
757 bubbles--colors-5) | |
758 ('user-defined | |
759 bubbles-colors))) | |
760 | |
761 (defsubst bubbles--shift-mode () | |
762 "Return the shift mode for the current game theme." | |
763 (case bubbles-game-theme | |
764 ('easy | |
765 'default) | |
766 ('medium | |
767 'default) | |
768 ('difficult | |
769 'always) | |
770 ('hard | |
771 'always) | |
772 ('user-defined | |
773 bubbles-shift-mode))) | |
774 | |
775 (defun bubbles-save-settings () | |
776 "Save current customization settings." | |
777 (interactive) | |
778 (custom-set-variables | |
779 (list 'bubbles-game-theme `(quote ,bubbles-game-theme) t) | |
780 (list 'bubbles-graphics-theme `(quote ,bubbles-graphics-theme) t)) | |
781 (customize-save-customized)) | |
782 | |
783 (defsubst bubbles--empty-char () | |
784 "The character used for removed bubbles (empty grid cells)." | |
99902
19d0410ccdd2
* play/bubbles.el (bubbles-mode): Define with `define-derived-mode'.
Juanma Barranquero <lekktu@gmail.com>
parents:
96463
diff
changeset
|
785 ?\s) |
82921 | 786 |
787 (defun bubbles-set-graphics-theme-ascii () | |
788 "Set graphics theme to `ascii'." | |
789 (interactive) | |
790 (setq bubbles-graphics-theme 'ascii) | |
791 (bubbles--update-faces-or-images)) | |
792 | |
793 (defun bubbles-set-graphics-theme-circles () | |
794 "Set graphics theme to `circles'." | |
795 (interactive) | |
796 (setq bubbles-graphics-theme 'circles) | |
797 (bubbles--initialize-images) | |
798 (bubbles--update-faces-or-images)) | |
799 | |
800 (defun bubbles-set-graphics-theme-squares () | |
801 "Set graphics theme to `squares'." | |
802 (interactive) | |
803 (setq bubbles-graphics-theme 'squares) | |
804 (bubbles--initialize-images) | |
805 (bubbles--update-faces-or-images)) | |
806 | |
807 (defun bubbles-set-graphics-theme-diamonds () | |
808 "Set graphics theme to `diamonds'." | |
809 (interactive) | |
810 (setq bubbles-graphics-theme 'diamonds) | |
811 (bubbles--initialize-images) | |
812 (bubbles--update-faces-or-images)) | |
813 | |
814 (defun bubbles-set-graphics-theme-balls () | |
815 "Set graphics theme to `balls'." | |
816 (interactive) | |
817 (setq bubbles-graphics-theme 'balls) | |
818 (bubbles--initialize-images) | |
819 (bubbles--update-faces-or-images)) | |
820 | |
821 (defun bubbles-set-graphics-theme-emacs () | |
822 "Set graphics theme to `emacs'." | |
823 (interactive) | |
824 (setq bubbles-graphics-theme 'emacs) | |
825 (bubbles--initialize-images) | |
826 (bubbles--update-faces-or-images)) | |
827 | |
828 ;; game theme menu | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
829 (defvar bubbles-game-theme-menu |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
830 (let ((menu (make-sparse-keymap "Game Theme"))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
831 (define-key menu [bubbles-set-game-userdefined] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
832 (list 'menu-item "User defined" 'bubbles-set-game-userdefined |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
833 :button '(:radio . (eq bubbles-game-theme 'user-defined)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
834 (define-key menu [bubbles-set-game-hard] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
835 (list 'menu-item "Hard" 'bubbles-set-game-hard |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
836 :button '(:radio . (eq bubbles-game-theme 'hard)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
837 (define-key menu [bubbles-set-game-difficult] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
838 (list 'menu-item "Difficult" 'bubbles-set-game-difficult |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
839 :button '(:radio . (eq bubbles-game-theme 'difficult)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
840 (define-key menu [bubbles-set-game-medium] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
841 (list 'menu-item "Medium" 'bubbles-set-game-medium |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
842 :button '(:radio . (eq bubbles-game-theme 'medium)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
843 (define-key menu [bubbles-set-game-easy] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
844 (list 'menu-item "Easy" 'bubbles-set-game-easy |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
845 :button '(:radio . (eq bubbles-game-theme 'easy)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
846 menu) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
847 "Map for bubbles game theme menu.") |
82921 | 848 |
849 ;; graphics theme menu | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
850 (defvar bubbles-graphics-theme-menu |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
851 (let ((menu (make-sparse-keymap "Graphics Theme"))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
852 (define-key menu [bubbles-set-graphics-theme-ascii] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
853 (list 'menu-item "ASCII" 'bubbles-set-graphics-theme-ascii |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
854 :button '(:radio . (eq bubbles-graphics-theme 'ascii)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
855 (define-key menu [bubbles-set-graphics-theme-emacs] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
856 (list 'menu-item "Emacs" 'bubbles-set-graphics-theme-emacs |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
857 :button '(:radio . (eq bubbles-graphics-theme 'emacs)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
858 (define-key menu [bubbles-set-graphics-theme-balls] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
859 (list 'menu-item "Balls" 'bubbles-set-graphics-theme-balls |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
860 :button '(:radio . (eq bubbles-graphics-theme 'balls)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
861 (define-key menu [bubbles-set-graphics-theme-diamonds] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
862 (list 'menu-item "Diamonds" 'bubbles-set-graphics-theme-diamonds |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
863 :button '(:radio . (eq bubbles-graphics-theme 'diamonds)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
864 (define-key menu [bubbles-set-graphics-theme-squares] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
865 (list 'menu-item "Squares" 'bubbles-set-graphics-theme-squares |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
866 :button '(:radio . (eq bubbles-graphics-theme 'squares)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
867 (define-key menu [bubbles-set-graphics-theme-circles] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
868 (list 'menu-item "Circles" 'bubbles-set-graphics-theme-circles |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
869 :button '(:radio . (eq bubbles-graphics-theme 'circles)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
870 menu) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
871 "Map for bubbles graphics theme menu.") |
82921 | 872 |
873 ;; menu | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
874 (defvar bubbles-menu |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
875 (let ((menu (make-sparse-keymap "Bubbles"))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
876 (define-key menu [bubbles-quit] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
877 (list 'menu-item "Quit" 'bubbles-quit)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
878 (define-key menu [bubbles] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
879 (list 'menu-item "New game" 'bubbles)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
880 (define-key menu [bubbles-separator-1] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
881 '("--")) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
882 (define-key menu [bubbles-save-settings] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
883 (list 'menu-item "Save all settings" 'bubbles-save-settings)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
884 (define-key menu [bubbles-customize] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
885 (list 'menu-item "Edit all settings" 'bubbles-customize)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
886 (define-key menu [bubbles-game-theme-menu] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
887 (list 'menu-item "Game Theme" bubbles-game-theme-menu)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
888 (define-key menu [bubbles-graphics-theme-menu] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
889 (list 'menu-item "Graphics Theme" bubbles-graphics-theme-menu |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
890 :enable 'bubbles--playing)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
891 (define-key menu [bubbles-separator-2] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
892 '("--")) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
893 (define-key menu [bubbles-undo] |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
894 (list 'menu-item "Undo last move" 'bubbles-undo |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
895 :enable '(and bubbles--playing (listp buffer-undo-list)))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
896 menu) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
897 "Map for bubbles menu.") |
82921 | 898 |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
899 ;; bubbles mode map |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
900 (defvar bubbles-mode-map |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
901 (let ((map (make-sparse-keymap 'bubbles-mode-map))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
902 ;; (suppress-keymap map t) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
903 (define-key map "q" 'bubbles-quit) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
904 (define-key map "\n" 'bubbles-plop) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
905 (define-key map " " 'bubbles-plop) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
906 (define-key map [double-down-mouse-1] 'bubbles-plop) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
907 (define-key map [mouse-2] 'bubbles-plop) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
908 (define-key map "\C-m" 'bubbles-plop) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
909 (define-key map "u" 'bubbles-undo) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
910 (define-key map "p" 'previous-line) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
911 (define-key map "n" 'next-line) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
912 (define-key map "f" 'forward-char) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
913 (define-key map "b" 'backward-char) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
914 ;; bind menu to mouse |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
915 (define-key map [down-mouse-3] bubbles-menu) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
916 ;; Put menu in menu-bar |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
917 (define-key map [menu-bar Bubbles] (cons "Bubbles" bubbles-menu)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
918 map) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
919 "Mode map for bubbles.") |
82921 | 920 |
99902
19d0410ccdd2
* play/bubbles.el (bubbles-mode): Define with `define-derived-mode'.
Juanma Barranquero <lekktu@gmail.com>
parents:
96463
diff
changeset
|
921 (define-derived-mode bubbles-mode nil "Bubbles" |
82921 | 922 "Major mode for playing bubbles. |
923 \\{bubbles-mode-map}" | |
924 (setq buffer-read-only t) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
925 (buffer-disable-undo) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
926 (force-mode-line-update) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
927 (redisplay) |
99902
19d0410ccdd2
* play/bubbles.el (bubbles-mode): Define with `define-derived-mode'.
Juanma Barranquero <lekktu@gmail.com>
parents:
96463
diff
changeset
|
928 (add-hook 'post-command-hook 'bubbles--mark-neighbourhood t t)) |
82921 | 929 |
930 ;;;###autoload | |
931 (defun bubbles () | |
102731
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
932 "Play Bubbles game. |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
933 \\<bubbles-mode-map> |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
934 The goal is to remove all bubbles with as few moves as possible. |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
935 \\[bubbles-plop] on a bubble removes that bubble and all |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
936 connected bubbles of the same color. Unsupported bubbles fall |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
937 down, and columns that do not contain any bubbles suck the |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
938 columns on its right towards the left. |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
939 |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
940 \\[bubbles-set-game-easy] sets the difficulty to easy. |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
941 \\[bubbles-set-game-medium] sets the difficulty to medium. |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
942 \\[bubbles-set-game-difficult] sets the difficulty to difficult. |
6673a663a72e
(bubbles): Doc fix (Bug#2776).
Chong Yidong <cyd@stupidchicken.com>
parents:
100908
diff
changeset
|
943 \\[bubbles-set-game-hard] sets the difficulty to hard." |
82921 | 944 (interactive) |
945 (switch-to-buffer (get-buffer-create "*bubbles*")) | |
946 (when (or (not bubbles--playing) | |
947 (y-or-n-p "Start new game? ")) | |
948 (setq bubbles--save-data nil) | |
949 (setq bubbles--playing t) | |
950 (bubbles--initialize))) | |
951 | |
952 (defun bubbles-quit () | |
953 "Quit Bubbles." | |
954 (interactive) | |
955 (message "bubbles-quit") | |
956 (bury-buffer)) | |
957 | |
95841
b4e36ff621b3
Add some compiler declarations, for builds without X.
Glenn Morris <rgm@gnu.org>
parents:
94675
diff
changeset
|
958 (declare-function image-size "image.c" (spec &optional pixels frame)) |
b4e36ff621b3
Add some compiler declarations, for builds without X.
Glenn Morris <rgm@gnu.org>
parents:
94675
diff
changeset
|
959 |
82921 | 960 (defun bubbles--compute-offsets () |
961 "Update horizontal and vertical offsets for centering the bubbles grid. | |
962 Set `bubbles--col-offset' and `bubbles--row-offset'." | |
963 (cond ((and (display-images-p) | |
964 bubbles--images-ok | |
965 (not (eq bubbles-graphics-theme 'ascii)) | |
966 (fboundp 'window-inside-pixel-edges)) | |
967 ;; compute offset in units of pixels | |
968 (let ((bubbles--image-size | |
969 (car (image-size (car bubbles--images) t)))) | |
970 (setq bubbles--col-offset | |
971 (list | |
972 (max 0 (/ (- (nth 2 (window-inside-pixel-edges)) | |
973 (nth 0 (window-inside-pixel-edges)) | |
974 (* ( + bubbles--image-size 2) ;; margin | |
975 (bubbles--grid-width))) 2)))) | |
976 (setq bubbles--row-offset | |
977 (list | |
978 (max 0 (/ (- (nth 3 (window-inside-pixel-edges)) | |
979 (nth 1 (window-inside-pixel-edges)) | |
980 (* (+ bubbles--image-size 1) ;; margin | |
981 (bubbles--grid-height))) 2)))))) | |
982 (t | |
983 ;; compute offset in units of chars | |
984 (setq bubbles--col-offset | |
985 (max 0 (/ (- (window-width) | |
986 (bubbles--grid-width)) 2))) | |
987 (setq bubbles--row-offset | |
988 (max 0 (/ (- (window-height) | |
989 (bubbles--grid-height) 2) 2)))))) | |
990 | |
991 (defun bubbles--remove-overlays () | |
992 "Remove all overlays." | |
993 (if (fboundp 'remove-overlays) | |
994 (remove-overlays))) | |
995 | |
996 (defun bubbles--initialize () | |
997 "Initialize Bubbles game." | |
998 (bubbles--initialize-faces) | |
999 (bubbles--initialize-images) | |
1000 (bubbles--remove-overlays) | |
1001 | |
1002 (switch-to-buffer (get-buffer-create "*bubbles*")) | |
1003 (bubbles--compute-offsets) | |
1004 (let ((inhibit-read-only t)) | |
1005 (set-buffer-modified-p nil) | |
1006 (erase-buffer) | |
1007 (insert " ") | |
1008 (add-text-properties | |
1009 (point-min) (point) (list 'intangible t 'display | |
1010 (cons 'space | |
1011 (list :height bubbles--row-offset)))) | |
1012 (insert "\n") | |
1013 (let ((max-char (length (bubbles--colors)))) | |
1014 (dotimes (i (bubbles--grid-height)) | |
1015 (let ((p (point))) | |
1016 (insert " ") | |
1017 (add-text-properties | |
1018 p (point) (list 'intangible t | |
1019 'display (cons 'space | |
1020 (list :width | |
1021 bubbles--col-offset))))) | |
1022 (dotimes (j (bubbles--grid-width)) | |
1023 (let* ((index (random max-char)) | |
1024 (char (nth index bubbles-chars))) | |
1025 (insert char) | |
1026 (add-text-properties (1- (point)) (point) (list 'index index)))) | |
1027 (insert "\n")) | |
1028 (insert "\n ") | |
1029 (add-text-properties | |
1030 (1- (point)) (point) (list 'intangible t 'display | |
1031 (cons 'space | |
1032 (list :width bubbles--col-offset))))) | |
1033 (put-text-property (point-min) (point-max) 'pointer 'arrow)) | |
1034 (bubbles-mode) | |
1035 (bubbles--reset-score) | |
1036 (bubbles--update-faces-or-images) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1037 (bubbles--goto 0 0) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1038 (setq buffer-undo-list t) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1039 (force-mode-line-update) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1040 (redisplay)) |
82921 | 1041 |
1042 (defun bubbles--initialize-faces () | |
1043 "Prepare faces for playing `bubbles'." | |
1044 (copy-face 'default 'bubbles--highlight-face) | |
1045 (set-face-background 'bubbles--highlight-face "#8080f4") | |
1046 (when (display-color-p) | |
1047 (setq bubbles--faces | |
1048 (mapcar (lambda (color) | |
1049 (let ((fname (intern (format "bubbles--face-%s" color)))) | |
1050 (unless (facep fname) | |
1051 (copy-face 'default fname) | |
1052 (set-face-foreground fname color)) | |
1053 fname)) | |
1054 (bubbles--colors))))) | |
1055 | |
1056 (defsubst bubbles--row (pos) | |
1057 "Return row of point POS." | |
1058 (save-excursion | |
1059 (goto-char pos) | |
1060 (beginning-of-line) | |
1061 (1- (count-lines (point-min) (point))))) | |
1062 | |
1063 (defsubst bubbles--col (pos) | |
1064 "Return column of point POS." | |
1065 (save-excursion | |
1066 (goto-char pos) | |
1067 (1- (current-column)))) | |
1068 | |
1069 (defun bubbles--goto (row col) | |
1070 "Move point to bubble at coordinates ROW and COL." | |
1071 (if (or (< row 0) | |
1072 (< col 0) | |
1073 (>= row (bubbles--grid-height)) | |
1074 (>= col (bubbles--grid-width))) | |
1075 ;; Error! return nil | |
1076 nil | |
1077 ;; go | |
1078 (goto-char (point-min)) | |
1079 (forward-line (1+ row)) | |
1080 (forward-char (1+ col)) | |
1081 (point))) | |
1082 | |
1083 (defun bubbles--char-at (row col) | |
1084 "Return character at bubble ROW and COL." | |
1085 (save-excursion | |
1086 (if (bubbles--goto row col) | |
1087 (char-after (point)) | |
1088 nil))) | |
1089 | |
1090 (defun bubbles--mark-direct-neighbours (row col char) | |
96463
ce09add00a57
American English spelling fixes.
Glenn Morris <rgm@gnu.org>
parents:
95841
diff
changeset
|
1091 "Mark direct neighbors of bubble at ROW COL with same CHAR." |
82921 | 1092 (save-excursion |
1093 (let ((count 0)) | |
1094 (when (and (bubbles--goto row col) | |
1095 (eq char (char-after (point))) | |
1096 (not (get-text-property (point) 'active))) | |
1097 (add-text-properties (point) (1+ (point)) | |
1098 '(active t face 'bubbles--highlight-face)) | |
1099 (setq count (+ 1 | |
1100 (bubbles--mark-direct-neighbours row (1+ col) char) | |
1101 (bubbles--mark-direct-neighbours row (1- col) char) | |
1102 (bubbles--mark-direct-neighbours (1+ row) col char) | |
1103 (bubbles--mark-direct-neighbours (1- row) col char)))) | |
1104 count))) | |
1105 | |
1106 (defun bubbles--mark-neighbourhood (&optional pos) | |
96463
ce09add00a57
American English spelling fixes.
Glenn Morris <rgm@gnu.org>
parents:
95841
diff
changeset
|
1107 "Mark neighborhood of point. |
82921 | 1108 Use optional parameter POS instead of point if given." |
1109 (when bubbles--playing | |
1110 (unless pos (setq pos (point))) | |
1111 (condition-case err | |
1112 (let ((char (char-after pos)) | |
1113 (inhibit-read-only t) | |
1114 (row (bubbles--row (point))) | |
1115 (col (bubbles--col (point)))) | |
1116 (add-text-properties (point-min) (point-max) | |
1117 '(face default active nil)) | |
1118 (let ((count 0)) | |
1119 (when (and row col (not (eq char (bubbles--empty-char)))) | |
1120 (setq count (bubbles--mark-direct-neighbours row col char)) | |
1121 (unless (> count 1) | |
1122 (add-text-properties (point-min) (point-max) | |
1123 '(face default active nil)) | |
1124 (setq count 0))) | |
1125 (bubbles--update-neighbourhood-score count)) | |
1126 (put-text-property (point-min) (point-max) 'pointer 'arrow) | |
1127 (bubbles--update-faces-or-images) | |
1128 (sit-for 0)) | |
1129 (error (message "Bubbles: Internal error %s" err))))) | |
1130 | |
1131 (defun bubbles--neighbourhood-available () | |
96463
ce09add00a57
American English spelling fixes.
Glenn Morris <rgm@gnu.org>
parents:
95841
diff
changeset
|
1132 "Return t if another valid neighborhood is available." |
82921 | 1133 (catch 'found |
1134 (save-excursion | |
1135 (dotimes (i (bubbles--grid-height)) | |
1136 (dotimes (j (bubbles--grid-width)) | |
1137 (let ((c (bubbles--char-at i j))) | |
1138 (if (and (not (eq c (bubbles--empty-char))) | |
1139 (or (eq c (bubbles--char-at (1+ i) j)) | |
1140 (eq c (bubbles--char-at i (1+ j))))) | |
1141 (throw 'found t))))) | |
1142 nil))) | |
1143 | |
1144 (defun bubbles--count () | |
1145 "Count remaining bubbles." | |
1146 (let ((count 0)) | |
1147 (save-excursion | |
1148 (dotimes (i (bubbles--grid-height)) | |
1149 (dotimes (j (bubbles--grid-width)) | |
1150 (let ((c (bubbles--char-at i j))) | |
1151 (if (not (eq c (bubbles--empty-char))) | |
1152 (setq count (1+ count))))))) | |
1153 count)) | |
1154 | |
1155 (defun bubbles--reset-score () | |
1156 "Reset bubbles score." | |
1157 (setq bubbles--neighbourhood-score 0 | |
1158 bubbles--score 0) | |
1159 (bubbles--update-score)) | |
1160 | |
1161 (defun bubbles--update-score () | |
99902
19d0410ccdd2
* play/bubbles.el (bubbles-mode): Define with `define-derived-mode'.
Juanma Barranquero <lekktu@gmail.com>
parents:
96463
diff
changeset
|
1162 "Calculate and display new bubbles score." |
82921 | 1163 (setq bubbles--score (+ bubbles--score bubbles--neighbourhood-score)) |
1164 (bubbles--show-scores)) | |
1165 | |
1166 (defun bubbles--update-neighbourhood-score (size) | |
96463
ce09add00a57
American English spelling fixes.
Glenn Morris <rgm@gnu.org>
parents:
95841
diff
changeset
|
1167 "Calculate and display score of active neighborhood from its SIZE." |
82921 | 1168 (if (> size 1) |
1169 (setq bubbles--neighbourhood-score (expt (- size 1) 2)) | |
1170 (setq bubbles--neighbourhood-score 0)) | |
1171 (bubbles--show-scores)) | |
1172 | |
1173 (defun bubbles--show-scores () | |
1174 "Display current scores." | |
1175 (save-excursion | |
1176 (goto-char (or (next-single-property-change (point-min) 'status) | |
1177 (point-max))) | |
1178 (let ((inhibit-read-only t) | |
1179 (pos (point))) | |
1180 (delete-region (point) (point-max)) | |
1181 (insert (format "Selected: %4d\n" bubbles--neighbourhood-score)) | |
1182 (insert " ") | |
1183 (add-text-properties (1- (point)) (point) | |
1184 (list 'intangible t 'display | |
1185 (cons 'space | |
1186 (list :width bubbles--col-offset)))) | |
1187 (insert (format "Score: %4d" bubbles--score)) | |
1188 (put-text-property pos (point) 'status t)))) | |
1189 | |
1190 (defun bubbles--game-over () | |
1191 "Finish bubbles game." | |
1192 (bubbles--update-faces-or-images) | |
1193 (setq bubbles--playing nil | |
1194 bubbles--save-data nil) | |
1195 ;; add bonus if all bubbles were removed | |
1196 (when (= 0 (bubbles--count)) | |
1197 (setq bubbles--score (+ bubbles--score (* (bubbles--grid-height) | |
1198 (bubbles--grid-width)))) | |
1199 (bubbles--show-scores)) | |
1200 ;; Game over message | |
1201 (goto-char (point-max)) | |
1202 (let* ((inhibit-read-only t)) | |
1203 (insert "\n ") | |
1204 (add-text-properties (1- (point)) (point) | |
1205 (list 'intangible t 'display | |
1206 (cons 'space | |
1207 (list :width bubbles--col-offset)))) | |
1208 (insert "Game Over!")) | |
1209 ;; save score | |
1210 (gamegrid-add-score (format "bubbles-%s-%d-%d-%d-scores" | |
1211 (symbol-name (bubbles--shift-mode)) | |
1212 (length (bubbles--colors)) | |
1213 (bubbles--grid-width) (bubbles--grid-height)) | |
1214 bubbles--score)) | |
1215 | |
1216 (defun bubbles-plop () | |
1217 "Remove active bubbles region." | |
1218 (interactive) | |
1219 (when (and bubbles--playing | |
1220 (> bubbles--neighbourhood-score 0)) | |
1221 (setq bubbles--save-data (list bubbles--score (buffer-string))) | |
1222 (let ((inhibit-read-only t)) | |
1223 ;; blank out current neighbourhood | |
1224 (let ((row (bubbles--row (point))) | |
1225 (col (bubbles--col (point)))) | |
1226 (goto-char (point-max)) | |
1227 (while (not (bobp)) | |
1228 (backward-char) | |
1229 (while (get-text-property (point) 'active) | |
1230 (delete-char 1) | |
1231 (insert (bubbles--empty-char)) | |
1232 (add-text-properties (1- (point)) (point) (list 'removed t | |
1233 'index -1)))) | |
1234 (bubbles--goto row col)) | |
1235 ;; show new score | |
1236 (bubbles--update-score) | |
1237 ;; update display and wait | |
1238 (bubbles--update-faces-or-images) | |
1239 (sit-for 0) | |
1240 (sleep-for 0.2) | |
1241 (discard-input) | |
1242 ;; drop down | |
1243 (let ((something-dropped nil)) | |
1244 (save-excursion | |
1245 (dotimes (i (bubbles--grid-height)) | |
1246 (dotimes (j (bubbles--grid-width)) | |
1247 (bubbles--goto i j) | |
1248 (while (get-text-property (point) 'removed) | |
1249 (setq something-dropped (or (bubbles--shift 'top i j) | |
1250 something-dropped)))))) | |
1251 ;; update display and wait | |
1252 (bubbles--update-faces-or-images) | |
1253 (when something-dropped | |
1254 (sit-for 0))) | |
1255 (discard-input) | |
1256 ;; shift to left | |
1257 (put-text-property (point-min) (point-max) 'removed nil) | |
1258 (save-excursion | |
1259 (goto-char (point-min)) | |
1260 (let ((removed-string (format "%c" (bubbles--empty-char)))) | |
1261 (while (search-forward removed-string nil t) | |
1262 (put-text-property (1- (point)) (point) 'removed t)))) | |
1263 (let ((shifted nil)) | |
1264 (cond ((eq (bubbles--shift-mode) 'always) | |
1265 (save-excursion | |
1266 (dotimes (i (bubbles--grid-height)) | |
1267 (dotimes (j (bubbles--grid-width)) | |
1268 (bubbles--goto i j) | |
1269 (while (get-text-property (point) 'removed) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1270 (setq shifted (or (bubbles--shift 'right i j) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1271 shifted)))))) |
82921 | 1272 (bubbles--update-faces-or-images) |
1273 (sleep-for 0.5)) | |
1274 (t ;; default shift-mode | |
1275 (save-excursion | |
1276 (dotimes (j (bubbles--grid-width)) | |
1277 (bubbles--goto (1- (bubbles--grid-height)) j) | |
1278 (let ((shifted-cols 0)) | |
1279 (while (get-text-property (point) 'removed) | |
1280 (setq shifted-cols (1+ shifted-cols)) | |
1281 (bubbles--shift 'right (1- (bubbles--grid-height)) j)) | |
1282 (dotimes (k shifted-cols) | |
1283 (let ((i (- (bubbles--grid-height) 2))) | |
1284 (while (>= i 0) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1285 (setq shifted (or (bubbles--shift 'right i j) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1286 shifted)) |
82921 | 1287 (setq i (1- i)))))))))) |
1288 (when shifted | |
1289 ;;(sleep-for 0.5) | |
1290 (bubbles--update-faces-or-images) | |
1291 (sit-for 0))) | |
1292 (put-text-property (point-min) (point-max) 'removed nil) | |
1293 (unless (bubbles--neighbourhood-available) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1294 (bubbles--game-over))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1295 ;; undo |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1296 (setq buffer-undo-list '((apply bubbles-undo . nil))) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1297 (force-mode-line-update) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1298 (redisplay))) |
82921 | 1299 |
1300 (defun bubbles-undo () | |
1301 "Undo last move." | |
1302 (interactive) | |
1303 (when bubbles--save-data | |
1304 (let ((inhibit-read-only t) | |
1305 (pos (point))) | |
1306 (erase-buffer) | |
1307 (insert (cadr bubbles--save-data)) | |
1308 (bubbles--update-faces-or-images) | |
1309 (setq bubbles--score (car bubbles--save-data)) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1310 (goto-char pos)) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1311 (setq buffer-undo-list t) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1312 (force-mode-line-update) |
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1313 (redisplay))) |
82921 | 1314 |
1315 (defun bubbles--shift (from row col) | |
1316 "Move bubbles FROM one side to position ROW COL. | |
1317 Return t if new char is non-empty." | |
1318 (save-excursion | |
1319 (when (bubbles--goto row col) | |
1320 (let ((char-org (char-after (point))) | |
1321 (char-new (bubbles--empty-char)) | |
1322 (removed nil) | |
1323 (trow row) | |
1324 (tcol col) | |
1325 (index -1)) | |
1326 (cond ((eq from 'top) | |
1327 (setq trow (1- row))) | |
1328 ((eq from 'left) | |
1329 (setq tcol (1- col))) | |
1330 ((eq from 'right) | |
1331 (setq tcol (1+ col)))) | |
1332 (save-excursion | |
1333 (when (bubbles--goto trow tcol) | |
1334 (setq char-new (char-after (point))) | |
1335 (setq removed (get-text-property (point) 'removed)) | |
1336 (setq index (get-text-property (point) 'index)) | |
1337 (bubbles--shift from trow tcol))) | |
1338 (insert char-new) | |
1339 (delete-char 1) | |
1340 (add-text-properties (1- (point)) (point) (list 'index index | |
1341 'removed removed)) | |
1342 (not (eq char-new (bubbles--empty-char))))))) | |
1343 | |
1344 (defun bubbles--initialize-images () | |
1345 "Prepare images for playing `bubbles'." | |
1346 (when (and (display-images-p) | |
1347 (not (eq bubbles-graphics-theme 'ascii))) | |
1348 (let ((template (case bubbles-graphics-theme | |
1349 ('circles bubbles--image-template-circle) | |
1350 ('balls bubbles--image-template-ball) | |
1351 ('squares bubbles--image-template-square) | |
1352 ('diamonds bubbles--image-template-diamond) | |
1353 ('emacs bubbles--image-template-emacs)))) | |
1354 (setq bubbles--empty-image | |
1355 (create-image (replace-regexp-in-string | |
1356 "^\"\\(.*\\)\t.*c .*\",$" | |
84539
94bc57977861
(bubbles--initialize-images): Fix bug:
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
82929
diff
changeset
|
1357 "\"\\1\tc None\"," template) |
82921 | 1358 'xpm t |
1359 ;;:mask 'heuristic | |
1360 :margin '(2 . 1))) | |
1361 (setq bubbles--images | |
1362 (mapcar (lambda (color) | |
1363 (let* ((rgb (color-values color)) | |
1364 (red (nth 0 rgb)) | |
1365 (green (nth 1 rgb)) | |
1366 (blue (nth 2 rgb))) | |
1367 (with-temp-buffer | |
1368 (insert template) | |
1369 (goto-char (point-min)) | |
1370 (re-search-forward | |
1371 "^\"[0-9]+ [0-9]+ \\(.*?\\) .*\",$" nil t) | |
1372 (goto-char (point-min)) | |
1373 (while (re-search-forward | |
1374 "^\"\\(.*\\)\t.*c \\(#.*\\)\",$" nil t) | |
1375 (let* ((crgb (color-values (match-string 2))) | |
1376 (r (nth 0 crgb)) | |
1377 (g (nth 1 crgb)) | |
1378 (b (nth 2 crgb)) | |
1379 (brightness (/ (+ r g b) 3.0 256 256)) | |
1380 (val (sin (* brightness (/ pi 2)))) | |
1381 (rr (* red val)) | |
1382 (gg (* green val)) | |
1383 (bb (* blue val)) | |
1384 ;;(rr (/ (+ red r) 2)) | |
1385 ;;(gg (/ (+ green g) 2)) | |
1386 ;;(bb (/ (+ blue b) 2)) | |
1387 (color (format "#%02x%02x%02x" | |
1388 (/ rr 256) (/ gg 256) | |
1389 (/ bb 256)))) | |
1390 (replace-match (format "\"\\1\tc %s\"," | |
1391 (upcase color))))) | |
1392 (create-image (buffer-string) 'xpm t | |
1393 :margin '(2 . 1) | |
1394 ;;:mask 'heuristic | |
1395 )))) | |
1396 (bubbles--colors)))) | |
1397 ;; check images | |
1398 (setq bubbles--images-ok bubbles--empty-image) | |
1399 (mapc (lambda (elt) | |
1400 (setq bubbles--images-ok (and bubbles--images-ok elt))) | |
1401 bubbles--images))) | |
1402 | |
1403 (defun bubbles--update-faces-or-images () | |
1404 "Update faces and/or images, depending on graphics mode." | |
1405 (bubbles--set-faces) | |
1406 (bubbles--show-images)) | |
1407 | |
1408 (defun bubbles--set-faces () | |
1409 "Update faces in the bubbles buffer." | |
1410 (unless (and (display-images-p) | |
1411 bubbles--images-ok | |
1412 (not (eq bubbles-graphics-theme 'ascii))) | |
1413 (when (display-color-p) | |
1414 (save-excursion | |
1415 (let ((inhibit-read-only t)) | |
1416 (dotimes (i (bubbles--grid-height)) | |
1417 (dotimes (j (bubbles--grid-width)) | |
1418 (bubbles--goto i j) | |
1419 (let* ((index (get-text-property (point) 'index)) | |
1420 (face (nth index bubbles--faces)) | |
1421 (fg-col (face-foreground face))) | |
1422 (when (get-text-property (point) 'active) | |
1423 (set-face-foreground 'bubbles--highlight-face "#ff0000") | |
1424 (setq face 'bubbles--highlight-face)) | |
1425 (put-text-property (point) (1+ (point)) | |
1426 'face face))))))))) | |
1427 | |
1428 (defun bubbles--show-images () | |
1429 "Update images in the bubbles buffer." | |
1430 (bubbles--remove-overlays) | |
1431 (if (and (display-images-p) | |
1432 bubbles--images-ok | |
1433 (not (eq bubbles-graphics-theme 'ascii))) | |
1434 (save-excursion | |
1435 (goto-char (point-min)) | |
1436 (forward-line 1) | |
1437 (let ((inhibit-read-only t) | |
1438 char) | |
1439 (dotimes (i (bubbles--grid-height)) | |
1440 (dotimes (j (bubbles--grid-width)) | |
1441 (forward-char 1) | |
84565
329f1482e2d6
(bubbles-version): Bump value to "0.5".
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
84539
diff
changeset
|
1442 (let ((index (or (get-text-property (point) 'index) -1))) |
82921 | 1443 (let ((img bubbles--empty-image)) |
1444 (if (>= index 0) | |
1445 (setq img (nth index bubbles--images))) | |
1446 (put-text-property (point) (1+ (point)) | |
1447 'display (cons img nil))))) | |
1448 (forward-line 1)))) | |
1449 (save-excursion | |
1450 (let ((inhibit-read-only t)) | |
1451 (goto-char (point-min)) | |
1452 (while (not (eobp)) | |
1453 (let ((disp-prop (get-text-property (point) 'display))) | |
1454 (if (and (listp disp-prop) | |
1455 (listp (car disp-prop)) | |
1456 (eq (caar disp-prop) 'image)) | |
1457 (put-text-property (point) (1+ (point)) 'display nil)) | |
1458 (forward-char 1))) | |
1459 (put-text-property (point-min) (point-max) 'pointer 'arrow))))) | |
1460 | |
1461 (provide 'bubbles) | |
1462 | |
82929 | 1463 ;; arch-tag: 2cd7237a-b0ad-400d-a7fd-75f676dceb70 |
82921 | 1464 ;;; bubbles.el ends here |