(71B) ROLLERS for HP-71B
12-24-2013, 05:16 PM (This post was last modified: 06-15-2017 01:30 PM by Gene.)
Post: #1
 Howard Owen Member Posts: 72 Joined: Dec 2013
(71B) ROLLERS for HP-71B
Here is ROLLERS for the HP-71B. The program relies on a separate file of subroutines called DICESUBS, which I also include here. This program is based on High Rollers for the HP-41C by Ross Cooling. PPC Journal Vol 14 No 2 Page 22 Feb, 1987, as implemented by Ángel Martin in the Sandbox ROM.

Code:
 0001 ! $Id: ROLLERS.txt,v 1.2 2011/04/12 21:32:58 hbo Exp$ 0010 ! ***************************************************** 0020 ! *   Rollers 0030 ! *   Loosely based on the Sandbox ROM implementation 0040 ! * 0050 ! *     0060 ! *   Copyright (C) Howard Owen 2005 0070 ! *   This program is free software; you can redistribute it and/or modify 0080 ! *   it under the terms of the GNU General Public License as published by 0090 ! *   the Free Software Foundation; either version 2 of the License, or 0100 ! *   (at your option) any later version. 0110 ! * 0120 RANDOMIZE  0130 DESTROY D,S,S3,C,D$,F,N 0140 N=2 ! # of Dice 0150 D1=6 ! Range(D)=1..D1 0160 DEF FNR(N)=INT(RND*D1+1) ! Roll 1 die 0170 OPTION BASE 1 0180 DIM D$[84] ! String with dice images 0190 DIM D1$[28] ! Display string (two dice) 0200 DIM V(N) ! dice "visibilities" for compat w/YATZ 0210 FOR I=1 TO N @ V(I)=1 @ NEXT I ! Dice always visible 0220 DIM D(N) ! Dice values 0230 DIM S(9) ! Numbers, 1 to 9 to start 0240 'RESET': FOR I=1 TO 9 @ S(I)=1 @ NEXT I 0250 Q=0 ! Quit flag 0260 CALL DICE(D$) IN DICESUBS ! Initialize dice images 0270 B2=FLAG(-2) ! Save initial state of the beeper flag 0280 !  0290 !                                                   Main loop 0300 !  0310 'NEWTURN': ! Start with fresh dice each turn 0320 FOR I=1 TO N @ D(I)=FNR(0) @ NEXT I ! roll 'em 0330 !                                                   Display dice and numbers 0340 WINDOW 1 0350 CALL DRAW(D$,D(),V(),N) IN DICESUBS ! Draw the dice 0360 CALL DRAWN(S(),T) ! And the numbers 0370 WINDOW 16 ! Input window starts here 0380 D2=D(1)+D(2) ! Total of dice 0390 ! Check for doubles. Encode F in flags 0-4 0400 IF D(1)=D(2) THEN BEEP 1760,.1 @ BEEP 1760,.1 @ F=F+1 @ CALL FLAGS(F) 0410 ! Check for won/lost 0420 CALL WIN(D2,S(),L,T) ! Check if this roll has any solution 0430 IF L=1 THEN 'CkWin' ! Yes it does, check if we won. 0440 CALL DOUBLES(L,F) ! We lost! But doubles maybe? 0450 IF L=0 THEN 'LOSE' ! Nope. Outta here. 0460 ! Saved by doubles 0470 DISP "use dbl" @ BEEP 440,.1 @ BEEP 220,.2 @ GOTO 'NEWTURN' ! Yes try again. 0480 ! Lose. Pfthptt! 0490 'LOSE': DISP "Lose!" @ CALL RASPB IN DICESUBS @ WAIT .5 @ GOTO 'MyExit' 0500 ! Check for win 0510 'CKWIN': ! If our dice match the number remaining, that's a win. 0520 IF T<>D2 THEN 'Play' 0530 ! Win! 0540 FOR I=9 TO 1 STEP -1 ! Remove each remaining number. 0550 IF S(I)=0 THEN 'Cont' 0560 CALL TRILL(1) IN DICESUBS ! Play a tune before each removal 0570 S(I)=0 @ CALL DRAWN(S(),T) ! Redraw the numbers 0580 'CONT': NEXT I 0590 CALL TRILL(2) IN DICESUBS 0600 WINDOW 16 0610 DISP "Win!!" 0620 CALL TRILL(1) IN DICESUBS 0630 WAIT .5 @ GOTO 'MyExit' 0640 'PLAY': D3=D2 ! Temporary dice counter. 0650 'PROMPT': ! Ask for input. 0660 DISP "Choose" 0670 K$=KEY$@ IF K$='' THEN 'PROMPT' ! Don't want to depend on a lex.. 0680 IF K$='Q' THEN GOSUB "Btoggle" @ GOTO 'PROMPT' 0690 IF K$="X" THEN DISP "Quit!" @ Q=1 @ GOTO 'MyExit' ! "eXit" 0700 P=NUM(K$)-48 ! Only other inputs allowed are digits 1 to 9 0710 IF P<0 OR P>9 THEN BEEP 440,.1 @ BEEP 220,.1 @ GOTO 'PROMPT' 0720 IF S(P)=0 THEN BEEP 440,.1 @ BEEP 220,.1 @ GOTO 'PROMPT' 0730 IF S(P)=-1 THEN BEEP 1760,.1 @ S(P)=1 @ D3=D3+P @ GOTO 'REDRAW' ! Toggle on 0740 S(P)=-1 ! Toggle off 0750 IF D3-P<>0 THEN 'NOTDONE' ! Not used all the dice? 0760 FOR I=1 TO 9 ! We have used them all. Convert "off" (-1) to "gone" (0) 0770 IF S(I)=-1 THEN S(I)=0 0780 NEXT I 0790 CALL DRAWN(S(),T) @ WINDOW 16 ! Redraw numbers 0800 IF T=1 THEN 'Lose' ! A remainder of 1 is not winnable 0810 DISP "Rolling" @ BEEP 440,.1 @ BEEP 880,.1 0820 WAIT .5 @ GOTO 'NewTurn' ! Roll again 0830 'NOTDONE': CALL WIN(D3-P,S(),L,T) ! Can we use this number? 0840 IF L=0 THEN BEEP 1160,.1 @ S(P)=1 @ GOTO 'redraw' ! No. Reject it. 0850 BEEP 1760,.1 @ D3=D3-P ! We can reach dice total this way. 0860 'REDRAW': CALL DRAWN(S(),T) @ WINDOW 16 @ GOTO 'PROMPT' ! redraw numbers 0870 ! **************************************** Exit Routine 0880 'MYEXIT': ! 0890 FOR I=0 TO 4 @ CFLAG I @ NEXT I ! Clear flags 0-4 0900 F=0 0910 WINDOW 1 0920 IF Q=1 THEN 'DONE' ! If we quit, don't prompt. 0930 BEEP 440,.2 @ BEEP 660,.2 0940 'EXPROMPT': DISP "Again? (Y/N)" 0950 'EXIN': K$=KEY$@ IF K$="" THEN 'EXIN' 0960 IF K$="Y" OR K$="y" THEN BEEP 880,.1 @ GOTO 'RESET' 0970 IF K$<>"N" AND K$<>"n" THEN BEEP 440,.1 @ GOTO 'EXPROMPT' 0980 BEEP 220,.2 0990 'DONE': DISP "Done" 1000 B2=FLAG(-2,B2) ! Restore original beeper state 1010 !  1020 ! ************************** End of main program 1030 !  1040 END  1050 !  1060 ! ************************** Subroutines 1070 !                            Toggle the beeper 1080 'BTOGGLE': 1090 Z=FLAG(-2,NOT FLAG(-2)) 1100 BEEP 1760,.2 1110 RETURN  1120 !  1130 ! **********************************    Subprograms 1140 !  1150 SUB DRAWN(S(),T) 1160 WINDOW 6 1170 S$="" 1180 T=0 1190 FOR I=1 TO 9 1200 IF S(I)=1 THEN S$=S$&STR$(I) @ T=T+I @ GOTO 'ContI' 1210 S$=S$&" " 1220 'CONTI': NEXT I 1230 DISP S$1240 END SUB 1250 ! 1260 ! Win - Check for possible plays 1270 ! 1280 ! Accept dice total (T1) and remaining numbers in S(), whose subscripts 1290 ! are the numbers, and whose values are 1 if the number is present,or 1300 ! not 1 if absent. Return whether a play is possible (W=1) or not (W=0) 1310 ! and the total of all numbers in S() in T2. 1320 ! 1330 ! Called to determine whether the game is lost, in which case T1 is the 1340 ! total of the dice. If we can't sum to that number with elements of (S), 1350 ! we have lost. Also called to determine whether a particular move will 1360 ! lead to a legal play. In that case T1 will only be a partial sum of the 1370 ! dice. For example, if the player has 12469 remaining, rolls a six and 1380 ! a seven, and selects '6', then this routine would be called with 1390 ! The six removed from S() and T1 being 7. The question being asked is 1400 ! "If the user chooses six, can the remaining dice sum to seven?" This 1410 ! way we can beep rudely if it isn't possible, and not accept illegal 1420 ! moves. 1430 ! 1440 SUB WIN(T1,S(),W,T2) 1450 W=0 ! Actually assuming a win. (1 gets added at the end.) 1460 IF T1=0 THEN 'WIN' ! We can always remove 0 from S(). 1470 IF T1<0 THEN 'LOSE' ! We can never add to S() 1480 DIM S2(9) ! We'll decode S() into this array 1490 T2=0 @ I2=1 ! Total of S2(), index into S2 (then highest index of S2()) 1500 ! 1510 ! Decode and sum S() 1520 ! 1530 FOR I=9 TO 1 STEP -1 ! Decode S() into S2(), in reverse numeric order. 1540 IF S(I)<>1 THEN 'CONT1' 1550 IF I>=T1 THEN 'CONT2' ! Don't consider dice that we can't use 1560 S2(I2)=I @ I2=I2+1 ! We could use this one 1570 'CONT2': T2=T2+I ! Sum all dice that are present (S(I)=1) 1580 'CONT1': NEXT I ! 1590 IF T1>9 THEN 'MORE' ! If so, then one number won't win 1600 IF S(T1)=1 THEN 'WIN' ! Is there one number that wins? 1610 'MORE': 1620 ! 1630 IF T1>T2 THEN 'LOSE' ! We can't reach T1, so we've lost 1640 IF T1=T2 THEN 'WIN' ! We win if we match T1 with all the numbers 1650 R=0 @ I2=I2-1 ! R is running total. 1660 ! 1670 ! Main evaluation loops. 1680 ! 1690 FOR I=1 TO I2 ! Arranged highest to lowest 1700 R=S2(I) ! Our trial sum starts with this 1710 FOR S3=I+1 TO I2 ! Starting with the next lowest number.. 1720 IF R+S2(S3)>T1 THEN 'S3Loop' ! If we went over, try the next lowest 1730 R=R+S2(S3) ! We may be able to use this one too. 1740 IF R=T1 THEN 'WIN' ! Bingo! 1750 'S3LOOP': NEXT S3 1760 NEXT I 1770 'LOSE': ! 1780 W=-1 1790 'WIN': ! 1800 W=W+1 1810 END SUB 1820 ! 1830 ! Check for doubles. L is return, F is muber of doubles pending. 1840 ! Call 'Flags()' to encode the number of pending doubles 1850 ! in flags 0-4. (For user's benefit, purely) 1860 ! 1870 SUB DOUBLES(L,F) 1880 IF F=0 THEN L=0 @ GOTO 'EXITW' ! No doubles left. 1890 F=F-1 ! Decrement the doubles count 1900 L=1 ! We did have a double left 1910 CALL FLAGS(F) ! Put remaining doubles in flags 1920 'EXITW': ! 1930 END SUB 1940 ! 1950 ! Encode the number of pending doubles in flags 0-4 1960 ! Used to display number of pending doubles in the flag annunciators. 1970 ! Treat the flags 0-4 as a quintic counting set, binary coded. 1980 ! Digits map 0->1, 1->2, 2->3, 3->4, 4->0. 1990 ! Numbers from 0 to 15 can be coded in this way. 2000 ! Reversing the direction of the flags, here is the coding table: 2010 ! 2020 ! Flags 4-0 Decimal 2030 ! 00001 1 2040 ! 00010 2 2050 ! 00100 3 2060 ! 01000 4 2070 ! 10000 5 2080 ! 10001 6 2090 ! 10010 7 2100 ! 10100 8 2110 ! 11000 9 2120 ! 11001 10 2130 ! 11010 11 2140 ! 11100 12 2150 ! 11101 13 2160 ! 11110 14 2170 ! 11111 15 2180 ! 2190 ! If you get over 15 doubles then run, don't walk, to the nearest casino! 2200 ! 2210 SUB FLAGS(F) 2220 T=F 2230 FOR I=4 TO 0 STEP -1 2240 IF T>=I+1 THEN T=T-(I+1) @ SFLAG I ELSE CFLAG I 2250 NEXT I 2260 END SUB DICESUBS: Code:  0001 !$Id: DICESUBS.txt,v 1.3 2011/04/13 01:21:34 hbo Exp $0010 ! ********************************** Subprograms 0020 ! 0030 ! Draw dice images in a GDISP ready string 0040 SUB DICE(D$) 0050 V$=CHR$(255) 0060 B$=CHR$(129) ! Dot at top and bottom 0070 T1$=CHR$(225) 0080 T2$=CHR$(135) 0090 T3$=CHR$(231) 0100 O$=CHR$(153) 0110 Z$=CHR$(0) 0120 D$='' 0130 GOSUB 'SPACE' 0140 GOSUB 'Ace' 0150 GOSUB 'SPACE' 0160 GOSUB 'Deuce' 0170 GOSUB 'SPACE' 0180 GOSUB 'Trey' 0190 GOSUB 'SPACE' 0200 GOSUB 'Four' 0210 GOSUB 'SPACE' 0220 GOSUB 'Five' 0230 GOSUB 'SPACE' 0240 GOSUB 'Six' 0250 GOTO 470 0260 'SPACE': 0270 D$=D$&Z$&Z$&Z$ 0280 RETURN  0290 'ACE': 0300 D$=D$&V$&B$&B$&B$&O$&O$&B$&B$&B$&V$ 0310 RETURN  0320 'DEUCE': 0330 D$=D$&V$&T1$&T1$&B$&B$&B$&B$&T2$&T2$&V$ 0340 RETURN  0350 'TREY': 0360 D$=D$&V$&T1$&T1$&B$&O$&O$&B$&T2$&T2$&V$ 0370 RETURN  0380 'FOUR': 0390 D$=D$&V$&T3$&T3$&B$&B$&B$&B$&T3$&T3$&V$ 0400 RETURN  0410 'FIVE': 0420 D$=D$&V$&T3$&T3$&B$&O$&O$&B$&T3$&T3$&V$ 0430 RETURN  0440 'SIX': 0450 D$=D$&V$&T3$&T3$&B$&T3$&T3$&B$&T3$&T3$&V$ 0460 RETURN  0470 END SUB  0480 !                                       Beep (sort of) like an HP-41 0490 SUB BEEP41 0500 BEEP 608,.25 0510 BEEP 440,.25 0520 BEEP 750,.25 0530 BEEP 608,.5 0540 END SUB  0550 !                                       Give 'em a raspberry 0560 SUB RASPB 0570 FOR I=1 TO 14 @ BEEP 110,.05 @ BEEP 70,.01 @ NEXT I 0580 END SUB  0590 !                                        0600 SUB DRAW(I$,D(),V(),N) ! Draw the current dice on the screen 0610 ! I$ is the dice images 1-6 in a string, 13 characters each 0620 ! D() is the array of dice values 0630 ! V() is the array of dice visibilities 0640 ! N is the number of dice to display 0650 DIM D$[13],O$[70] 0660 B$=CHR$(0) 0670 B1$=B$&B$&B$&B$&B$&B$&B$&B$&B$&B$&B$&B$&B$ 0680 FOR I=1 TO N 0690 B=13*(D(I)-1)+1 0700 IF V(I) THEN D$=I$[B,B+12] ELSE D$=B1$ 0710 O$=O$&D$0720 NEXT I 0730 GDISP O$ 0740 END SUB  0750 !  0760 DESTROY D 0770 SUB TRILL(C) 0780 D=.05 0790 DIM N(8) 0800 FOR I=1 TO 8 @ READ N(I) @ NEXT I 0810 FOR R=1 TO C 0820 FOR I=1 TO 8 @ BEEP N(I),D @ NEXT I 0830 NEXT R 0840 DATA 220,330,440,660,880,1320,1760,220 0850 END SUB

Documentation:

$Id$

HIGH ROLLERS

I The Game
II Mechanics of Play
III Miscellany
a Shutting up the Beeps
b Ending the Game Normally
c Ending the Game Abnormally
d Battery Hog

I The Game

High Rollers is a game played with two dice and a list of numbers 1
through 9. The goal is to eliminate all 9 of the numbers from the
list. This is done by rolling the dice, and removing numbers from the
list that add up to the total on the dice. If the total on the dice
can't be removed from the numbers remaining in the list, then you
lose. (But see the rule about doubles, below.)

Before giving an example of all that, let me define some notation.
Dice rolls will be shown as X:Y. So a roll of 4 and 2 would be shown
as 4:2. Removing numbers from the list will be shown as (X Y Z). So
one way of removing a total of 6 from the list would be (1 2 3).

If you rolled 5:1, that would total 6. You can remove six from the full
list of numbers in four different ways. Removing (6), (4 2), (5 1) or (1
2 3) will all work. On the other hand, if you roll 1:1, there is only
one way to remove a two, by playing (2). Speaking of snake-eyes, if
you roll doubles, like 1:1 or 2:2, that gives you a get out of jail
card. If a particular roll can't be removed from the current list, you
would ordinarily lose. But if you had previously rolled doubles, that
would give you another chance. If you rolled two doubles before getting
stuck, that would give you two extra chances and so forth.

Here's a sample game, using the notation defined above.

Code:
 List          Roll    Move   Doubles 123456789     4:2     (5 1) _234_6789     3:3     (6)    1 _234__789     6:6     (9 3)  2 _2_4__78_     2:1     ---    1 _2_4__78_     4:3     (7)    1 _2 4___8_     5:1     (2 4)  1 _______8_     5:2     ---    0 _______8_     4:3     LOSE!
II Mechanics of Play

To start the program, type "RUN ROLLERS". (I will assume you have
loaded the program, by hook or by crook, so that command will work.)
After a moment, you will see two dice and a list of numbers 1 through
9. Press the number keys corresponding to the numbers you want to
remove from the list. If your entry adds up to the total on the dice,
ROLLERS will roll the dice again. Otherwise, if the number you choose
could lead to a combination of numbers that would add up to the total
on the dice, ROLLERS will beep and wait for the next number. If the
number you chouse couldn't add up to the dice total, ROLLERS will beep
in a lower tone and reject the entry. Here's an example:

123456789 5:2
Enter (3) - high pitched beep. 3 disappears from the list.
Enter (5) - low pitched beep. 5 stays in the list
Enter (4) - high pitched beep, 4 disappears, ROLLERS rolls the dice again.

If you have entered the first number of a legal sequence, but then
decide you want to play something else, you can press the number

III Miscellany

III.a Shutting up the Beeps

This program beeps a lot. If this annoys you, you can execute BEEP OFF
before starting it up. Also, pressing "Q" when in the dice rolling
mode will toggle the beeper on and off. ROLLERS will remember whether the
beeper was on or off when it first started up, and will restore the
beeper to that state when the program exits normally.

III.b Ending the Game Normally

If a roll would result in all numbers being removed from the list,
ROLLERS has a little celebration, plays a tune and announces the
win. It will then ask you if you want to play again. If you answer "Y"
the game will restart, otherwise you will be returned to command mode
with the word "Done" in the display.

III.c Ending the Game Abnormally

If you get sick of the game while playing it, you may want to end it
early. You can do this by pressing the ATTN (ON) button. (Throwing the
machine against the wall is not recommended.) If you do this, the
display will not be restored to its normal mode. You will have to type
"WINDOW 1" yourself to get the display back to normal. Also, if you
changed the beeper setting in the program, and that setting was
different from your normal beeper setting, interrupting the program
will leave the beeper ON or OFF as the case may be. You will have to
manually set the beeper yourself to change this, by typing "BEEPER ON"
or "BEEPER OFF" as appropriate.

III.d Battery Hog

Besides beeping a lot, ROLLERS uses the system KEY\$ routine to poll for
input. That means that it won't go to sleep if you leave the machine
on like it normally would. (There are better keyboard entry routines
in various LEX files, but I wanted this program to run on a stock
HP-71B.) The moral is: don't do that. Turn off the calculator, or exit
ROLLERS by pressing the ON button before you go off and leave it alone.

This program is free software; you can redistribute it and/or modify
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

The author may be contacted by electronic mail at hbo@egbok.com.

Regards,
Howard
03-12-2017, 03:45 PM
Post: #2
 DoctorClu Junior Member Posts: 3 Joined: Mar 2017
RE: ROLLERS for HP-71B
Awesome!
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)