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!