Mercurial > emacs
view lisp/play/tetris.el @ 42602:633233bf2bbf
2002-01-07 Michael Kifer <kifer@cs.stonybrook.edu>
* viper-init.el (viper-cond-compile-for-xemacs-or-emacs):
new macro that replaces viper-emacs-p and viper-xemacs-p in many
cases. Used to reduce the number of warnings.
* viper-cmd.el: use viper-cond-compile-for-xemacs-or-emacs.
(viper-standard-value): moved here from viper.el.
(viper-set-unread-command-events): moved to viper-util.el
(viper-check-minibuffer-overlay): make sure
viper-minibuffer-overlay is moved to cover the entire input field.
* viper-util.el: use viper-cond-compile-for-xemacs-or-emacs.
(viper-read-key-sequence, viper-set-unread-command-events,
viper-char-symbol-sequence-p, viper-char-array-p): moved here.
* viper-ex.el: use viper-cond-compile-for-xemacs-or-emacs.
* viper-keym.el: use viper-cond-compile-for-xemacs-or-emacs.
* viper-mous.el: use viper-cond-compile-for-xemacs-or-emacs.
* viper-macs.el (viper-char-array-p, viper-char-symbol-sequence-p,
viper-event-vector-p): moved to viper-util.el
* viper.el (viper-standard-value): moved to viper-cmd.el.
Use viper-cond-compile-for-xemacs-or-emacs.
* ediff-help.el: use ediff-cond-compile-for-xemacs-or-emacs.
* ediff-hook.el: use ediff-cond-compile-for-xemacs-or-emacs.
* ediff-init.el (ediff-cond-compile-for-xemacs-or-emacs): new
macro designed to be used in many places where ediff-emacs-p or
ediff-xemacs-p was previously used. Reduces the number of
warnings.
Use ediff-cond-compile-for-xemacs-or-emacs in many places in lieue
of ediff-xemacs-p.
(ediff-make-current-diff-overlay, ediff-highlight-diff-in-one-buffer,
ediff-convert-fine-diffs-to-overlays, ediff-empty-diff-region-p,
ediff-whitespace-diff-region-p, ediff-get-region-contents):
moved to ediff-util.el.
(ediff-event-key): moved here.
* ediff-merge.el: got rid of unreferenced variables.
* ediff-mult.el: use ediff-cond-compile-for-xemacs-or-emacs.
* ediff-util.el: use ediff-cond-compile-for-xemacs-or-emacs.
(ediff-cleanup-mess): improved the way windows are set up after
quitting ediff.
(ediff-janitor): use ediff-dispose-of-variant-according-to-user.
(ediff-dispose-of-variant-according-to-user): new function
designed to be smarter and also understands indirect buffers.
(ediff-highlight-diff-in-one-buffer,
ediff-unhighlight-diff-in-one-buffer,
ediff-unhighlight-diffs-totally-in-one-buffer,
ediff-highlight-diff, ediff-highlight-diff,
ediff-unhighlight-diff, ediff-unhighlight-diffs-totally,
ediff-empty-diff-region-p, ediff-whitespace-diff-region-p,
ediff-get-region-contents, ediff-make-current-diff-overlay):
moved here.
(ediff-format-bindings-of): new function by Hannu Koivisto
<azure@iki.fi>.
(ediff-setup): make sure the merge buffer is always widened and
modifiable.
(ediff-write-merge-buffer-and-maybe-kill): refuse to write the
result of a merge into a file visited by another buffer.
(ediff-arrange-autosave-in-merge-jobs): check if the merge file
is visited by another buffer and ask to save/delete that buffer.
(ediff-verify-file-merge-buffer): new function to do the above.
* ediff-vers.el: load ediff-init.el at compile time.
* ediff-wind.el: use ediff-cond-compile-for-xemacs-or-emacs.
* ediff.el (ediff-windows, ediff-regions-wordwise,
ediff-regions-linewise): use indirect buffers to improve
robustness and make it possible to compare regions of the same
buffer (even overlapping regions).
(ediff-clone-buffer-for-region-comparison,
ediff-clone-buffer-for-window-comparison): new functions.
(ediff-files-internal): refuse to compare identical files.
(ediff-regions-internal): get rid of the warning about comparing
regions of the same buffer.
* ediff-diff.el (ediff-convert-fine-diffs-to-overlays): moved here.
Plus the following fixes courtesy of Dave Love:
Doc fixes.
(ediff-word-1): Use word class and move - to the
front per regexp documentation.
(ediff-wordify): Bind forward-word-function outside loop.
(ediff-copy-to-buffer): Use insert-buffer-substring rather than
consing buffer contents.
(ediff-goto-word): Move syntax table setting outside loop.
author | Michael Kifer <kifer@cs.stonybrook.edu> |
---|---|
date | Tue, 08 Jan 2002 04:36:01 +0000 |
parents | 56f1be55a6a2 |
children | 6267794dc181 |
line wrap: on
line source
;;; tetris.el --- implementation of Tetris for Emacs ;; Copyright (C) 1997 Free Software Foundation, Inc. ;; Author: Glynn Clements <glynn@sensei.co.uk> ;; Version: 2.01 ;; Created: 1997-08-13 ;; Keywords: games ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;;; Code: (eval-when-compile (require 'cl)) (require 'gamegrid) ;; ;;;;;;;;;;;;; customization variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar tetris-use-glyphs t "Non-nil means use glyphs when available.") (defvar tetris-use-color t "Non-nil means use color when available.") (defvar tetris-draw-border-with-glyphs t "Non-nil means draw a border even when using glyphs.") (defvar tetris-default-tick-period 0.3 "The default time taken for a shape to drop one row.") (defvar tetris-update-speed-function 'tetris-default-update-speed-function "Function run whenever the Tetris score changes Called with two arguments: (SHAPES ROWS) SHAPES is the number of shapes which have been dropped ROWS is the number of rows which have been completed If the return value is a number, it is used as the timer period.") (defvar tetris-mode-hook nil "Hook run upon starting Tetris.") (defvar tetris-tty-colors [nil "blue" "white" "yellow" "magenta" "cyan" "green" "red"] "Vector of colors of the various shapes in text mode Element 0 is ignored.") (defvar tetris-x-colors [nil [0 0 1] [0.7 0 1] [1 1 0] [1 0 1] [0 1 1] [0 1 0] [1 0 0]] "Vector of colors of the various shapes Element 0 is ignored.") (defvar tetris-buffer-name "*Tetris*" "Name used for Tetris buffer.") (defvar tetris-buffer-width 30 "Width of used portion of buffer.") (defvar tetris-buffer-height 22 "Height of used portion of buffer.") (defvar tetris-width 10 "Width of playing area.") (defvar tetris-height 20 "Height of playing area.") (defvar tetris-top-left-x 3 "X position of top left of playing area.") (defvar tetris-top-left-y 1 "Y position of top left of playing area.") (defvar tetris-next-x (+ (* 2 tetris-top-left-x) tetris-width) "X position of next shape.") (defvar tetris-next-y tetris-top-left-y "Y position of next shape.") (defvar tetris-score-x tetris-next-x "X position of score.") (defvar tetris-score-y (+ tetris-next-y 6) "Y position of score.") (defvar tetris-score-file (concat temporary-file-directory "tetris-scores") ;; anybody with a well-connected server want to host this? ;(defvar tetris-score-file "/anonymous@ftp.pgt.com:/pub/cgw/tetris-scores" "File for holding high scores.") ;; ;;;;;;;;;;;;; display options ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar tetris-border-options '(((glyph colorize) (t ?\+)) ((color-x color-x) (mono-x grid-x) (t nil)) (((glyph color-x) [0.5 0.5 0.5]) (t nil)))) (defvar tetris-blank-options '(((glyph colorize) (t ?\040)) ((color-x color-x) (mono-x grid-x) (color-tty color-tty) (t nil)) (((glyph color-x) [0 0 0]) (color-tty "black") (t nil)))) (defvar tetris-cell-options '(((glyph colorize) (emacs-tty ?O) (t ?\040)) ((color-x color-x) (mono-x mono-x) (color-tty color-tty) (mono-tty mono-tty) (t nil)) ;; color information is taken from tetris-x-colors and tetris-tty-colors )) (defvar tetris-space-options '(((t ?\040)) nil nil)) ;; ;;;;;;;;;;;;; constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defconst tetris-shapes [[[[1 1 0 0] [1 1 0 0] [1 1 0 0] [1 1 0 0]] [[1 1 0 0] [1 1 0 0] [1 1 0 0] [1 1 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] [[[2 2 2 0] [0 2 0 0] [2 0 0 0] [2 2 0 0]] [[0 0 2 0] [0 2 0 0] [2 2 2 0] [2 0 0 0]] [[0 0 0 0] [2 2 0 0] [0 0 0 0] [2 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] [[[3 3 3 0] [3 3 0 0] [0 0 3 0] [3 0 0 0]] [[3 0 0 0] [0 3 0 0] [3 3 3 0] [3 0 0 0]] [[0 0 0 0] [0 3 0 0] [0 0 0 0] [3 3 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] [[[4 4 0 0] [0 4 0 0] [4 4 0 0] [0 4 0 0]] [[0 4 4 0] [4 4 0 0] [0 4 4 0] [4 4 0 0]] [[0 0 0 0] [4 0 0 0] [0 0 0 0] [4 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] [[[0 5 5 0] [5 0 0 0] [0 5 5 0] [5 0 0 0]] [[5 5 0 0] [5 5 0 0] [5 5 0 0] [5 5 0 0]] [[0 0 0 0] [0 5 0 0] [0 0 0 0] [0 5 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] [[[0 6 0 0] [6 0 0 0] [6 6 6 0] [0 6 0 0]] [[6 6 6 0] [6 6 0 0] [0 6 0 0] [6 6 0 0]] [[0 0 0 0] [6 0 0 0] [0 0 0 0] [0 6 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] [[[7 7 7 7] [7 0 0 0] [7 7 7 7] [7 0 0 0]] [[0 0 0 0] [7 0 0 0] [0 0 0 0] [7 0 0 0]] [[0 0 0 0] [7 0 0 0] [0 0 0 0] [7 0 0 0]] [[0 0 0 0] [7 0 0 0] [0 0 0 0] [7 0 0 0]]]]) ;;the scoring rules were taken from "xtetris". Blocks score differently ;;depending on their rotation (defconst tetris-shape-scores [ [6 6 6 6] [6 7 6 7] [6 7 6 7] [6 7 6 7] [6 7 6 7] [5 5 6 5] [5 8 5 8]] ) (defconst tetris-shape-dimensions [[2 2] [3 2] [3 2] [3 2] [3 2] [3 2] [4 1]]) (defconst tetris-blank 0) (defconst tetris-border 8) (defconst tetris-space 9) (defun tetris-default-update-speed-function (shapes rows) (/ 20.0 (+ 50.0 rows))) ;; ;;;;;;;;;;;;; variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar tetris-shape 0) (defvar tetris-rot 0) (defvar tetris-next-shape 0) (defvar tetris-n-shapes 0) (defvar tetris-n-rows 0) (defvar tetris-score 0) (defvar tetris-pos-x 0) (defvar tetris-pos-y 0) (defvar tetris-paused nil) (make-variable-buffer-local 'tetris-shape) (make-variable-buffer-local 'tetris-rot) (make-variable-buffer-local 'tetris-next-shape) (make-variable-buffer-local 'tetris-n-shapes) (make-variable-buffer-local 'tetris-n-rows) (make-variable-buffer-local 'tetris-score) (make-variable-buffer-local 'tetris-pos-x) (make-variable-buffer-local 'tetris-pos-y) (make-variable-buffer-local 'tetris-paused) ;; ;;;;;;;;;;;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar tetris-mode-map (make-sparse-keymap 'tetris-mode-map)) (define-key tetris-mode-map "n" 'tetris-start-game) (define-key tetris-mode-map "q" 'tetris-end-game) (define-key tetris-mode-map "p" 'tetris-pause-game) (define-key tetris-mode-map " " 'tetris-move-bottom) (define-key tetris-mode-map [left] 'tetris-move-left) (define-key tetris-mode-map [right] 'tetris-move-right) (define-key tetris-mode-map [up] 'tetris-rotate-prev) (define-key tetris-mode-map [down] 'tetris-rotate-next) (defvar tetris-null-map (make-sparse-keymap 'tetris-null-map)) (define-key tetris-null-map "n" 'tetris-start-game) ;; ;;;;;;;;;;;;;;;; game functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun tetris-display-options () (let ((options (make-vector 256 nil))) (loop for c from 0 to 255 do (aset options c (cond ((= c tetris-blank) tetris-blank-options) ((and (>= c 1) (<= c 7)) (append tetris-cell-options `((((glyph color-x) ,(aref tetris-x-colors c)) (color-tty ,(aref tetris-tty-colors c)) (t nil))))) ((= c tetris-border) tetris-border-options) ((= c tetris-space) tetris-space-options) (t '(nil nil nil))))) options)) (defun tetris-get-tick-period () (if (boundp 'tetris-update-speed-function) (let ((period (apply tetris-update-speed-function tetris-n-shapes tetris-n-rows nil))) (and (numberp period) period)))) (defun tetris-get-shape-cell (x y) (aref (aref (aref (aref tetris-shapes tetris-shape) y) tetris-rot) x)) (defun tetris-shape-width () (aref (aref tetris-shape-dimensions tetris-shape) (% tetris-rot 2))) (defun tetris-shape-height () (aref (aref tetris-shape-dimensions tetris-shape) (- 1 (% tetris-rot 2)))) (defun tetris-draw-score () (let ((strings (vector (format "Shapes: %05d" tetris-n-shapes) (format "Rows: %05d" tetris-n-rows) (format "Score: %05d" tetris-score)))) (loop for y from 0 to 2 do (let* ((string (aref strings y)) (len (length string))) (loop for x from 0 to (1- len) do (gamegrid-set-cell (+ tetris-score-x x) (+ tetris-score-y y) (aref string x))))))) (defun tetris-update-score () (tetris-draw-score) (let ((period (tetris-get-tick-period))) (if period (gamegrid-set-timer period)))) (defun tetris-new-shape () (setq tetris-shape tetris-next-shape) (setq tetris-rot 0) (setq tetris-next-shape (random 7)) (setq tetris-pos-x (/ (- tetris-width (tetris-shape-width)) 2)) (setq tetris-pos-y 0) (if (tetris-test-shape) (tetris-end-game) (tetris-draw-shape)) (tetris-draw-next-shape) (tetris-update-score)) (defun tetris-draw-next-shape () (loop for y from 0 to 3 do (loop for x from 0 to 3 do (gamegrid-set-cell (+ tetris-next-x x) (+ tetris-next-y y) (let ((tetris-shape tetris-next-shape) (tetris-rot 0)) (tetris-get-shape-cell x y)))))) (defun tetris-draw-shape () (loop for y from 0 to (1- (tetris-shape-height)) do (loop for x from 0 to (1- (tetris-shape-width)) do (let ((c (tetris-get-shape-cell x y))) (if (/= c tetris-blank) (gamegrid-set-cell (+ tetris-top-left-x tetris-pos-x x) (+ tetris-top-left-y tetris-pos-y y) c)))))) (defun tetris-erase-shape () (loop for y from 0 to (1- (tetris-shape-height)) do (loop for x from 0 to (1- (tetris-shape-width)) do (let ((c (tetris-get-shape-cell x y)) (px (+ tetris-top-left-x tetris-pos-x x)) (py (+ tetris-top-left-y tetris-pos-y y))) (if (/= c tetris-blank) (gamegrid-set-cell px py tetris-blank)))))) (defun tetris-test-shape () (let ((hit nil)) (loop for y from 0 to (1- (tetris-shape-height)) do (loop for x from 0 to (1- (tetris-shape-width)) do (unless hit (setq hit (let* ((c (tetris-get-shape-cell x y)) (xx (+ tetris-pos-x x)) (yy (+ tetris-pos-y y)) (px (+ tetris-top-left-x xx)) (py (+ tetris-top-left-y yy))) (and (/= c tetris-blank) (or (>= xx tetris-width) (>= yy tetris-height) (/= (gamegrid-get-cell px py) tetris-blank)))))))) hit)) (defun tetris-full-row (y) (let ((full t)) (loop for x from 0 to (1- tetris-width) do (if (= (gamegrid-get-cell (+ tetris-top-left-x x) (+ tetris-top-left-y y)) tetris-blank) (setq full nil))) full)) (defun tetris-shift-row (y) (if (= y 0) (loop for x from 0 to (1- tetris-width) do (gamegrid-set-cell (+ tetris-top-left-x x) (+ tetris-top-left-y y) tetris-blank)) (loop for x from 0 to (1- tetris-width) do (let ((c (gamegrid-get-cell (+ tetris-top-left-x x) (+ tetris-top-left-y y -1)))) (gamegrid-set-cell (+ tetris-top-left-x x) (+ tetris-top-left-y y) c))))) (defun tetris-shift-down () (loop for y0 from 0 to (1- tetris-height) do (if (tetris-full-row y0) (progn (setq tetris-n-rows (1+ tetris-n-rows)) (loop for y from y0 downto 0 do (tetris-shift-row y)))))) (defun tetris-draw-border-p () (or (not (eq gamegrid-display-mode 'glyph)) tetris-draw-border-with-glyphs)) (defun tetris-init-buffer () (gamegrid-init-buffer tetris-buffer-width tetris-buffer-height tetris-space) (let ((buffer-read-only nil)) (if (tetris-draw-border-p) (loop for y from -1 to tetris-height do (loop for x from -1 to tetris-width do (gamegrid-set-cell (+ tetris-top-left-x x) (+ tetris-top-left-y y) tetris-border)))) (loop for y from 0 to (1- tetris-height) do (loop for x from 0 to (1- tetris-width) do (gamegrid-set-cell (+ tetris-top-left-x x) (+ tetris-top-left-y y) tetris-blank))) (if (tetris-draw-border-p) (loop for y from -1 to 4 do (loop for x from -1 to 4 do (gamegrid-set-cell (+ tetris-next-x x) (+ tetris-next-y y) tetris-border)))))) (defun tetris-reset-game () (gamegrid-kill-timer) (tetris-init-buffer) (setq tetris-next-shape (random 7)) (setq tetris-shape 0 tetris-rot 0 tetris-pos-x 0 tetris-pos-y 0 tetris-n-shapes 0 tetris-n-rows 0 tetris-score 0 tetris-paused nil) (tetris-new-shape)) (defun tetris-shape-done () (tetris-shift-down) (setq tetris-n-shapes (1+ tetris-n-shapes)) (setq tetris-score (+ tetris-score (aref (aref tetris-shape-scores tetris-shape) tetris-rot))) (tetris-update-score) (tetris-new-shape)) (defun tetris-update-game (tetris-buffer) "Called on each clock tick. Drops the shape one square, testing for collision." (if (and (not tetris-paused) (eq (current-buffer) tetris-buffer)) (let (hit) (tetris-erase-shape) (setq tetris-pos-y (1+ tetris-pos-y)) (setq hit (tetris-test-shape)) (if hit (setq tetris-pos-y (1- tetris-pos-y))) (tetris-draw-shape) (if hit (tetris-shape-done))))) (defun tetris-move-bottom () "Drops the shape to the bottom of the playing area" (interactive) (let ((hit nil)) (tetris-erase-shape) (while (not hit) (setq tetris-pos-y (1+ tetris-pos-y)) (setq hit (tetris-test-shape))) (setq tetris-pos-y (1- tetris-pos-y)) (tetris-draw-shape) (tetris-shape-done))) (defun tetris-move-left () "Moves the shape one square to the left" (interactive) (unless (= tetris-pos-x 0) (tetris-erase-shape) (setq tetris-pos-x (1- tetris-pos-x)) (if (tetris-test-shape) (setq tetris-pos-x (1+ tetris-pos-x))) (tetris-draw-shape))) (defun tetris-move-right () "Moves the shape one square to the right" (interactive) (unless (= (+ tetris-pos-x (tetris-shape-width)) tetris-width) (tetris-erase-shape) (setq tetris-pos-x (1+ tetris-pos-x)) (if (tetris-test-shape) (setq tetris-pos-x (1- tetris-pos-x))) (tetris-draw-shape))) (defun tetris-rotate-prev () "Rotates the shape clockwise" (interactive) (tetris-erase-shape) (setq tetris-rot (% (+ 1 tetris-rot) 4)) (if (tetris-test-shape) (setq tetris-rot (% (+ 3 tetris-rot) 4))) (tetris-draw-shape)) (defun tetris-rotate-next () "Rotates the shape anticlockwise" (interactive) (tetris-erase-shape) (setq tetris-rot (% (+ 3 tetris-rot) 4)) (if (tetris-test-shape) (setq tetris-rot (% (+ 1 tetris-rot) 4))) (tetris-draw-shape)) (defun tetris-end-game () "Terminates the current game" (interactive) (gamegrid-kill-timer) (use-local-map tetris-null-map) (gamegrid-add-score tetris-score-file tetris-score)) (defun tetris-start-game () "Starts a new game of Tetris" (interactive) (tetris-reset-game) (use-local-map tetris-mode-map) (let ((period (or (tetris-get-tick-period) tetris-default-tick-period))) (gamegrid-start-timer period 'tetris-update-game))) (defun tetris-pause-game () "Pauses (or resumes) the current game" (interactive) (setq tetris-paused (not tetris-paused)) (message (and tetris-paused "Game paused (press p to resume)"))) (defun tetris-active-p () (eq (current-local-map) tetris-mode-map)) (put 'tetris-mode 'mode-class 'special) (defun tetris-mode () "A mode for playing Tetris. tetris-mode keybindings: \\{tetris-mode-map} " (kill-all-local-variables) (add-hook 'kill-buffer-hook 'gamegrid-kill-timer nil t) (use-local-map tetris-null-map) (setq major-mode 'tetris-mode) (setq mode-name "Tetris") (setq mode-popup-menu '("Tetris Commands" ["Start new game" tetris-start-game] ["End game" tetris-end-game (tetris-active-p)] ["Pause" tetris-pause-game (and (tetris-active-p) (not tetris-paused))] ["Resume" tetris-pause-game (and (tetris-active-p) tetris-paused)])) (setq gamegrid-use-glyphs tetris-use-glyphs) (setq gamegrid-use-color tetris-use-color) (gamegrid-init (tetris-display-options)) (run-hooks 'tetris-mode-hook)) ;;;###autoload (defun tetris () "Play the Tetris game. Shapes drop from the top of the screen, and the user has to move and rotate the shape to fit in with those at the bottom of the screen so as to form complete rows. tetris-mode keybindings: \\<tetris-mode-map> \\[tetris-start-game] Starts a new game of Tetris \\[tetris-end-game] Terminates the current game \\[tetris-pause-game] Pauses (or resumes) the current game \\[tetris-move-left] Moves the shape one square to the left \\[tetris-move-right] Moves the shape one square to the right \\[tetris-rotate-prev] Rotates the shape clockwise \\[tetris-rotate-next] Rotates the shape anticlockwise \\[tetris-move-bottom] Drops the shape to the bottom of the playing area " (interactive) (switch-to-buffer tetris-buffer-name) (gamegrid-kill-timer) (tetris-mode) (tetris-start-game)) (provide 'tetris) ;;; tetris.el ends here