Challenge: Open-ended Dice on the HP-41



#4

This challenge is derived from creating applications for the Amar role-playing game. It is a challenge involving the extension of the normal dice with 6 sides - a so called open-ended dice throw.

Definition: Take a dice with 6 sides. Now we would like to extend the range of the numbers beyond the intrinsic 1 to 6. A way to accomplish that is to make the 1 and the 6 special cases. Whenever you throw a 6, you can extend the range by making another throw. A throw of 4 to 6 (50%) will add 1 to the original 6. Throw again and a result of 4 to 6 will again add 1 to the number (making it 8) etc. Every throw of 4 to 6 will add one until you get a 1, 2 or 3, then it stops. Conversely, throwing a 1 on the first throw is a special case. Throw again, and a result of 1 to 3 will subtract 1 from the original number. Keep throwing 1, 2 or 3 to subtract one... until you throw a 4, 5 or 6 - then it stops. Now we add a dimension; Whenever you throw two 6's consecutively it is marked as a "critical". A throw of two consecutive 1's is a "fumble". All this is called an "open-ended" dice throw. A normal dice roll is termed a D6, an open-ended roll is O6.

Challenge: Create a program for the HP-41 that does open-ended dice rolls. It should show whether the roll also includes a "critical"/"fumble". Do this without using any storage registers - i.e. only using the stack (and the Alpha register if you wish).

I will publish my solution for dissection in a few days :-)


#5


i was interested in how far out from [1,6] the "openness" might get. So i hacked up a quick program in Lua to print out a histogram.
here's what i get after a million goes:

the first column is the value and the second the percentage of trials hitting that value.

1       8.2905
2 16.6888
3 16.6197
4 16.6964
5 16.7057
6 8.3628
7 4.1587
8 2.0964
9 1.0276
10 0.5105
11 0.264
12 0.1336
13 0.0652
14 0.0334
15 0.0141
16 0.0092
17 0.0041
18 0.0024
19 0.0011
20 0.0003
21 0.0002
22 0.0001
23 0.0002
-1 2.0857
0 4.1388
-2 1.0439
-3 0.5196
-4 0.2631
-5 0.1331
-6 0.0665
-7 0.0324
-8 0.0163
-9 0.0072
-10 0.0041
-11 0.0015
-12 0.0013
-13 0.0008
-14 0.0005
-15 0.0001
-16 0.0001
total 100
critical = 2.7771
fumble = 2.7606

So we have a [2,4] plateau (1/6 as expected), then 50% falloff each side. However, it's interesting to note that the "critical" and "fumble" percentages are almost 1 in 36.

This indicates that you don't really get much difference tracking consecutive 1's and 6's after the first go. Consequently, i modified my simulator to count a "critical" as 2 6's at the start and a "fumble" as 2 1's. here's what i get:

1       8.2841
2 16.659
3 16.6423
4 16.7312
5 16.7244
6 8.2914
7 4.2017
8 2.0684
9 1.0386
10 0.5212
11 0.2641
12 0.1315
13 0.0618
14 0.0322
15 0.0185
16 0.0073
17 0.0041
18 0.002
19 0.0012
20 0.0006
22 0.0001
23 0.0001
24 0.0001
-7 0.0298
-8 0.0176
-9 0.0072
-10 0.0033
-11 0.0024
-12 0.0006
-13 0.0006
-14 0.0003
-1 2.0799
0 4.1518
-2 1.0266
-3 0.5313
-4 0.2638
-5 0.1286
-6 0.0701
-15 0.0002
total 100
critical = 2.7716
fumble = 2.7501

Similar story. So i would say, for the purposes of generating values for Amar, you could simplify your algorithm on the 41c and not track consecutive values. which should shorten the program.

here are my two versions. o6() is the "real" algorithm and "os6plain" is my hacked one.

function d6()
return math.floor(math.random()*6+1)
end

function o6()
local v = d6()
local d
local crit = false
local fumb = false
local c = true
if v == 6 then
while true do
d = d6()
if d >= 4 then
v = v + 1
if d == 6 then
crit = c
c = true
else
c = false
end
else break
end
end
elseif v == 1 then
while true do
d = d6()
if d < 4 then
v = v - 1
if d == 1 then
fumb = c
c = true
else
c = false
end
else break
end
end
end
return v,crit,fumb
end

function o6plain()
local v = d6()
local crit = false
local fumb = false
if v == 6 then
crit = d6() == 6
while d6() >= 4 do v = v + 1 end
elseif v == 1 then
fumb = d6() == 1
while d6() < 4 do v = v - 1 end
end
return v,crit,fumb
end


#6

Uh-oh! i made a mistake tracking the consecutive values. The difference is actually more - about 3% instead of 2.7

should be,

function o6()
local v = d6()
local d
local crit = false
local fumb = false
local c = true
if v == 6 then
while true do
d = d6()
if d >= 4 then
v = v + 1
if d == 6 then
if c then crit = true end
c = true
else
c = false
end
else break
end
end
elseif v == 1 then
while true do
d = d6()
if d < 4 then
v = v - 1
if d == 1 then
if c then fumb = true end
c = true
else
c = false
end
else break
end
end
end
return v,crit,fumb
end

so, it depends on whether you really want to track consecutive values or not.


Possibly Related Threads...
Thread Author Replies Views Last Post
  HP-41(CL): The easiest way to transfer FOCAL programs from a Linux PC to the HP-41 Geir Isene 13 2,140 12-05-2013, 02:40 AM
Last Post: Hans Brueggemann
  How to open 82162A Thermal Printer Chassis? Ron Fredericks 1 519 07-17-2013, 03:58 AM
Last Post: Tony Duell
  any open source HP 10BII emulators? John 15 1,786 06-12-2013, 09:58 AM
Last Post: Kimberly Thompson
  Programming cable for hp-30b -> wp-34s Open letter to Gene Nigel Rowe 37 3,472 08-02-2012, 12:30 AM
Last Post: Guy Dufour
  41-MCODE: a weekend challenge Ángel Martin 3 557 03-19-2012, 06:49 AM
Last Post: Mike (Stgt)
  HP48 open/repair guides back online Han 2 512 11-04-2011, 11:15 PM
Last Post: hpnut
  An "Open" letter to "DIY" and "Repurposed" calculator projects Ethan Conner 40 3,291 10-21-2011, 04:41 PM
Last Post: Ethan Conner
  HP48 - WHY where were they made so difficult to open up? mr-scorpio 12 1,276 10-01-2011, 02:23 PM
Last Post: Frido Bohn
  Can we make'em like Bill and David? An open RPN? snaggs 23 1,955 09-18-2011, 04:15 PM
Last Post: Hugh Evans
  Sort of OT: Dice odds Dave Britten 9 1,175 09-13-2011, 01:29 PM
Last Post: Kiyoshi Akima

Forum Jump: