Roll an ASCII die

16

1

In this challenge, you must output an ascii-art of a random die roll.

like this:

   ________
  /\       \
 /  \   6   \
{ 4  }-------}
 \  /   5   /
  \/_______/

Please note that:

   ________
  /\       \
 /  \   3   \
{ 4  }-------}
 \  /   5   /
  \/_______/

is invalid output, because that is not a possible result on a die

There are 6(faces that could be up)*4(faces that could be the left face after the top is determined)*1(faces that could be the right face after the other two are determined)=24 possibilities of die rolls.

Your program must output one of these die rolls in the form of an ascii art (modeled like the one below, with the x y and zs replaced with numbers) like above, with each output having >0 probability of occurring, but the probabilities do not have to be even (they are allowed to be trick dice, unlike in real life). Your program cannot output an invalid die roll, or a non die roll. Your program must have a probability of 1 of outputting a valid roll

Please note that your die does not necessarily have to be a right handed die like shown in the first image. (right- and left-handed describe the die's net)

right-handed die
   ________
  /\       \    net
 /  \   z   \     _|4|_ _
{ x  }-------}   |6|2|1|5|
 \  /   y   /      |3|
  \/_______/


left handed die
   ________
  /\       \    net
 /  \   y   \     _|3|_ _
{ x  }-------}   |6|2|1|5|
 \  /   z   /      |4|
  \/_______/

If your die is left handed, the following is valid output, but not if your die is right handed:

   ________
  /\       \
 /  \   2   \
{ 1  }-------}
 \  /   3   /
  \/_______/

While you can choose left handed or right handed, your die has to be consistent: it cannot change from left to right or vice versa

the following is a list of valid outputs for the die. Refer to the pictures above for positions of X-Y-Z:

X-Y-Z
-----
5-4-1
1-5-4
4-1-5

5-6-4
4-5-6
6-4-5

5-3-6
6-5-3
3-6-5

5-1-3
3-5-1
1-3-5

2-6-3
3-2-6
6-3-2

2-4-6
6-2-4
4-6-2

2-1-4
4-2-1
1-4-2

2-3-1
1-2-3
3-1-2

again this is , so fewer bytes is better

Destructible Lemon

Posted 2016-08-07T04:10:15.093

Reputation: 5 908

4

Solvers might be interested in a formula for the third die face given the other two.

– xnor – 2016-08-07T04:15:36.750

@xnor and as such I think that's a strong argument that this question is a duplicate – Digital Trauma – 2016-08-07T04:20:36.527

1I don't know though of any ASCII art to draw a cube in this projection. With the small size though, I don't know if one can do better than hardcoding in languages like Python. – xnor – 2016-08-07T04:25:43.020

Related: http://meta.codegolf.stackexchange.com/a/8197/17602

– Neil – 2016-08-07T09:17:39.400

@xnor indeed, even with some 7 and 8 char sequences in there. – Jonathan Allan – 2016-08-07T17:41:37.987

Answers

8

Python 3, 197 196192 bytes

from random import*;c=choice;r=range(1,7);u=c(r);l=c(list(set(r)-{u,u^7}));print(r'''   ________
  /\       \
 /  \%4d   \
{ %d  }-------}
 \  /%4d   /
  \/_______/'''%(u,l,3*u*l*(u*u-l*l)%7))

Test it on ideone

Right-handed (switch to a lefty by swapping u*u with l*l on the last line)

Bound to be beat - but let's get the dice rolling sigh - especially since all my attempts to golf the ASCII except going raw and using old-school formatting all failed to save bytes;
- any further golfing tips for a n00b gladly appreciated.

Jonathan Allan

Posted 2016-08-07T04:10:15.093

Reputation: 67 804

1You can save 1 byte by using from random import* and c=choice. – acrolith – 2016-08-07T17:50:49.467

@daHugLenny - didn't now I could miss that white space before the *; ta! – Jonathan Allan – 2016-08-07T18:20:10.790

1Welcome to PPCG! Nice first post! – GamrCorps – 2016-08-07T19:24:11.833

Thanks @GamrCorps - I have been meaning to do some for a while... now I have rep I can post a meaningful solution on a protected question... :D – Jonathan Allan – 2016-08-07T19:37:58.050

2Instead of having 3 spaces and then %d, use %4d instead and it'll pad it properly for you. You might be able to leverage it for other parts of the die as well. – Value Ink – 2016-08-08T11:32:57.953

5

Javascript 238 232 207 201 bytes

var r=24*Math.random()|0,o=r%3,b=r-o,v="123513653263154214624564";console.log(`   ________
  /\\       \\
 /  \\   %s   \\
{ %s  }-------}
 \\  /   %s   /
  \\/_______/`,v[r],v[b+(o+1)%3],v[b+(o+2)%3])

which when ungolfed is:

var r = 24 * Math.random() | 0,
    o = r % 3,
    b = r - o,
    v = "123513653263154214624564";
console.log(
`   ________
  /\\       \\
 /  \\   %s   \\
{ %s  }-------}
 \\  /   %s   /
  \\/_______/`,

    v[r],
    v[b+(o+1)%3]
    ,v[b+(o+2)%3]
)

Algorithm

Consider that at each of the 8 corner intersections of a die, the intersecting die face values are fixed but can appear in any of 3 rotations. For example while looking down at the "1","2","3" corner, the die can be rotated about an axis through the corner and out the opposite corner, to show "1", "2" or "3" on top of the ASCII art.

v hard codes the die faces which intersect at each corner, b is an offset to the start of a random corner, and o is start of the rotation within corner data. The ASCII art is written to the console using a console.log format string.

traktor53

Posted 2016-08-07T04:10:15.093

Reputation: 299

You can probably shave a few bytes by using \`` quotes which permit the use of literal newline characters instead of having to write\n` all the time. – Neil – 2016-08-09T14:33:01.630

@Neil most appreciated, it worked well. Also removed the trailing ';' – traktor53 – 2016-08-09T23:44:47.473

5

C,177

f(r){r=rand()%24;r=(5545>>r%4*3&63^256-(r*2&8))*513>>r/8*3;printf("   ________\n  /\\%9s /  \\%4d   \\\n{ %d  }-------}\n \\  /%4d   /\n  \\/_______/","\\\n",7&r,7&r/8,7&r/64);}

In test program

f(r){r=rand()%24;
r=(5545>>r%4*3&63^256-(r*2&8))*513>>r/8*3;
printf("   ________\n  /\\%9s /  \\%4d   \\\n{ %d  }-------}\n \\  /%4d   /\n  \\/_______/","\\\n",7&r,7&r/8,7&r/64);}

j;
main(){
    for(j=99;j--;puts(""))f();
}

Explanation

r=                    \\after calculation, assign to r (in order to use only one variable.)
(5545>>r%4*3&63       \\5545 is 12651 in octal. Select 2 digts for the equator
^256-(r*2&8))         \\if 4's bit of r is 0, prepend 4=256/64. Else prepend 3 and reverse one of the faces by xoring with 7. 256-8 = 248 = 3*64+7*8.
*513                  \\now we have a 3 digit octal number. duplicate all digits by multiplying by 1001 octal.
>>r/8*3               \\rightshift 0,1 or 2 digits to rotate. 

Level River St

Posted 2016-08-07T04:10:15.093

Reputation: 22 049

4

Javascript, 251 bytes

r="replace";a=()=>(0|Math.random()*6)+1;b=(x,y)=>3*x*y*(x*x+6*y*y)%7;u=()=>{x=a(),y=a();z=b(x,y);if(z==0)u();return"   ________\r\n  \/\\       \\\r\n \/  \\   1   \\\r\n{ 2  }-------}\r\n \\  \/   3   \/\r\n  \\\/_______\/"[r](1,x)[r](2,y)[r](3,z);}

Call using u();
It's long but it's an answer, and I haven't answered in a long time.

Bald Bantha

Posted 2016-08-07T04:10:15.093

Reputation: 463

Missing a space at the top-left of the output test on ideone.

– Jonathan Allan – 2016-08-07T20:09:03.243

a=()=>(0|Math.random()*6)+1; should save 8 – traktor53 – 2016-08-08T04:06:56.180

4

TSQL 308 bytes

DECLARE @ char(87)=(SELECT
REPLACE(REPLACE(REPLACE('   ________
  /\       \ 
 /  \   7   \ 
{ 8  }-------}
 \  /   9   /
  \/_______/',7,a),8,b),9,3*ABS(a*a*a*b-a*b*b*b)%7)
FROM(SELECT*,SUBSTRING(REPLACE(STUFF(123456,a,1,''),7-a,''),CAST(RAND()*4as int)+1,1)b
FROM(SELECT CAST(RAND()*6as int)+1a)x)x)PRINT @

280 bytes(in Server Management Studio: Query - result to text)

SELECT
REPLACE(REPLACE(REPLACE('   ________
  /\       \ 
 /  \   7   \ 
{ 8  }-------}
 \  /   9   /
  \/_______/',7,a),8,b),9,3*ABS(a*a*a*b-a*b*b*b)%7)
FROM(SELECT*,SUBSTRING(REPLACE(STUFF(123456,a,1,''),7-a,''),CAST(RAND()*4as int)+1,1)b
FROM(SELECT CAST(RAND()*6as int)+1a)x)x

Note: by removing the print and the declare part - and output the result directly from the SELECT. However that would not work in the fiddle

Fiddle

t-clausen.dk

Posted 2016-08-07T04:10:15.093

Reputation: 2 874

Maybe you can change to ABS(a^3*b-a*b^3) to save 4 bytes? (I'm not sure - seems to work in the fiddle, but it is only ever giving me a single roll of a,b,c=5,1,3 so I may be mistaken) – Jonathan Allan – 2016-08-09T00:16:03.733

@JonathanAllan thank you for your comment. Exponential is written POWER(a,3) in TSQL. ^ has a different meaning – t-clausen.dk – 2016-08-09T08:20:00.293

3

Ruby, 150 bytes

All the string formatting abuse!!!

Credit for formula obtaining the last number goes to @xnor here.

u=1+rand(6)
l=([*1..6]-[u,u^7]).sample
$><<'%11s
  /\%8s
 /  \%4d%4s
{ %d  }%s}
 \  /%4d%4s
  \/%s/'%[?_*8,?\\,u,?\\,l,?-*7,3*u*l*(u*u-l*l)%7,?/,?_*7]

Value Ink

Posted 2016-08-07T04:10:15.093

Reputation: 10 608

No - credit for formula goes to xnor

– Jonathan Allan – 2016-08-08T23:28:03.770

@JonathanAllan thanks for pointing me towards the proper credit. At any rate, how I formatted this answer was more what I had in mind when I said you could probably leverage string formatting more to your advantage to save bytes. – Value Ink – 2016-08-08T23:36:37.707