Magic Square v1.1 by Doug Cannon Sept 27, 1990
Posted to Usenet June 7, 1991
Errors corrected Nov 11, 1991
This is quite an interesting program. I think I got the
idea from an ancient electronic game called MERLIN. One of the
games you could play was Magic Square. I never owned Merlin, but
I think this is how it goes. Anyway, it's a cute game, with a little
animation added to make it more exciting.
The keys you may press are the number keys (0-9) and the letter
H. H is for help. It will tell you how many key presses left to win.
The number keys are oriented the same as the playing board.
If you press an edge key (2, 4, 6, 8) then it will inverse the
three dots along that edge. If you press it again, it just un-does
what it did. Pressing a corner key will inverse the four dots in that
corner. Of course, pressing it again will undo what it did.
Pressing the center key will inverse 5 dots in the shape of a plus.
(That is, the four edge dots, and the center dot.)
The object of the game is to have each dot "turned on" except the
center one. Then you win. Each time you press a key (including H)
It adds one to your score. The lower the score, the better.
I think I couldn't have made these instructions more unclear, but
just try it, and I think you'll get the hang of it.
Sorry that it is a lengthy program. It is fun, though.
One more thing. If you simply execute [MAGS] this is the starting
program. (I recommend you use a speed-up program first). Then you
will play 3 rounds of Magic Square. If you would like to play more
or less rounds, then enter a number onto the stack before pressing
[MAGS].
That's it! Enjoy!
----------------------------------------
'MAGS' [4299]
<< 64 STWS ;Set to 64 for bin operations
DEPTH 0 == 3 IFT ;Check if nothing on stack, put a 3
DUP TYPE 0 <> 3 IFT ;If level 1 not a number, put a 3
IP MPGM >> ;Execute MPGM.
Please note that I used a <> symbol to mean . The HP28s, of
course has the real symbol, but my editor does not. Please enter
the proper symbol on your hp.
--------------------------------
'INIT' [2076]
<< #0b -> DTA
<< CLLCD CLRH 1 137 SUB CLRH ;Set up CLRH to be
412 548 SUB SWAP OVER DUP + + + ;used with SCORE
362 Z ANIM + 141 Z + ;Set up ANIM
9 1 FOR Y ;9 total graphics to make
"PLEASE WAIT " Y ->STR + 1 DISP
ZERO PUSH Y GET 'DTA' STO
1 9 FOR X ;9 possible dots
DTA #1b AND
#1b IF == ;Check if this dot present
THEN X DOTT OR ;if yes, make it
END
DTA SR 'DTA' STO
NEXT
-1 STEP
>> >>
----------------------------------------
'DCAL' [6C38]
<< #111101111b 0 -> DTA KTP ;Set local vars
<< 1 9 FOR X ;Need 9 possibilities
RAND 2 * IP ;pick a 1 or 0
IF ;if it was a 1
THEN PUSH X GET DTA XOR ;Then it's a key
'DTA' STO 2 X 1 - ^ KTP + ;to be pushed in game.
'KTP' STO
ELSE X 1 + PICK XOR ;else do graphic
END
X 5 IF == ;#5 is a
THEN 6 PICK XOR ;special case.
END
NEXT
KTP R->B DTA ;pass results
>> >>
----------------------------------------
'HELP' [862]
<< 0 -> KTP N ;Init local vars
<< 1 9 FOR X ;Check 9 possibilities
#1b KTP AND
#1b if == ;If there's a 1 ...
THEN 1 N + 'N' STO ;Add 1 to N.
END
KTP SR 'KTP' STO ;Shift right one bit
NEXT ;Check the rest
120 Z SNUM N 6 * 1 + N 1 + ;Get the right
6 * SUB + 422 Z + OR DUP ;Number,
->LCD ;Display it.
>> >>
----------------------------------------
'SCORE' [1EE4]
<< ->STR -> SC ;Make # into string, STO in SC
<< 12 PICK AND 257 Z ;Erase old score, get some zeros
1 SC SIZE FOR X ;for X = 1 to SIZE(SC)
BNUM SC X X SUB STR-> ;get a digit
6 * 1 + DUP 5 + SUB + ;get digit graphics
NEXT ;do the rest
548 OVER SIZE - Z ;get remaining blanks
+ OR ;merge it on
>> >>
----------------------------------------
'FANF' [8804]
<< BD 1 10 FOR F ;10 times
DUP -> LCD 2000 1000 ;display alternating pics.
'SIGN(FP(F/2))' EVAL * + ;play alternating
.05 BEEP SWAP ;tones
NEXT
SWAP DROP
>>
----------------------------------------
'DOTT' [EC32]
<< DUP 1 - 3 / IP 1 + SWAP ;converts a num (1-9)
1 - 3 MOD 1 + -> S T ;into coords (S,T)
<< DDATA S GET LIST-> DROP 466 ;Crazy calculations
S 137 * - Z + 129 Z SWAP + + ;that
S 137 * 193 - Z SWAP + T 10 * ;actually
Z SWAP + 3 T - 10 * Z + ;work!!
>> >>
----------------------------------------
'Z' [2F40]
<< ZERO 1 ROT SUB >>
----------------------------------------
'MGPM' [D118]
<< {"1" "2" "3" "4" "5" "6" "7" "8" "9" "H"} ;all keypresses
0 0 0 #0b #0b 0 0 0 CHR
-> N KEYS SC LSC STOT KTP DTA ;init local vars
CNT DIR BL ;same
<< INIT
1 N FOR G ;do 1 to N rounds
BD DCAL 'DTA' STO 'KTP' STO ;get BD, pick random dots
DUP ->LCD ;show it
DO
KEYS 0 'CNT' STO
DO ;Check for key,
CNT 1 + 'CNT' STO ;fall out of loop
UNTIL KEY 5 CNT == OR END ;if key or if take too long
DUP TYPE ;Check to make sure
IF 2 == 5 CNT <> OR ;key was pressed.
THEN CLRH 4 ROLL AND ;if yes, then erase
3 ROLLD POS DUP ;help, find which key.
0 IF <> ;if a good key
THEN SC 1 + 'SC' STO DUP ;add 1 to score
10 IF <> ;if not "H"
THEN 2 OVER 1 - ^ R->B ;Then get a dot pattern,
KTP XOR 'KTP' STO SWAP ;let KTP know
OVER 2 + PICK XOR PUSH ;prepare picture
ROT GET DTA XOR 'DTA' ;Let DTA know
STO DUP ->LCD ;Display picture
6000 .04 BEEP ;BEEP
ELSE DROP KTP HELP ;if "H" pressed, run HELP
END
ELSE DROP 1000 .05 BEEP ;if a bad key, BEEP
END
ELSE DROP 11 PICK ;if too much time, then
IF DIR ;if DIR = 1 (direction)
THEN 0 'DIR' STO ;then set to 0
ELSE 1 'DIR' STO BL SWAP ;if dir=0, set to 1
+ 1 548 SUB ;go other way
END
XOR SC LSC ;check if score should
IF <> THEN SC SCORE SC ;be updated
'LSC' STO END
DUP ->LCD ;show update
END
UNTIL KTP #0b == END ;keep playing until done (KTP=0)
FANF DROP STOT SC + 'STOT' ;play fanfare, add score
STO 0 'SC' STO ;to tot, score = 0
NEXT ;do the other rounds.
11 DROPN ;drop stack data
"OUT OF " N ->STR + ;show # of rounds
" GAMES" +
"YOUR SCORE= " STOT ->STR + ;show score
STOT N / 10 * IP 10 / ->STR ;find ave per game
" PER GAME" + CLMF ;show it
>> >>
----------------------------------------
Local KEYS (LIST) of all possible keypresses
Variables: N (REAL) Number of rounds
SC (REAL) Score of round being played
LSC (REAL) Last updated score
STOT (REAL) Total score for all rounds
KTP (BIN) Keys to be pressed to win
DTA (BIN) Data showing where dots are
CNT (REAL) Counter variable
DIR (REAL) Direction of animation
BL (STR) One single blank (CHR(0))
----------------------------------------
Now we need to create the various graphics used.
Most of them are quite simple.
There are two small utility programs we will need to aid us in
creating these graphics.
The following program converts a stack of numbers into a string.
'MAKE' [1C7]
<< "" DEPTH 1 - 1 SWAP START SWAP
CHR SWAP + NEXT >>
The next program duplicates an object a specified number of times.
'DUPX' [7E46]
<< 1 - 1 SWAP START DUP NEXT >>
----------------------------------------
'ZERO' [0]
0 548 [DUPX] [MAKE] 'ZERO' [STO]
----------------------------------------
'CLRH' [DA25]
255 118 [DUPX] 0 19 [DUPX]
255 411 [DUPX] [MAKE]
'CLRH' [STO]
Of course you know that if I say [DUPX] it means you should push
the softkey to run the program [DUPX]. (Or [MAKE] or whatever.)
----------------------------------------
'ANIM' [8880]
This graphic requires that we enter a small program to be
executed only once.
<< 40 84 MAKE 1 5 START DUP + NEXT 1 39 SUB
'ANIM' STO 64 32 80 MAKE ANIM + 'ANIM' STO
20 8 4 MAKE ANIM SWAP + 'ANIM' STO >>
Now just press [EVAL] and the work is done.
----------------------------------------
'SNUM' [16E9]
Once again we will execute a small program.
<< "0123456789" 1 DISP LCD-> 1 60 SUB
'SNUM' STO CLMF >>
As before, press [EVAL] and HP does the hard stuff.
----------------------------------------
'BNUM' [E9A7]
This is a little bit harder than 'SNUM' but not too bad.
We need to enter the following numbers onto the stack,
then execute [MAKE].
126 255 195 255 126 0 0 196 254 255 192 0 230 247 211 223
206 0 66 195 219 255 102 0 31 31 24 255 255 0 95 223 219
251 115 0 126 255 219 251 114 0 3 227 251 31 7 0 126 255
219 255 126 0 78 223 219 255 126 0
[MAKE] 'BNUM' [STO]
----------------------------------------
Well, that's it for the easy graphics, now we need to create
the board. This is not so easy. So, I will give three options:
If you don't care much for graphics, then do this:
548 [Z] 'BD' [STO] and skip the rest. But this will not be as
pretty.
If you want only the bare essentials, then type in the first part.
The second part is a neat graphic that is just for show.
First part only: CHK [8087]
First and Second parts: CHK [CFD4]
First part: ( Please pay attention to [DUPX] and [DUPN] )
Fourth row:
0 52 [DUPX] 255 255 192 8 [DUPX] 10 [DUPN] 10 [DUPN]
255 255 0 248 136 136 112 0 112 136 136 112 0 120 128 128
120 0 112 136 168 232 0 0 0 112 136 136 136 0 240 72
72 240 0 248 32 64 248 0 248 32 64 248 0 112 136 136
112 0 248 32 64 248 0
[MAKE] 'BD' [STO]
---------------
Third row:
0 52 [DUPX] 255 255 48 8 [DUPX] 10 [DUPN] 10 [DUPN]
255 255 0 128 192 224 176 152 204 230 178 154 206
4 [DUPN] 8 [DUPN] 16 [DUPN] 8 [DUPN] 102 50 26 14 6 2
[MAKE] [BD] + 'BD' [STO]
---------------
Second row:
0 52 [DUPX] 255 255 12 8 [DUPX] 10 [DUPN] 10 [DUPN]
255 255 0 102 239 219 247 102 0 126 255 195 231 102 0 126
255 195 255 126 0 255 255 27 255 238 0 255 255 219 219 195
0 0 108 108 0 0 126 255 195 255 126 0 12 [DUPX]
[MAKE] [BD] + 'BD' [STO]
---------------
First row:
0 52 [DUPX] 255 255 3 8 [DUPX] 10 [DUPN] 10 [DUPN]
255 255 0 127 65 119 20 119 65 127 0 127 127 107 107 99
0 127 127 96 96 96 0 127 127 27 31 14 0 0 54 54
0 23 [DUPX] [MAKE] [BD] + 'BD' [STO]
----------------------------------------
Now lets enter in the pretty graphic. (It really is worth it!)
Fourth row:
0 0 0 3 14 24 120 112 240 240 249 127 63 30 97 255
240 224 144 119 239 159 64 255 224 224 255 127 31 224 107 28
28 107 247 127 128 127 15 6 31 127 251 97 0 255 243 227
243 248 112 0 86 [DUPX] [MAKE] 'TEMP' [STO]
---------------
Third row:
0 15 127 128 0 0 60 126 127 239 199 199 142 92 225 252
60 28 60 252 248 224 28 248 0 0 248 252 248 0 252 28
28 252 248 224 24 252 60 28 60 252 248 224 24 252 60 28
60 124 56 0 86 [DUPX] [MAKE] [TEMP] + 'TEMP' [STO]
---------------
Second row:
63 255 255 63 3 1 1 3 7 15 3 0 0 0 224 127
63 15 0 31 61 26 7 7 7 26 61 31 0 7 31 62
57 59 59 59 29 6 0 31 63 31 0 7 31 63 60 56
60 62 28 0 86 [DUPX] [MAKE] [TEMP] + 'TEMP' [STO]
---------------
First row:
0 240 254 255 255 254 248 224 254 255 255 254 126 124 248 240
192 0 0 248 254 255 15 7 15 255 254 248 0 248 254 255
15 135 135 143 30 56 0 254 255 254 0 248 254 255 15 7
15 31 14 0 86 [DUPX] [MAKE] [TEMP] + 'TEMP' [STO]
---------------
There, now that wasn't so bad! I suggest that we check to see
if we have entered this graphic correctly.
'TEMP' CHK [4F53]
Now just do this: [BD] [TEMP] OR 'BD' [STO]
Do the check: 'BD' CHK [CFD4] ( As stated above )
And if it's OK, then do this: 'TEMP' [PURGE]
---------------------------------------
The last thing to enter are the two data files.
The first is easy.
'PUSH' [C503]
{ #D8h #1C0h #1B0h
#49h #BAh #124h
#1Bh #7h #36h }
The next one you will need to use [MAKE] again.
15 31 63 63 63 63 31 15 [MAKE] 'TEMP' [STO]
0 128 192 192 192 192 128 0 [MAKE]
[TEMP] 2 ->LIST 'DDATA' [STO]
3 7 15 15 15 15 7 3 [MAKE] 'TEMP' [STO]
192 224 240 240 240 240 224 192 [MAKE]
[TEMP] 2 ->LIST [DDATA] 2 ->LIST 'DDATA' [STO]
0 1 3 3 3 3 1 0 [MAKE] 'TEMP' [STO]
240 248 252 252 252 252 248 240 [MAKE]
[TEMP] 2 ->LIST [DDATA] LIST-> [DROP] 3 ->LIST
'DDATA' [STO]
'DDATA' CHK [F995]
----------------------------------------
Please, Let me know if you've enjoyed this program.
Also, if you encounter any problems, let me know.
Drop me a line: dougc@bert.cs.byu.edu
I have many more of similar interest.
I even have a humdinger of an animation program that you
have to see to believe. The problem is that it requires 8
pictures of 548 numbers each, meaning you enter 4,384 numbers
onto the stack (in pieces of course!) and then the program
is quite simple. But very fascinating!