Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / lisp / play / bubbles.el
index 4d853e5..a786f68 100644 (file)
@@ -1,6 +1,6 @@
-;;; bubbles.el --- Puzzle game for Emacs.
+;;; bubbles.el --- Puzzle game for Emacs
 
-;; Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+;; Copyright (C) 2007-2012  Free Software Foundation, Inc.
 
 ;; Author:      Ulf Jasper <ulf.jasper@web.de>
 ;; URL:         http://ulf.epplejasper.de/
@@ -55,7 +55,7 @@
 
 ;; 0.3 (2007-03-11)
 ;;     - Renamed shift modes and thus names of score files. All
-;;       highscores are lost, unless you rename the score files from
+;;       high scores are lost, unless you rename the score files from
 ;;       bubbles-shift-... to bubbles-...!
 ;;     - Bugfixes: Check for successful image creation.
 ;;                 Disable menus and counter when game is over.
@@ -82,7 +82,7 @@
 (defconst bubbles-version "0.5" "Version number of bubbles.el.")
 
 (require 'gamegrid)
-(require 'cl)
+(eval-when-compile (require 'cl))       ; for 'case
 
 ;; User options
 
@@ -209,7 +209,7 @@ the number of colors, see `bubbles-colors'."
 (defcustom bubbles-shift-mode
   'default
   "Shift mode.
-Available modes are `shift-default' and`shift-always'."
+Available modes are `shift-default' and `shift-always'."
   :type '(radio (const :tag "Default" default)
                 (const :tag "Shifter" always)
                 ;;(const :tag "Mega Shifter" 'mega)
@@ -233,7 +233,7 @@ Available modes are `shift-default' and`shift-always'."
   "Current Bubbles score.")
 
 (defvar bubbles--neighbourhood-score 0
-  "Score of active bubbles neighbourhood.")
+  "Score of active bubbles neighborhood.")
 
 (defvar bubbles--faces nil
   "List of currently used faces.")
@@ -719,57 +719,57 @@ static char * dot3d_xpm[] = {
 (defsubst bubbles--grid-width ()
   "Return the grid width for the current game theme."
   (car (case bubbles-game-theme
-         ('easy
+         (easy
           bubbles--grid-small)
-         ('medium
+         (medium
           bubbles--grid-medium)
-         ('difficult
+         (difficult
           bubbles--grid-large)
-         ('hard
+         (hard
           bubbles--grid-huge)
-         ('user-defined
+         (user-defined
           bubbles-grid-size))))
 
 (defsubst bubbles--grid-height ()
   "Return the grid height for the current game theme."
   (cdr (case bubbles-game-theme
-         ('easy
+         (easy
           bubbles--grid-small)
-         ('medium
+         (medium
           bubbles--grid-medium)
-         ('difficult
+         (difficult
           bubbles--grid-large)
-         ('hard
+         (hard
           bubbles--grid-huge)
-         ('user-defined
+         (user-defined
           bubbles-grid-size))))
 
 (defsubst bubbles--colors ()
   "Return the color list for the current game theme."
   (case bubbles-game-theme
-    ('easy
+    (easy
      bubbles--colors-2)
-    ('medium
+    (medium
      bubbles--colors-3)
-    ('difficult
+    (difficult
      bubbles--colors-4)
-    ('hard
+    (hard
      bubbles--colors-5)
-    ('user-defined
+    (user-defined
      bubbles-colors)))
 
 (defsubst bubbles--shift-mode ()
   "Return the shift mode for the current game theme."
   (case bubbles-game-theme
-    ('easy
+    (easy
      'default)
-    ('medium
+    (medium
      'default)
-    ('difficult
+    (difficult
      'always)
-    ('hard
+    (hard
      'always)
-    ('user-defined
+    (user-defined
      bubbles-shift-mode)))
 
 (defun bubbles-save-settings ()
@@ -782,7 +782,7 @@ static char * dot3d_xpm[] = {
 
 (defsubst bubbles--empty-char ()
   "The character used for removed bubbles (empty grid cells)."
-  ? )
+  ?\s)
 
 (defun bubbles-set-graphics-theme-ascii ()
   "Set graphics theme to `ascii'."
@@ -918,24 +918,30 @@ static char * dot3d_xpm[] = {
     map)
   "Mode map for bubbles.")
 
-(defun bubbles-mode ()
+(define-derived-mode bubbles-mode nil "Bubbles"
   "Major mode for playing bubbles.
 \\{bubbles-mode-map}"
-  (kill-all-local-variables)
-  (use-local-map bubbles-mode-map)
-  (setq major-mode 'bubbles-mode)
-  (setq mode-name "Bubbles")
-  (setq buffer-read-only t)
+  (setq buffer-read-only t
+        show-trailing-whitespace nil)
   (buffer-disable-undo)
-  (setq buffer-undo-list t)
   (force-mode-line-update)
   (redisplay)
-  (add-hook 'post-command-hook 'bubbles--mark-neighbourhood t t)
-  (run-hooks 'bubbles-mode-hook))
+  (add-hook 'post-command-hook 'bubbles--mark-neighbourhood t t))
 
 ;;;###autoload
 (defun bubbles ()
-  "Play Bubbles game."
+  "Play Bubbles game.
+\\<bubbles-mode-map>
+The goal is to remove all bubbles with as few moves as possible.
+\\[bubbles-plop] on a bubble removes that bubble and all
+connected bubbles of the same color.  Unsupported bubbles fall
+down, and columns that do not contain any bubbles suck the
+columns on its right towards the left.
+
+\\[bubbles-set-game-easy] sets the difficulty to easy.
+\\[bubbles-set-game-medium] sets the difficulty to medium.
+\\[bubbles-set-game-difficult] sets the difficulty to difficult.
+\\[bubbles-set-game-hard] sets the difficulty to hard."
   (interactive)
   (switch-to-buffer (get-buffer-create "*bubbles*"))
   (when (or (not bubbles--playing)
@@ -950,6 +956,8 @@ static char * dot3d_xpm[] = {
   (message "bubbles-quit")
   (bury-buffer))
 
+(declare-function image-size "image.c" (spec &optional pixels frame))
+
 (defun bubbles--compute-offsets ()
   "Update horizontal and vertical offsets for centering the bubbles grid.
 Set `bubbles--col-offset' and `bubbles--row-offset'."
@@ -1081,7 +1089,7 @@ Set `bubbles--col-offset' and `bubbles--row-offset'."
       nil)))
 
 (defun bubbles--mark-direct-neighbours (row col char)
-  "Mark direct neighbours of bubble at ROW COL with same CHAR."
+  "Mark direct neighbors of bubble at ROW COL with same CHAR."
   (save-excursion
     (let ((count 0))
       (when (and (bubbles--goto row col)
@@ -1097,7 +1105,7 @@ Set `bubbles--col-offset' and `bubbles--row-offset'."
       count)))
 
 (defun bubbles--mark-neighbourhood (&optional pos)
-  "Mark neighbourhood of point.
+  "Mark neighborhood of point.
 Use optional parameter POS instead of point if given."
   (when bubbles--playing
     (unless pos (setq pos (point)))
@@ -1122,7 +1130,7 @@ Use optional parameter POS instead of point if given."
       (error (message "Bubbles: Internal error %s" err)))))
 
 (defun bubbles--neighbourhood-available ()
-  "Return t if another valid neighbourhood is available."
+  "Return t if another valid neighborhood is available."
   (catch 'found
     (save-excursion
       (dotimes (i (bubbles--grid-height))
@@ -1152,12 +1160,12 @@ Use optional parameter POS instead of point if given."
   (bubbles--update-score))
 
 (defun bubbles--update-score ()
-  "Calculate and display new bubble score."
+  "Calculate and display new bubbles score."
   (setq bubbles--score (+ bubbles--score bubbles--neighbourhood-score))
   (bubbles--show-scores))
 
 (defun bubbles--update-neighbourhood-score (size)
-  "Calculate and display score of active neighbourhood from its SIZE."
+  "Calculate and display score of active neighborhood from its SIZE."
   (if (> size 1)
       (setq bubbles--neighbourhood-score (expt (- size 1) 2))
     (setq bubbles--neighbourhood-score 0))
@@ -1310,8 +1318,7 @@ Use optional parameter POS instead of point if given."
 Return t if new char is non-empty."
   (save-excursion
     (when (bubbles--goto row col)
-      (let ((char-org (char-after (point)))
-            (char-new (bubbles--empty-char))
+      (let ((char-new (bubbles--empty-char))
             (removed nil)
             (trow row)
             (tcol col)
@@ -1339,11 +1346,11 @@ Return t if new char is non-empty."
   (when (and (display-images-p)
              (not (eq bubbles-graphics-theme 'ascii)))
     (let ((template (case bubbles-graphics-theme
-                      ('circles bubbles--image-template-circle)
-                      ('balls bubbles--image-template-ball)
-                      ('squares bubbles--image-template-square)
-                      ('diamonds bubbles--image-template-diamond)
-                      ('emacs bubbles--image-template-emacs))))
+                      (circles bubbles--image-template-circle)
+                      (balls bubbles--image-template-ball)
+                      (squares bubbles--image-template-square)
+                      (diamonds bubbles--image-template-diamond)
+                      (emacs bubbles--image-template-emacs))))
       (setq bubbles--empty-image
             (create-image (replace-regexp-in-string
                            "^\"\\(.*\\)\t.*c .*\",$"
@@ -1370,7 +1377,7 @@ Return t if new char is non-empty."
                                    (g (nth 1 crgb))
                                    (b (nth 2 crgb))
                                    (brightness (/ (+ r g b) 3.0 256 256))
-                                   (val (sin (* brightness (/ pi 2))))
+                                   (val (sin (* brightness (/ float-pi 2))))
                                    (rr (* red val))
                                    (gg (* green val))
                                    (bb (* blue val))
@@ -1409,9 +1416,8 @@ Return t if new char is non-empty."
           (dotimes (i (bubbles--grid-height))
             (dotimes (j (bubbles--grid-width))
               (bubbles--goto i j)
-              (let* ((index (get-text-property (point) 'index))
-                     (face (nth index bubbles--faces))
-                     (fg-col (face-foreground face)))
+              (let ((face (nth (get-text-property (point) 'index)
+                               bubbles--faces)))
                 (when (get-text-property (point) 'active)
                   (set-face-foreground 'bubbles--highlight-face "#ff0000")
                   (setq face 'bubbles--highlight-face))
@@ -1427,8 +1433,7 @@ Return t if new char is non-empty."
       (save-excursion
         (goto-char (point-min))
         (forward-line 1)
-        (let ((inhibit-read-only t)
-              char)
+        (let ((inhibit-read-only t))
           (dotimes (i (bubbles--grid-height))
             (dotimes (j (bubbles--grid-width))
               (forward-char 1)
@@ -1453,5 +1458,4 @@ Return t if new char is non-empty."
 
 (provide 'bubbles)
 
-;; arch-tag: 2cd7237a-b0ad-400d-a7fd-75f676dceb70
 ;;; bubbles.el ends here