[comp.sys.handhelds] Faster Tetris

a634@mindlink.UUCP (Rob Prior) (11/19/90)

Here it is, for you that didn't get itthe first time... :)

Sun Nov 18 01:01:50 1990
Message : #1027542    From: erikmb@cd.chalmers.se
Group   : NETCOMP.HandHeld
Length  : 875 words 5428 bytes
Subject : FAST TETRIS FOR HP-48SX (NOT TETRAS!)

Msg-ID: <9011171106.AA03996@cd.chalmers.se>
Posted: 17 Nov 90 11:06:45 GMT

Person: Erik Bryntse


TETRIS (NOT TETRAS BUT ANYWAY...)

Since everybody is screaming for the mysterious TETRAS, I am posting my own
TETRIS so that you will have something to play while waiting...

It is basically an RPL-program, but I have written two ML-routines that
handles the blocks on screen. This makes it fast enough. Here is a short
description of these


XFIG

Puts figure on screen. Coordinates are measured in 4x4 screen pixels.
XX is the X coordinate from 0..32
Y is the Y coordinate from 0..15

IN: 3: # YXXYXXYXXh     the figure with up to five blocks in it
    2: # YXXh           the position of upper-left corner of figure
    1: # QQQQh          the bit pattern of the blocks that makes up the figure

OUT: -


TFIG

Tests if figure is on screen. Only looks at THE UPPER ROW of each block!

IN:  2: # YXXYXXh       the figure as above
     1: # YXXh          the position of figure

OUT: 1: # 2h            if all of the blocks in fig is on screen
        # 1h            if some of the blocks is on screen
        # 0h            if none of the block is on screen

The output argument is not "free"; it uses the memory of the level 1 input
argument.

This means that if you write a program << # 103h # 504h TFIG >> the # 504h
in the program will change every time you run it! Use instead # 0h OR TFIG to
come around this problem (yes I could have made the ML-program better but
it works...).

Some error checking are done, ie that there are the right number of binaries
on stack. However NO RANGE checking is made so these routines will happily
overwrite your memory if you pass them out-of-range coordinates.

Download the directory below, run ASC-> on TFIG and XFIG, and press TETRIS
to start the game.

Use the left- and right arrows to move, up-arrow to rotate and down-arrow to
drop the block.

==================================CUT
HERE======================================
%%HP: T(3)A(R)F(.);
DIR
  TETRIS
    \<< 1 CF MKSCR 0
'PNTS' STO 0 ADDP
      DO FLST RAND
7 * IP 1 + DUP
'OB1' STO GET 1 DUP
'OB2' STO GET # Bh
1 CF
        DO
          IF 1 FC?
          THEN RK2
RK2 RK2 RK2
          END DUP2
# 0h XFIG # 100h +
DUP2 # 0h + TFIG
          IF # 0h
==
          THEN DUP2
# F99Fh XFIG
          ELSE
# 100h - # F99Fh
XFIG # 0h
          END
        UNTIL DUP
# 0h ==
        END 20 ADDP
DROP PACK MEM DROP
      UNTIL FULL
      END 2 WAIT
      WHILE KEY
      REPEAT DROP
      END
    \>>
  MKSCR
    \<< PICT PURGE {
# 54h # 3Ch } {
# 54h # 0h } OVER
LINE { # 2Bh # 3Ch
} DUP ROT LINE {
# 2Bh # 0h } LINE
PICT { # 58h # Ah }
IPIC REPL { # 0h
# 0h } PVIEW
    \>>
  RK2
    \<<
      IF KEY
      THEN
        IF { 34 36
35 25 } SWAP POS
DUP
        THEN {
          \<< # 1h
NEG MSIDE
          \>>
          \<< # 1h
MSIDE
          \>>
          \<< 1 SF
          \>> ROTF }
SWAP GET EVAL
        ELSE DROP
        END
      END
    \>>
  ADDP
    \<< 'PNTS' STO+
PICT { # 5h # 5h }
PNTS 2 \->GROB REPL
    \>>
  MSIDE
    \<< \-> CD
      \<< DUP2 # 0h
XFIG CD + DUP2 # 0h
+ TFIG
        IF # 0h \=/
        THEN CD -
        END DUP2
# F99Fh XFIG
      \>>
    \>>
  TFIG  @ Use ASC->
"CCD20E310013606DD061B97507142137135818F098BA606FF014713481AF0914
234E4A208A26060E01691527100E717414381AF2914581AF291321428A26060B
01691567AFAAF1D122A95118C9D5F522A8520A81819F122A82C1201B56507146
818F29818F29C9136AF2156090A90B456E002F308200E49BF4BF4BF4AF68AE09
AF0AF2AC48108087340E68084396840E614313216915472007DD071361421648
08C3CA6"
  XFIG  @ Use ASC->
"CCD204410034E7507137143818F8E1358BE60691117E818F328FB97601CE1B56
507146134152739E1B20F880029916912014313234E4A201428A2606EB016915
271011741431321428A63E16915271001741431321428A68C1691567AFAAF122
A95118C9AF5BF522A8520A8181D22A82C1201B56507146818F29818F29C91341
19BF2BF2241542BF616F16F1610D880BEBF4BF4BF4AF68AA60688F208F2D7601
42164808CE7C9"
  ROTF
    \<< DUP2 # 0h
XFIG FLST OB1 GET
OB2 1 -
      IF DUP 0 \<=
      THEN DROP DUP
SIZE
      END DUP \-> OS2
      \<< GET SWAP
DUP2 # 0h + TFIG
        IF # 0h ==
        THEN ROT
DROP OS2 'OB2' STO
        ELSE SWAP
DROP
        END DUP2
# F99Fh XFIG
      \>>
    \>>
  OB2 1
  OB1 5
  PNTS 740
  FLST { {
# 103104105204h
# 4104204103h
# 203204205104h
# 4104204105h } {
# 4104204005h
# 103104105205h
# 4104204203h
# 103203204205h } {
# 3004104204h
# 105203204205h
# 4104204205h
# 103104105203h } {
# 4104103203h
# 103104204205h } {
# 3103104204h
# 203204104105h } {
# 302303304305h
# 4104204304h } {
# 3004103104h } }
  RKEY
    \<<
      IF KEY
      THEN
        IF DUP 34
==
        THEN DROP
# 1h NEG MSIDE 1
        END
        IF DUP 36
==
        THEN DROP
# 1h MSIDE 1
        END
        IF DUP 35
==
        THEN 1 SF
        END
        IF 25 ==
        THEN ROTF
        END
      END
    \>>
  TLIN
    \<< DUP
# 101102103104105h
SWAP DUP2 # 0h +
TFIG ROT ROT # 5h +
TFIG +
    \>>
  IPIC
GROB 40 43
0000000000EFE7F7F9C30120801A240120801A200120801A2001E380F9C30120
8058040120809804012080192401E7801AC30000000000000000000000000000
000000000000C1416067724001A04555CC556047754443A04445C54562422200
0000000000000000000000000000000000000000000000000
  PACK
    \<< # D0Ah
      DO TLIN
        IF # 4h ==
        THEN P2
        ELSE # 100h
-
        END
      UNTIL DUP
# 200h <
      END DROP
    \>>
  P2
    \<< 100 ADDP DUP
# F00h AND SRB 4 *
3 + # 28h SWAP 2
\->LIST PICT SWAP {
# 55h # 8h } SUB
PICT { # 28h # Ch }
ROT REPL
    \>>
  FULL
    \<<
# 101102103104105h
# 30Ah DUP2 # 0h +
TFIG ROT ROT # 5h +
TFIG + # 0h >
    \>>
END
==================================CUT
HERE======================================


Enjoy!


Erik Bryntse

-=*=-

Here's the update... :)

Replace:  TETRIS, RK2 with the new ones below
Delete:   RKEY (presumably a test version of RK2, doesn't do anything)
Add:      delay, a (a will be created by the new TETRIS, if you like)

Everything else stays the same.  Enjoy the revision!

The programs:

==================================CUT
HERE======================================
  TETRIS
    \<< .101 'a' STO 1            @ Initializes the delay timer
CF MKSCR 0 'PNTS'
STO 0 ADDP
      DO delay FLST               @ Decreases the delay before
RAND 7 * IP 1 + DUP               @ each piece is displayed
'OB1' STO GET 1 DUP
'OB2' STO GET # 11d
1 CF
        DO
          IF 1 FC?
          THEN RK2
RK2 RK2 RK2
          END DUP2
# 0d XFIG # 256d +
DUP2 # 0d + TFIG
          IF # 0d
==
          THEN DUP2
# 63903d XFIG
          ELSE
# 256d - # 63903d
XFIG # 0d
          END
        UNTIL DUP
# 0d ==
        END 20 ADDP
DROP PACK MEM DROP
      UNTIL FULL
      END 2 WAIT
      WHILE KEY
      REPEAT DROP
      END
    \>>

  RK2
    \<<
      IF KEY
      THEN
        IF { 72 74
73 63 } SWAP POS
DUP
        THEN {
          \<< # 1d
NEG MSIDE
          \>>
          \<< # 1d
MSIDE
          \>>
          \<< 1 SF
          \>> ROTF }
SWAP GET EVAL
        ELSE DROP
        END
      END a WAIT                  @ Waits the specified time
    \>>

  delay                           @ The program that changes the
    \<< a .001 - DUP              @ wait time
      IF 0 \<=
      THEN 0 'a'
STO DROP
      ELSE 'a' STO
      END
    \>>

  a .101                          @ the delay
==================================CUT
HERE======================================

--
 _______________________________________________________________
|Rob Prior - President, Still Animation Logo Design, Burnaby, BC|
|---------------------------------------------------------------|
|            Mail to: a634@mindlink.uucp                        |
|   ___  _        or: !uunet!van-bc!rsoft!mindlink!a634         |
|  /__  /_\    "You must find us.... a shrubbery!!!!!!"         |
|____/ /   \____________________________________________________|

a634@mindlink.UUCP (Rob Prior) (11/20/90)

To all of you who have sent me e-mail;

(1) I didn't write the original version, so stop asking me how to
    change this and that.  I don't know.

(2) The update I posted has changed the keyboard layout for controlling
    the blocks.  The new layout is:

                     Rotate Counter Clockwise
                              [8]
               Move Left  [4] [5] [6] Move Right
                               |
                              Drop

(3) If anyone is interested, you can put a pause key into the program
    by modifying the RK2 program even further:

RK2
\<<
   IF KEY    THEN                /-------------------- 11 is the 'A' key
(pause)
     IF { 72 74 73 63 11 } SWAP POS DUP
     THEN { << program to move left >>
            << program to move right >>
            << program to drop >>
            ROTF
            << DO UNTIL KEY END DROP >> }  @ This pauses until a key
     SWAP GET EVAL                         @ is pressed.
     ELSE DROP
     END
   END a WAIT
>>

(4) I have a new version of the IPIC program that shows the key
    layout (I just wrote it today, so give me a day to post it).

(5) Could the person who wrote the original please mail me?  I would
    like to change it to use [7] to rotate left and [9] to rotate
    right.  I'm not a real programmer, and I can't figure out how
    to do that fix on my own.

That's it!

Rob
--
 _______________________________________________________________
|Rob Prior - President, Still Animation Logo Design, Burnaby, BC|
|---------------------------------------------------------------|
|            Mail to: a634@mindlink.uucp                        |
|   ___  _        or: !uunet!van-bc!rsoft!mindlink!a634         |
|  /__  /_\    "You must find us.... a shrubbery!!!!!!"         |
|____/ /   \____________________________________________________|

frechett@boulder.Colorado.EDU (-=Runaway Daemon=-) (11/21/90)

ERk.. Could you please repost or send the directory in full. The reason is that
applying the patches that you tack onto the end is not only a pain but it
doesn't work.  When everything is set up the way that you specify, the controls
are dead.  It drops everything fine. But you can't rotate or move the blocks.
I am not ignorant of what I am doing and it just simply doesn't work right.

	ian
--
-=Runaway Daemon=-

bgribble@jarthur.Claremont.EDU (Bill Gribble) (11/21/90)

In article <30064@boulder.Colorado.EDU> frechett@snoopy.Colorado.EDU (-=Runaway Daemon=-) writes:

>ERk.. Could you please repost or send the directory in full. The reason is that
>applying the patches that you tack onto the end is not only a pain but it
>doesn't work.  When everything is set up the way that you specify, the controls
>are dead.  It drops everything fine. But you can't rotate or move the blocks.
>I am not ignorant of what I am doing and it just simply doesn't work right.
>
>	ian

(this from the man who just posted the Game Flame) 

Yes, it works - the conbtrols are just different.  The new ones are 
  4 and 6 to move, 8 to rotate, and 5 to drop the block.

*****************************************************************************
**   Bill Gribble                     Harvey Mudd College, Claremont, CA   **
**   bgribble@jarthur.claremont.edu   Never heard of it?  You're stupid.   **
*****************************************************************************

rob@ireta.wimsey.bc.ca (Rob Prior) (11/23/90)

Okay, at Eric's request I am posting my latest update to the
fast version of TETRIS.  It has a different keyboard layout
than the first version:

                      Rotate
                        [8]
          Move Left [4] [5] [6] Move Right
                         |
                       Drop

This was done to give your fingers more room to move when
playing.  It is personal preference, and can be changed by
modifying the RK2 program.

This version also uses [A] as a pause key.  It just puts the
game into an endless loop until a key is pressed, so you can't
pause the game and turn off the calculator.  I guess this could
have been done, but I wrote it for the odd time that the boss
walks by... :)

It has a new screen display, and it shows the keyboard layout.
(Don't forget to put the GROB for IPIC onto one line before
 uploading to the 48)

Anyways, enough chatter, here it is!

-=*=- Cut Here -=*=-
%%HP: T(3)A(D)F(.);
DIR
  PPAR {
(-6.5,-3.1)
(6.5,3.2) X 0 (0,0)
FUNCTION Y }
  TETRIS
    \<< .101 'a' STO
1 CF MKSCR 0 'PNTS'
STO 0 ADDP
      DO delay FLST
RAND 7 * IP 1 + DUP
'OB1' STO GET 1 DUP
'OB2' STO GET # 11d
1 CF
        DO
          IF 1 FC?
          THEN RK2
RK2 RK2 RK2
          END DUP2
# 0d XFIG # 256d +
DUP2 # 0d + TFIG
          IF # 0d
==
          THEN DUP2
# 63903d XFIG
          ELSE
# 256d - # 63903d
XFIG # 0d
          END
        UNTIL DUP
# 0d ==
        END 20 ADDP
DROP PACK MEM DROP
      UNTIL FULL
      END 2 WAIT
      WHILE KEY
      REPEAT DROP
      END
    \>>
  PNTS 5340
  a .0000001
  MKSCR
    \<< PICT PURGE {
# 84d # 60d } {
# 84d # 0d } OVER
LINE { # 43d # 60d
} DUP ROT LINE {
# 43d # 0d } LINE
PICT { # 88d # 0d }
IPIC REPL { # 0d
# 0d } PVIEW
    \>>
  RK2
    \<<
      IF KEY
      THEN
        IF { 72 74
73 63 11 } SWAP POS
DUP
        THEN {
          \<< # 1d
NEG MSIDE
          \>>
          \<< # 1d
MSIDE
          \>>
          \<< 1 SF
          \>> ROTF
          \<<
            DO
            UNTIL
KEY
            END
DROP
          \>> } SWAP
GET EVAL
        ELSE DROP
        END
      END a WAIT
    \>>
  ADDP
    \<< 'PNTS' STO+
PICT { # 5d # 5d }
PNTS 2 \->GROB REPL
    \>>
  MSIDE
    \<< \-> CD
      \<< DUP2 # 0d
XFIG CD + DUP2 # 0d
+ TFIG
        IF # 0d \=/
        THEN CD -
        END DUP2
# 63903d XFIG
      \>>
    \>>
  TFIG    @ Use ASC->
"CCD20E310013606DD061B97507142137135818F098BA606FF014713481AF0914
234E4A208A26060E01691527100E717414381AF2914581AF291321428A26060B
01691567AFAAF1D122A95118C9D5F522A8520A81819F122A82C1201B56507146
818F29818F29C9136AF2156090A90B456E002F308200E49BF4BF4BF4AF68AE09
AF0AF2AC48108087340E68084396840E614313216915472007DD071361421648
08C3CA6"
  XFIG    @ Use ASC->
"CCD204410034E7507137143818F8E1358BE60691117E818F328FB97601CE1B56
507146134152739E1B20F880029916912014313234E4A201428A2606EB016915
271011741431321428A63E16915271001741431321428A68C1691567AFAAF122
A95118C9AF5BF522A8520A8181D22A82C1201B56507146818F29818F29C91341
19BF2BF2241542BF616F16F1610D880BEBF4BF4BF4AF68AA60688F208F2D7601
42164808CE7C9"
  ROTF
    \<< DUP2 # 0d
XFIG FLST OB1 GET
OB2 1 -
      IF DUP 0 \<=
      THEN DROP DUP
SIZE
      END DUP \-> OS2
      \<< GET SWAP
DUP2 # 0d + TFIG
        IF # 0d ==
        THEN ROT
DROP OS2 'OB2' STO
        ELSE SWAP
DROP
        END DUP2
# 63903d XFIG
      \>>
    \>>
  OB2 1
  OB1 4
  FLST { {
# 17802707620356d
# 279242096899d
# 35399189680388d
# 279242096901d } {
# 279242096645d
# 17802707620357d
# 279242097155d
# 17806986854917d }
{ # 206226604548d
# 17944425808389d
# 279242097157d
# 17802707620355d }
{ # 279241044483d
# 17802708664837d }
{ # 210504794628d
# 35399188627717d }
{ # 52926935483141d
# 279242097412d } {
# 206226600196d } }
  TLIN
    \<< DUP
# 72356802986000645d
SWAP DUP2 # 0d +
TFIG ROT ROT # 5d +
TFIG +
    \>>
  IPIC
GROB 40 63     @ Make this all one line before U/L'ing to the 48
0000000000EFFFFFFFF7A480800125EFFFFFFFF70000000000EFE7F7F9C30120
801A240120801A200120801A2001E380F9C30120805804012080980401208019
2401E7801AC30000000000EFFFFFFFF7A480800125EFFFFFFFF7000000000000
000000000000000000EF3000000020200000002220032567252005551127AA23
7523252001554125200157372020000000EF3000000000000000000000000000
00088700000008580000000830100000087010000008F0100000000000000000
FF10000000101000000093100000009210000000931000000092100000009310
00000010100000FFFFFF10021010109003909393918392909093C7939393D783
121292930312939391021010109000FFFFFF1000000000000000010000000001
00000000EF00000000C70000000083000000000100000000000000
  delay
    \<< a .001 - DUP
      IF .001 \<=
      THEN .0000001
'a' STO DROP
      ELSE 'a' STO
      END
    \>>
  PACK
    \<< # 3338d
      DO TLIN
        IF # 4d ==
        THEN P2
        ELSE # 256d
-
        END
      UNTIL DUP
# 512d <
      END DROP
    \>>
  P2
    \<< 100 ADDP DUP
# 3840d AND SRB 4 *
3 + # 40d SWAP 2
\->LIST PICT SWAP {
# 85d # 8d } SUB
PICT { # 40d # 12d
} ROT REPL
    \>>
  FULL
    \<<
# 72356802986000645d
# 778d DUP2 # 0d +
TFIG ROT ROT # 5d +
TFIG + # 0d >
    \>>
END
-=*=- Cut Here -=*=-

+---------
| rob@ireta.wimsey.bc.ca
| Rob Prior, President, Still Animation Logo Design
+----------------------------------------------------------

jmorriso@ee.ubc.ca (John Paul Morrison) (11/29/90)

There is a "bug" in the Tetris games that can corrupt memory, or cause a
"memory lost"
to occur. In the original documentation, the programs XFIG is documented
as not checking 
bounds when it writes to screen memory. If you play tetris with FIXed
mode on, (or whatever)
or if you get an obscenely high score, the score will  extend into the
game area. In addition
when you break down a whole row, this part of the screen scrolls down,
and copies the score
down too. Big problems happen if a block falling down hits the score on
screen. TFIG can get confused, and weird things can happen. With this
effect I have had the blocks move 
outside the normal playing area, and they can go all over the screen and
scroll off (presumably  into other partts of memory).

No problems may appear at first, but objects residing in the same
directory or above can get
thrashed, or a memory lost can occur while playing.

Bug fix: put the calculator into STD mode. IF you somehow get a huge
score, stop playing when
the score extends into the playing region.

jpm

frechett@boulder.Colorado.EDU (-=Runaway Daemon=-) (11/30/90)

OK, that post makes sense, with one exception.  There is a better way to do
the pause.  I also used the A key but did it much simpler.  In RK2
where you assign what the 11 key does.  Use this instead.
<< 0 WAIT DROP >>   That will pause the calc completely until the next key
press.  Or I have also tried << OFF >> which works very well.  Good 
surprize for when you lend someone the calc.  The other thing that I added
was a call for PNTS at the end of TETRIS, so that it dumps the final score 
after it is done.  A friend of mine has it set up to start with a delay of 
.075 and decrease by .017 each block and he scored 11900  ;)  scary.  

	ian
--
-=Runaway Daemon=-

robert@longs.LANCE.ColoState.Edu (Robert D. Thompson) (12/04/90)

*> Relay-Version: VMS News - V6.0 13/10/90 VAX/VMS ......

*> Newsgroups: comp.sys.handhelds
*> Subject: Re: Faster Tetris (again)
*> Message-ID: <30428@boulder.Colorado.EDU>
*> From: frechett@boulder.Colorado.EDU (-=Runaway Daemon=-)
*> Date: 30 Nov 90 00:12:01 GMT
*> Reply-To: frechett@snoopy.Colorado.EDU (-=Runaway Daemon=-)
*> Sender: news@boulder.Colorado.EDU
*> References: <LLs3s1w163w@ireta.wimsey.bc.ca>
*> Organization: University of Colorado, Boulder
*> Nntp-Posting-Host: snoopy.colorado.edu
*> Lines: 15
*> 

Ok here is an even better way to pause:

	in RK2 add the following lines

		<< 2 ->LIST 
			'lstk' STO 
			HALT 
			lstk LIST-> 
			DROP
			{ #0 #0 } PVIEW
		>>

	after:

	
		... DUP 
    			THEN { .....

Also add, at the beginning of the key list, add the key-code for the pause key.
	
This will halt the program and leave the stack as it was when you started.

Sorry about the non-downloadable code but it is short.

-Robert

P.S.  With the default settings, I got 16900. (not to gloat or 	       
    anything)