]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow different randomization of shapes in Tetris
authorTimothee Denizou <timothee.denizou@epita.fr>
Tue, 21 Jun 2022 19:50:15 +0000 (21:50 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 21 Jun 2022 19:50:15 +0000 (21:50 +0200)
* lisp/play/tetris.el (tetris-allow-repetitions): New user option.
(tetris--shuffle, tetris--seven-bag): New functions.
(tetris-new-shape): Use the option.

* Added 7 bag randomizer for tetris
A piece is selected from the bag and removed each time we want a piece
When the bag is empty, refill the bag with the seven piece and shuffle it

Copyright-paperwork-exempt: yes

lisp/play/tetris.el

index 8ce2453c753646be14d5552c686bbf254c56c0a7..af1004e08111f2468020b903f5b5098aeaae16d1 100644 (file)
@@ -117,6 +117,13 @@ If the return value is a number, it is used as the timer period."
   "Y position of top left of playing area."
   :type 'number)
 
+(defcustom tetris-allow-repetitions t
+  "If non-nil, use a random selection for each shape.
+If nil, put the shapes into a bag and select without putting
+back (until empty, when the bag is repopulated."
+  :type 'boolean
+  :version "29.1")
+
 (defvar tetris-next-x (+ (* 2 tetris-top-left-x) tetris-width)
   "X position of next shape.")
 
@@ -233,6 +240,7 @@ each one of its four blocks.")
 (defvar-local tetris-pos-x 0)
 (defvar-local tetris-pos-y 0)
 (defvar-local tetris-paused nil)
+(defvar-local tetris--bag nil)
 
 ;; ;;;;;;;;;;;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -341,10 +349,23 @@ each one of its four blocks.")
   (let ((period (tetris-get-tick-period)))
     (if period (gamegrid-set-timer period))))
 
+(defun tetris--shuffle (sequence)
+  (cl-loop for i from (length sequence) downto 2
+           do (cl-rotatef (elt sequence (random i))
+                          (elt sequence (1- i))))
+  sequence)
+
+(defun tetris--seven-bag ()
+  (when (not tetris--bag)
+    (setq tetris--bag (tetris--shuffle (list 0 1 2 3 4 5 6))))
+  (pop tetris--bag))
+
 (defun tetris-new-shape ()
   (setq tetris-shape tetris-next-shape)
   (setq tetris-rot 0)
-  (setq tetris-next-shape (random 7))
+  (setq tetris-next-shape (if tetris-allow-repetitions
+                              (tetris--seven-bag)
+                            (random 7)))
   (setq tetris-pos-x (/ (- tetris-width (tetris-shape-width)) 2))
   (setq tetris-pos-y 0)
   (if (tetris-test-shape)