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