Double dice graphics python

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite












I'm new to programming and in my project, I'm trying to print basic dice graphics. I'm trying to make a function that accepts two numbers from 1 to 6, and prints corresponding two dice faces next to each other. I've tried several approaches, but this is the only one that worked, and it's quite chunky:



s="+ - - - - + + - - - - +"
m1="| o o |"
m2="| o |"
m3="| o |"
m4="| o |"
m5="| |"

def dice(a,b):
if a == 1:
str1=m5
str2=m3
str3=m5
elif a == 2:
str1=m2
str2=m5
str3=m4
elif a == 3:
str1=m2
str2=m3
str3=m4
elif a == 4:
str1=m1
str2=m5
str3=m1
elif a == 5:
str1=m1
str2=m3
str3=m1
elif a == 6:
str1=m1
str2=m1
str3=m1
if b == 1:
str1=str1+" "+m5
str2=str2+" "+m3
str3=str3+" "+m5
elif b == 2:
str1=str1+" "+m2
str2=str2+" "+m5
str3=str3+" "+m4
elif b == 3:
str1=str1+" "+m2
str2=str2+" "+m3
str3=str3+" "+m4
elif b == 4:
str1=str1+" "+m1
str2=str2+" "+m5
str3=str3+" "+m1
elif b == 5:
str1=str1+" "+m1
str2=str2+" "+m3
str3=str3+" "+m1
elif b == 6:
str1=str1+" "+m1
str2=str2+" "+m1
str3=str3+" "+m1
print(s)
print(str1)
print(str2)
print(str3)
print(s)


Is there a more compact and elegant way to do this?
Thanks in advance!










share|improve this question









New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • Can you please first explain what you aim to do?
    – Willem Van Onsem
    1 hour ago






  • 2




    @WillemVanOnsem You can run the code to see what it does. It prints a pair of dice to the screen. OP is asking if there's a more compact and elegant way to do it.
    – Matt Messersmith
    1 hour ago










  • Select best matching anser when you are ready to play craps.. ;)
    – TadejP
    36 mins ago














up vote
6
down vote

favorite












I'm new to programming and in my project, I'm trying to print basic dice graphics. I'm trying to make a function that accepts two numbers from 1 to 6, and prints corresponding two dice faces next to each other. I've tried several approaches, but this is the only one that worked, and it's quite chunky:



s="+ - - - - + + - - - - +"
m1="| o o |"
m2="| o |"
m3="| o |"
m4="| o |"
m5="| |"

def dice(a,b):
if a == 1:
str1=m5
str2=m3
str3=m5
elif a == 2:
str1=m2
str2=m5
str3=m4
elif a == 3:
str1=m2
str2=m3
str3=m4
elif a == 4:
str1=m1
str2=m5
str3=m1
elif a == 5:
str1=m1
str2=m3
str3=m1
elif a == 6:
str1=m1
str2=m1
str3=m1
if b == 1:
str1=str1+" "+m5
str2=str2+" "+m3
str3=str3+" "+m5
elif b == 2:
str1=str1+" "+m2
str2=str2+" "+m5
str3=str3+" "+m4
elif b == 3:
str1=str1+" "+m2
str2=str2+" "+m3
str3=str3+" "+m4
elif b == 4:
str1=str1+" "+m1
str2=str2+" "+m5
str3=str3+" "+m1
elif b == 5:
str1=str1+" "+m1
str2=str2+" "+m3
str3=str3+" "+m1
elif b == 6:
str1=str1+" "+m1
str2=str2+" "+m1
str3=str3+" "+m1
print(s)
print(str1)
print(str2)
print(str3)
print(s)


Is there a more compact and elegant way to do this?
Thanks in advance!










share|improve this question









New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • Can you please first explain what you aim to do?
    – Willem Van Onsem
    1 hour ago






  • 2




    @WillemVanOnsem You can run the code to see what it does. It prints a pair of dice to the screen. OP is asking if there's a more compact and elegant way to do it.
    – Matt Messersmith
    1 hour ago










  • Select best matching anser when you are ready to play craps.. ;)
    – TadejP
    36 mins ago












up vote
6
down vote

favorite









up vote
6
down vote

favorite











I'm new to programming and in my project, I'm trying to print basic dice graphics. I'm trying to make a function that accepts two numbers from 1 to 6, and prints corresponding two dice faces next to each other. I've tried several approaches, but this is the only one that worked, and it's quite chunky:



s="+ - - - - + + - - - - +"
m1="| o o |"
m2="| o |"
m3="| o |"
m4="| o |"
m5="| |"

def dice(a,b):
if a == 1:
str1=m5
str2=m3
str3=m5
elif a == 2:
str1=m2
str2=m5
str3=m4
elif a == 3:
str1=m2
str2=m3
str3=m4
elif a == 4:
str1=m1
str2=m5
str3=m1
elif a == 5:
str1=m1
str2=m3
str3=m1
elif a == 6:
str1=m1
str2=m1
str3=m1
if b == 1:
str1=str1+" "+m5
str2=str2+" "+m3
str3=str3+" "+m5
elif b == 2:
str1=str1+" "+m2
str2=str2+" "+m5
str3=str3+" "+m4
elif b == 3:
str1=str1+" "+m2
str2=str2+" "+m3
str3=str3+" "+m4
elif b == 4:
str1=str1+" "+m1
str2=str2+" "+m5
str3=str3+" "+m1
elif b == 5:
str1=str1+" "+m1
str2=str2+" "+m3
str3=str3+" "+m1
elif b == 6:
str1=str1+" "+m1
str2=str2+" "+m1
str3=str3+" "+m1
print(s)
print(str1)
print(str2)
print(str3)
print(s)


Is there a more compact and elegant way to do this?
Thanks in advance!










share|improve this question









New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I'm new to programming and in my project, I'm trying to print basic dice graphics. I'm trying to make a function that accepts two numbers from 1 to 6, and prints corresponding two dice faces next to each other. I've tried several approaches, but this is the only one that worked, and it's quite chunky:



s="+ - - - - + + - - - - +"
m1="| o o |"
m2="| o |"
m3="| o |"
m4="| o |"
m5="| |"

def dice(a,b):
if a == 1:
str1=m5
str2=m3
str3=m5
elif a == 2:
str1=m2
str2=m5
str3=m4
elif a == 3:
str1=m2
str2=m3
str3=m4
elif a == 4:
str1=m1
str2=m5
str3=m1
elif a == 5:
str1=m1
str2=m3
str3=m1
elif a == 6:
str1=m1
str2=m1
str3=m1
if b == 1:
str1=str1+" "+m5
str2=str2+" "+m3
str3=str3+" "+m5
elif b == 2:
str1=str1+" "+m2
str2=str2+" "+m5
str3=str3+" "+m4
elif b == 3:
str1=str1+" "+m2
str2=str2+" "+m3
str3=str3+" "+m4
elif b == 4:
str1=str1+" "+m1
str2=str2+" "+m5
str3=str3+" "+m1
elif b == 5:
str1=str1+" "+m1
str2=str2+" "+m3
str3=str3+" "+m1
elif b == 6:
str1=str1+" "+m1
str2=str2+" "+m1
str3=str3+" "+m1
print(s)
print(str1)
print(str2)
print(str3)
print(s)


Is there a more compact and elegant way to do this?
Thanks in advance!







python dice






share|improve this question









New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 37 mins ago









Willem Van Onsem

128k16124208




128k16124208






New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 1 hour ago









pythonwhizzkid

312




312




New contributor




pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






pythonwhizzkid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • Can you please first explain what you aim to do?
    – Willem Van Onsem
    1 hour ago






  • 2




    @WillemVanOnsem You can run the code to see what it does. It prints a pair of dice to the screen. OP is asking if there's a more compact and elegant way to do it.
    – Matt Messersmith
    1 hour ago










  • Select best matching anser when you are ready to play craps.. ;)
    – TadejP
    36 mins ago
















  • Can you please first explain what you aim to do?
    – Willem Van Onsem
    1 hour ago






  • 2




    @WillemVanOnsem You can run the code to see what it does. It prints a pair of dice to the screen. OP is asking if there's a more compact and elegant way to do it.
    – Matt Messersmith
    1 hour ago










  • Select best matching anser when you are ready to play craps.. ;)
    – TadejP
    36 mins ago















Can you please first explain what you aim to do?
– Willem Van Onsem
1 hour ago




Can you please first explain what you aim to do?
– Willem Van Onsem
1 hour ago




2




2




@WillemVanOnsem You can run the code to see what it does. It prints a pair of dice to the screen. OP is asking if there's a more compact and elegant way to do it.
– Matt Messersmith
1 hour ago




@WillemVanOnsem You can run the code to see what it does. It prints a pair of dice to the screen. OP is asking if there's a more compact and elegant way to do it.
– Matt Messersmith
1 hour ago












Select best matching anser when you are ready to play craps.. ;)
– TadejP
36 mins ago




Select best matching anser when you are ready to play craps.. ;)
– TadejP
36 mins ago












5 Answers
5






active

oldest

votes

















up vote
7
down vote













You're attempt shows already some good parts: finding common parts, and store these in separate variables.



But we can do a better job by implementing a single function that generates one die. For example:



s ="+ - - - - +"
m1="| o o |"
m2="| o |"
m3="| o |"
m4="| o |"
m5="| |"

dice = [
[m5, m3, m5],
[m2, m5, m4],
[m2, m3, m4],
[m1, m5, m1],
[m1, m3, m1],
[m1, m1, m1]
]


so now we can make a function for one die with:



def die(i):
return [s, *dice[i-1], s]


This will, for a given i in the range, return a list containing three strings.



We can then make function that joins the lines together, like:



def join_row(*rows):
return [' '.join(r) for r in zip(*rows)]


So now for two dice, we can define a function like:



def twodice(a, b):
for line in join_row(die(a), die(b)):
print(line)


The nice thing is that we can generalize this for any number of dice, for example:



def ndice(*ns):
for line in join_row(*map(die, ns)):
print(line)


For example:



>>> ndice(3, 2, 5, 1)
+ - - - - + + - - - - + + - - - - + + - - - - +
| o | | o | | o o | | |
| o | | | | o | | o |
| o | | o | | o o | | |
+ - - - - + + - - - - + + - - - - + + - - - - +
>>> ndice(1)
+ - - - - +
| |
| o |
| |
+ - - - - +
>>> ndice(1, 4)
+ - - - - + + - - - - +
| | | o o |
| o | | |
| | | o o |
+ - - - - + + - - - - +
>>> ndice(1, 4, 2)
+ - - - - + + - - - - + + - - - - +
| | | o o | | o |
| o | | | | |
| | | o o | | o |
+ - - - - + + - - - - + + - - - - +
>>> ndice(1, 4, 2, 5)
+ - - - - + + - - - - + + - - - - + + - - - - +
| | | o o | | o | | o o |
| o | | | | | | o |
| | | o o | | o | | o o |
+ - - - - + + - - - - + + - - - - + + - - - - +


A nice thing of this approach is that you get a lot of utility functions with this that you can reuse for similar problems. Furthermore each function does simple things, and thus the odds that there are huge problems with one of the functions is rather "low". If problems occur, it is typically easy to fix these.






share|improve this answer






















  • this answer was elegant and beautifully explained!
    – Mohammad Ganji
    1 hour ago










  • The singular of dice is one die.
    – wim
    1 hour ago











  • @wim: thanks updated :)
    – Willem Van Onsem
    1 hour ago

















up vote
2
down vote













You can write the string representations of all dice as a dictionary, with the keys from 1 to 6. As value, you can use a list of strings, composing the dice.



When printing, you pick lines from each set of values, according to the keys.



As on how to create the dictionaries, the approach can be like the one you took there, but it is made at once, without all the ifs -



s= "+ - - - - +"
m1="| o o |"
m2="| o |"
m3="| o |"
m4="| o |"
m5="| |"

die =
1: [s, m5, m3, m5, s],
2: ...,
...
6: [s, m2, m2, m2, s]


def print_dice(a, b):
for part1, part2 in zip(die[a], die[b)):
print (part1, part2)


The zip is responsible for, given two or more sequences or iterators, pick an element from each and yield a tuple with each element. The print function itself can print both parts of the dices.



And if insetead of two dices you want any number of them, you just have to use the "*" syntax in Python, it will work both in the function parameters, in the call to zip, and call to print:



def print_n_dice(*args):
for parts in zip(*(die[x] for x in args)):
print(*parts)





share|improve this answer





























    up vote
    2
    down vote













    Although you could do something really fancy, for such a relatively simple case something like this using some hardcoded data would be probably be fine (and changing how they look would also be very easy to do):



    DICE_DATA = """
    + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
    | |,| o |,| o |,| o o |,| o o |,| o o |
    | o |,| |,| o |,| |,| o |,| o o |
    | |,| o |,| o |,| o o |,| o o |,| o o |
    + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
    """

    faces = [ for _ in range(6)]
    for line in DICE_DATA.splitlines():
    for i, section in enumerate(line.split(',')):
    faces[i].append(section)

    for face in faces:
    print('n'.join(face)) # Print a single face.


    Output:



    + - - - - +
    | |
    | o |
    | |
    + - - - - +
    + - - - - +
    | o |
    | |
    | o |
    + - - - - +
    + - - - - +
    | o |
    | o |
    | o |
    + - - - - +
    + - - - - +
    | o o |
    | |
    | o o |
    + - - - - +
    + - - - - +
    | o o |
    | o |
    | o o |
    + - - - - +
    + - - - - +
    | o o |
    | o o |
    | o o |
    + - - - - +





    share|improve this answer





























      up vote
      1
      down vote













      Here's another variation on the theme. I encode the face patterns as numeric strings.



      rows = (
      "+ - - - - +",
      "| o o |",
      "| o |",
      "| o |",
      "| o |",
      "| |",
      )

      faces = ['555', '535', '254', '234', '151', '131', '111']

      def dice(n):
      out = [rows[0]]
      for u in faces[n]:
      out.append(rows[int(u)])
      out.append(rows[0])
      return out

      def multi_dice(*nums):
      buf = [ for _ in range(5)]
      for row, seg in zip(buf, zip(*[dice(n) for n in nums])):
      row.extend(seg)
      return 'n'.join(map(' '.join, buf))

      # Test showing all 6 faces
      print(multi_dice(1, 2, 3, 4, 5, 6))


      output



      + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
      | | | o | | o | | o o | | o o | | o o |
      | o | | | | o | | | | o | | o o |
      | | | o | | o | | o o | | o o | | o o |
      + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +


      We can reduce the dice function to one line, using a list comprehension:



      def dice(n):
      return [rows[0]] + [rows[int(u)] for u in faces[n]] + [rows[0]]


      As a bonus, if you pass n=0 to dice, you get a blank face.






      share|improve this answer



























        up vote
        1
        down vote













        You don't need to generate every line in a dice. Dice are symmetrical; the bottom half is a rotation of the top half. You can create one half purely with a few boolean tests to decide between an eye and not an eye; here are the dice values for when the three eyes in a half (ignoring the middle eye) are on:



        + - - - - - - - - - - +
        | 2,3,4,5,6 4,5,6 |
        |
        | 6


        The middle eye is there when the number is odd. So you can determine if an eye is off with value < 2, value < 4 and value < 6, respectively.



        The following version generates such a half without the central eye, then combines two halves ('rotating' the second half by reversing the string), and inserting the middle eye between them:



        def ascii_dice(v, e='o '):
        half = f'+ - - - - +n| e[v < 2] e[v < 4] |n| e[v < 6] '
        return f'halfe[~v & 1]half[::-1]'


        This produces any of the 6 dice faces on demand:



        >>> for i in range(1, 7):
        ... print(ascii_dice(i))
        ...
        + - - - - +
        | |
        | o |
        | |
        + - - - - +
        + - - - - +
        | o |
        | |
        | o |
        + - - - - +
        + - - - - +
        | o |
        | o |
        | o |
        + - - - - +
        + - - - - +
        | o o |
        | |
        | o o |
        + - - - - +
        + - - - - +
        | o o |
        | o |
        | o o |
        + - - - - +
        + - - - - +
        | o o |
        | o o |
        | o o |
        + - - - - +


        Next, combining multiple dice next to each other is simply a function of splitting up multiple blocks of lines and grouping the lines of each block; all the first lines together, second lines together, etc, then rejoining those with a space in between. That's a job zip() and str.join() are very good at:



        def multi_dice(*d, sep=' '):
        zipped = zip(*(ascii_dice(v).splitlines() for v in d))
        return 'n'.join([sep.join(l) for l in zipped])


        Now you can print as many dice next to each other as you could want:



        >>> print(multi_dice(*random.sample(range(1, 7), 6)))
        + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
        | o | | o o | | o o | | o | | | | o o |
        | | | o o | | o | | o | | o | | |
        | o | | o o | | o o | | o | | | | o o |
        + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +





        share|improve this answer






















          Your Answer





          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );






          pythonwhizzkid is a new contributor. Be nice, and check out our Code of Conduct.









           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52672240%2fdouble-dice-graphics-python%23new-answer', 'question_page');

          );

          Post as a guest






























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          7
          down vote













          You're attempt shows already some good parts: finding common parts, and store these in separate variables.



          But we can do a better job by implementing a single function that generates one die. For example:



          s ="+ - - - - +"
          m1="| o o |"
          m2="| o |"
          m3="| o |"
          m4="| o |"
          m5="| |"

          dice = [
          [m5, m3, m5],
          [m2, m5, m4],
          [m2, m3, m4],
          [m1, m5, m1],
          [m1, m3, m1],
          [m1, m1, m1]
          ]


          so now we can make a function for one die with:



          def die(i):
          return [s, *dice[i-1], s]


          This will, for a given i in the range, return a list containing three strings.



          We can then make function that joins the lines together, like:



          def join_row(*rows):
          return [' '.join(r) for r in zip(*rows)]


          So now for two dice, we can define a function like:



          def twodice(a, b):
          for line in join_row(die(a), die(b)):
          print(line)


          The nice thing is that we can generalize this for any number of dice, for example:



          def ndice(*ns):
          for line in join_row(*map(die, ns)):
          print(line)


          For example:



          >>> ndice(3, 2, 5, 1)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | o | | o | | o o | | |
          | o | | | | o | | o |
          | o | | o | | o o | | |
          + - - - - + + - - - - + + - - - - + + - - - - +
          >>> ndice(1)
          + - - - - +
          | |
          | o |
          | |
          + - - - - +
          >>> ndice(1, 4)
          + - - - - + + - - - - +
          | | | o o |
          | o | | |
          | | | o o |
          + - - - - + + - - - - +
          >>> ndice(1, 4, 2)
          + - - - - + + - - - - + + - - - - +
          | | | o o | | o |
          | o | | | | |
          | | | o o | | o |
          + - - - - + + - - - - + + - - - - +
          >>> ndice(1, 4, 2, 5)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | | | o o | | o | | o o |
          | o | | | | | | o |
          | | | o o | | o | | o o |
          + - - - - + + - - - - + + - - - - + + - - - - +


          A nice thing of this approach is that you get a lot of utility functions with this that you can reuse for similar problems. Furthermore each function does simple things, and thus the odds that there are huge problems with one of the functions is rather "low". If problems occur, it is typically easy to fix these.






          share|improve this answer






















          • this answer was elegant and beautifully explained!
            – Mohammad Ganji
            1 hour ago










          • The singular of dice is one die.
            – wim
            1 hour ago











          • @wim: thanks updated :)
            – Willem Van Onsem
            1 hour ago














          up vote
          7
          down vote













          You're attempt shows already some good parts: finding common parts, and store these in separate variables.



          But we can do a better job by implementing a single function that generates one die. For example:



          s ="+ - - - - +"
          m1="| o o |"
          m2="| o |"
          m3="| o |"
          m4="| o |"
          m5="| |"

          dice = [
          [m5, m3, m5],
          [m2, m5, m4],
          [m2, m3, m4],
          [m1, m5, m1],
          [m1, m3, m1],
          [m1, m1, m1]
          ]


          so now we can make a function for one die with:



          def die(i):
          return [s, *dice[i-1], s]


          This will, for a given i in the range, return a list containing three strings.



          We can then make function that joins the lines together, like:



          def join_row(*rows):
          return [' '.join(r) for r in zip(*rows)]


          So now for two dice, we can define a function like:



          def twodice(a, b):
          for line in join_row(die(a), die(b)):
          print(line)


          The nice thing is that we can generalize this for any number of dice, for example:



          def ndice(*ns):
          for line in join_row(*map(die, ns)):
          print(line)


          For example:



          >>> ndice(3, 2, 5, 1)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | o | | o | | o o | | |
          | o | | | | o | | o |
          | o | | o | | o o | | |
          + - - - - + + - - - - + + - - - - + + - - - - +
          >>> ndice(1)
          + - - - - +
          | |
          | o |
          | |
          + - - - - +
          >>> ndice(1, 4)
          + - - - - + + - - - - +
          | | | o o |
          | o | | |
          | | | o o |
          + - - - - + + - - - - +
          >>> ndice(1, 4, 2)
          + - - - - + + - - - - + + - - - - +
          | | | o o | | o |
          | o | | | | |
          | | | o o | | o |
          + - - - - + + - - - - + + - - - - +
          >>> ndice(1, 4, 2, 5)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | | | o o | | o | | o o |
          | o | | | | | | o |
          | | | o o | | o | | o o |
          + - - - - + + - - - - + + - - - - + + - - - - +


          A nice thing of this approach is that you get a lot of utility functions with this that you can reuse for similar problems. Furthermore each function does simple things, and thus the odds that there are huge problems with one of the functions is rather "low". If problems occur, it is typically easy to fix these.






          share|improve this answer






















          • this answer was elegant and beautifully explained!
            – Mohammad Ganji
            1 hour ago










          • The singular of dice is one die.
            – wim
            1 hour ago











          • @wim: thanks updated :)
            – Willem Van Onsem
            1 hour ago












          up vote
          7
          down vote










          up vote
          7
          down vote









          You're attempt shows already some good parts: finding common parts, and store these in separate variables.



          But we can do a better job by implementing a single function that generates one die. For example:



          s ="+ - - - - +"
          m1="| o o |"
          m2="| o |"
          m3="| o |"
          m4="| o |"
          m5="| |"

          dice = [
          [m5, m3, m5],
          [m2, m5, m4],
          [m2, m3, m4],
          [m1, m5, m1],
          [m1, m3, m1],
          [m1, m1, m1]
          ]


          so now we can make a function for one die with:



          def die(i):
          return [s, *dice[i-1], s]


          This will, for a given i in the range, return a list containing three strings.



          We can then make function that joins the lines together, like:



          def join_row(*rows):
          return [' '.join(r) for r in zip(*rows)]


          So now for two dice, we can define a function like:



          def twodice(a, b):
          for line in join_row(die(a), die(b)):
          print(line)


          The nice thing is that we can generalize this for any number of dice, for example:



          def ndice(*ns):
          for line in join_row(*map(die, ns)):
          print(line)


          For example:



          >>> ndice(3, 2, 5, 1)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | o | | o | | o o | | |
          | o | | | | o | | o |
          | o | | o | | o o | | |
          + - - - - + + - - - - + + - - - - + + - - - - +
          >>> ndice(1)
          + - - - - +
          | |
          | o |
          | |
          + - - - - +
          >>> ndice(1, 4)
          + - - - - + + - - - - +
          | | | o o |
          | o | | |
          | | | o o |
          + - - - - + + - - - - +
          >>> ndice(1, 4, 2)
          + - - - - + + - - - - + + - - - - +
          | | | o o | | o |
          | o | | | | |
          | | | o o | | o |
          + - - - - + + - - - - + + - - - - +
          >>> ndice(1, 4, 2, 5)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | | | o o | | o | | o o |
          | o | | | | | | o |
          | | | o o | | o | | o o |
          + - - - - + + - - - - + + - - - - + + - - - - +


          A nice thing of this approach is that you get a lot of utility functions with this that you can reuse for similar problems. Furthermore each function does simple things, and thus the odds that there are huge problems with one of the functions is rather "low". If problems occur, it is typically easy to fix these.






          share|improve this answer














          You're attempt shows already some good parts: finding common parts, and store these in separate variables.



          But we can do a better job by implementing a single function that generates one die. For example:



          s ="+ - - - - +"
          m1="| o o |"
          m2="| o |"
          m3="| o |"
          m4="| o |"
          m5="| |"

          dice = [
          [m5, m3, m5],
          [m2, m5, m4],
          [m2, m3, m4],
          [m1, m5, m1],
          [m1, m3, m1],
          [m1, m1, m1]
          ]


          so now we can make a function for one die with:



          def die(i):
          return [s, *dice[i-1], s]


          This will, for a given i in the range, return a list containing three strings.



          We can then make function that joins the lines together, like:



          def join_row(*rows):
          return [' '.join(r) for r in zip(*rows)]


          So now for two dice, we can define a function like:



          def twodice(a, b):
          for line in join_row(die(a), die(b)):
          print(line)


          The nice thing is that we can generalize this for any number of dice, for example:



          def ndice(*ns):
          for line in join_row(*map(die, ns)):
          print(line)


          For example:



          >>> ndice(3, 2, 5, 1)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | o | | o | | o o | | |
          | o | | | | o | | o |
          | o | | o | | o o | | |
          + - - - - + + - - - - + + - - - - + + - - - - +
          >>> ndice(1)
          + - - - - +
          | |
          | o |
          | |
          + - - - - +
          >>> ndice(1, 4)
          + - - - - + + - - - - +
          | | | o o |
          | o | | |
          | | | o o |
          + - - - - + + - - - - +
          >>> ndice(1, 4, 2)
          + - - - - + + - - - - + + - - - - +
          | | | o o | | o |
          | o | | | | |
          | | | o o | | o |
          + - - - - + + - - - - + + - - - - +
          >>> ndice(1, 4, 2, 5)
          + - - - - + + - - - - + + - - - - + + - - - - +
          | | | o o | | o | | o o |
          | o | | | | | | o |
          | | | o o | | o | | o o |
          + - - - - + + - - - - + + - - - - + + - - - - +


          A nice thing of this approach is that you get a lot of utility functions with this that you can reuse for similar problems. Furthermore each function does simple things, and thus the odds that there are huge problems with one of the functions is rather "low". If problems occur, it is typically easy to fix these.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 1 hour ago

























          answered 1 hour ago









          Willem Van Onsem

          128k16124208




          128k16124208











          • this answer was elegant and beautifully explained!
            – Mohammad Ganji
            1 hour ago










          • The singular of dice is one die.
            – wim
            1 hour ago











          • @wim: thanks updated :)
            – Willem Van Onsem
            1 hour ago
















          • this answer was elegant and beautifully explained!
            – Mohammad Ganji
            1 hour ago










          • The singular of dice is one die.
            – wim
            1 hour ago











          • @wim: thanks updated :)
            – Willem Van Onsem
            1 hour ago















          this answer was elegant and beautifully explained!
          – Mohammad Ganji
          1 hour ago




          this answer was elegant and beautifully explained!
          – Mohammad Ganji
          1 hour ago












          The singular of dice is one die.
          – wim
          1 hour ago





          The singular of dice is one die.
          – wim
          1 hour ago













          @wim: thanks updated :)
          – Willem Van Onsem
          1 hour ago




          @wim: thanks updated :)
          – Willem Van Onsem
          1 hour ago












          up vote
          2
          down vote













          You can write the string representations of all dice as a dictionary, with the keys from 1 to 6. As value, you can use a list of strings, composing the dice.



          When printing, you pick lines from each set of values, according to the keys.



          As on how to create the dictionaries, the approach can be like the one you took there, but it is made at once, without all the ifs -



          s= "+ - - - - +"
          m1="| o o |"
          m2="| o |"
          m3="| o |"
          m4="| o |"
          m5="| |"

          die =
          1: [s, m5, m3, m5, s],
          2: ...,
          ...
          6: [s, m2, m2, m2, s]


          def print_dice(a, b):
          for part1, part2 in zip(die[a], die[b)):
          print (part1, part2)


          The zip is responsible for, given two or more sequences or iterators, pick an element from each and yield a tuple with each element. The print function itself can print both parts of the dices.



          And if insetead of two dices you want any number of them, you just have to use the "*" syntax in Python, it will work both in the function parameters, in the call to zip, and call to print:



          def print_n_dice(*args):
          for parts in zip(*(die[x] for x in args)):
          print(*parts)





          share|improve this answer


























            up vote
            2
            down vote













            You can write the string representations of all dice as a dictionary, with the keys from 1 to 6. As value, you can use a list of strings, composing the dice.



            When printing, you pick lines from each set of values, according to the keys.



            As on how to create the dictionaries, the approach can be like the one you took there, but it is made at once, without all the ifs -



            s= "+ - - - - +"
            m1="| o o |"
            m2="| o |"
            m3="| o |"
            m4="| o |"
            m5="| |"

            die =
            1: [s, m5, m3, m5, s],
            2: ...,
            ...
            6: [s, m2, m2, m2, s]


            def print_dice(a, b):
            for part1, part2 in zip(die[a], die[b)):
            print (part1, part2)


            The zip is responsible for, given two or more sequences or iterators, pick an element from each and yield a tuple with each element. The print function itself can print both parts of the dices.



            And if insetead of two dices you want any number of them, you just have to use the "*" syntax in Python, it will work both in the function parameters, in the call to zip, and call to print:



            def print_n_dice(*args):
            for parts in zip(*(die[x] for x in args)):
            print(*parts)





            share|improve this answer
























              up vote
              2
              down vote










              up vote
              2
              down vote









              You can write the string representations of all dice as a dictionary, with the keys from 1 to 6. As value, you can use a list of strings, composing the dice.



              When printing, you pick lines from each set of values, according to the keys.



              As on how to create the dictionaries, the approach can be like the one you took there, but it is made at once, without all the ifs -



              s= "+ - - - - +"
              m1="| o o |"
              m2="| o |"
              m3="| o |"
              m4="| o |"
              m5="| |"

              die =
              1: [s, m5, m3, m5, s],
              2: ...,
              ...
              6: [s, m2, m2, m2, s]


              def print_dice(a, b):
              for part1, part2 in zip(die[a], die[b)):
              print (part1, part2)


              The zip is responsible for, given two or more sequences or iterators, pick an element from each and yield a tuple with each element. The print function itself can print both parts of the dices.



              And if insetead of two dices you want any number of them, you just have to use the "*" syntax in Python, it will work both in the function parameters, in the call to zip, and call to print:



              def print_n_dice(*args):
              for parts in zip(*(die[x] for x in args)):
              print(*parts)





              share|improve this answer














              You can write the string representations of all dice as a dictionary, with the keys from 1 to 6. As value, you can use a list of strings, composing the dice.



              When printing, you pick lines from each set of values, according to the keys.



              As on how to create the dictionaries, the approach can be like the one you took there, but it is made at once, without all the ifs -



              s= "+ - - - - +"
              m1="| o o |"
              m2="| o |"
              m3="| o |"
              m4="| o |"
              m5="| |"

              die =
              1: [s, m5, m3, m5, s],
              2: ...,
              ...
              6: [s, m2, m2, m2, s]


              def print_dice(a, b):
              for part1, part2 in zip(die[a], die[b)):
              print (part1, part2)


              The zip is responsible for, given two or more sequences or iterators, pick an element from each and yield a tuple with each element. The print function itself can print both parts of the dices.



              And if insetead of two dices you want any number of them, you just have to use the "*" syntax in Python, it will work both in the function parameters, in the call to zip, and call to print:



              def print_n_dice(*args):
              for parts in zip(*(die[x] for x in args)):
              print(*parts)






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 1 hour ago

























              answered 1 hour ago









              jsbueno

              53.6k671124




              53.6k671124




















                  up vote
                  2
                  down vote













                  Although you could do something really fancy, for such a relatively simple case something like this using some hardcoded data would be probably be fine (and changing how they look would also be very easy to do):



                  DICE_DATA = """
                  + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                  | |,| o |,| o |,| o o |,| o o |,| o o |
                  | o |,| |,| o |,| |,| o |,| o o |
                  | |,| o |,| o |,| o o |,| o o |,| o o |
                  + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                  """

                  faces = [ for _ in range(6)]
                  for line in DICE_DATA.splitlines():
                  for i, section in enumerate(line.split(',')):
                  faces[i].append(section)

                  for face in faces:
                  print('n'.join(face)) # Print a single face.


                  Output:



                  + - - - - +
                  | |
                  | o |
                  | |
                  + - - - - +
                  + - - - - +
                  | o |
                  | |
                  | o |
                  + - - - - +
                  + - - - - +
                  | o |
                  | o |
                  | o |
                  + - - - - +
                  + - - - - +
                  | o o |
                  | |
                  | o o |
                  + - - - - +
                  + - - - - +
                  | o o |
                  | o |
                  | o o |
                  + - - - - +
                  + - - - - +
                  | o o |
                  | o o |
                  | o o |
                  + - - - - +





                  share|improve this answer


























                    up vote
                    2
                    down vote













                    Although you could do something really fancy, for such a relatively simple case something like this using some hardcoded data would be probably be fine (and changing how they look would also be very easy to do):



                    DICE_DATA = """
                    + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                    | |,| o |,| o |,| o o |,| o o |,| o o |
                    | o |,| |,| o |,| |,| o |,| o o |
                    | |,| o |,| o |,| o o |,| o o |,| o o |
                    + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                    """

                    faces = [ for _ in range(6)]
                    for line in DICE_DATA.splitlines():
                    for i, section in enumerate(line.split(',')):
                    faces[i].append(section)

                    for face in faces:
                    print('n'.join(face)) # Print a single face.


                    Output:



                    + - - - - +
                    | |
                    | o |
                    | |
                    + - - - - +
                    + - - - - +
                    | o |
                    | |
                    | o |
                    + - - - - +
                    + - - - - +
                    | o |
                    | o |
                    | o |
                    + - - - - +
                    + - - - - +
                    | o o |
                    | |
                    | o o |
                    + - - - - +
                    + - - - - +
                    | o o |
                    | o |
                    | o o |
                    + - - - - +
                    + - - - - +
                    | o o |
                    | o o |
                    | o o |
                    + - - - - +





                    share|improve this answer
























                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      Although you could do something really fancy, for such a relatively simple case something like this using some hardcoded data would be probably be fine (and changing how they look would also be very easy to do):



                      DICE_DATA = """
                      + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                      | |,| o |,| o |,| o o |,| o o |,| o o |
                      | o |,| |,| o |,| |,| o |,| o o |
                      | |,| o |,| o |,| o o |,| o o |,| o o |
                      + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                      """

                      faces = [ for _ in range(6)]
                      for line in DICE_DATA.splitlines():
                      for i, section in enumerate(line.split(',')):
                      faces[i].append(section)

                      for face in faces:
                      print('n'.join(face)) # Print a single face.


                      Output:



                      + - - - - +
                      | |
                      | o |
                      | |
                      + - - - - +
                      + - - - - +
                      | o |
                      | |
                      | o |
                      + - - - - +
                      + - - - - +
                      | o |
                      | o |
                      | o |
                      + - - - - +
                      + - - - - +
                      | o o |
                      | |
                      | o o |
                      + - - - - +
                      + - - - - +
                      | o o |
                      | o |
                      | o o |
                      + - - - - +
                      + - - - - +
                      | o o |
                      | o o |
                      | o o |
                      + - - - - +





                      share|improve this answer














                      Although you could do something really fancy, for such a relatively simple case something like this using some hardcoded data would be probably be fine (and changing how they look would also be very easy to do):



                      DICE_DATA = """
                      + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                      | |,| o |,| o |,| o o |,| o o |,| o o |
                      | o |,| |,| o |,| |,| o |,| o o |
                      | |,| o |,| o |,| o o |,| o o |,| o o |
                      + - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +,+ - - - - +
                      """

                      faces = [ for _ in range(6)]
                      for line in DICE_DATA.splitlines():
                      for i, section in enumerate(line.split(',')):
                      faces[i].append(section)

                      for face in faces:
                      print('n'.join(face)) # Print a single face.


                      Output:



                      + - - - - +
                      | |
                      | o |
                      | |
                      + - - - - +
                      + - - - - +
                      | o |
                      | |
                      | o |
                      + - - - - +
                      + - - - - +
                      | o |
                      | o |
                      | o |
                      + - - - - +
                      + - - - - +
                      | o o |
                      | |
                      | o o |
                      + - - - - +
                      + - - - - +
                      | o o |
                      | o |
                      | o o |
                      + - - - - +
                      + - - - - +
                      | o o |
                      | o o |
                      | o o |
                      + - - - - +






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 19 mins ago

























                      answered 58 mins ago









                      martineau

                      62.7k887167




                      62.7k887167




















                          up vote
                          1
                          down vote













                          Here's another variation on the theme. I encode the face patterns as numeric strings.



                          rows = (
                          "+ - - - - +",
                          "| o o |",
                          "| o |",
                          "| o |",
                          "| o |",
                          "| |",
                          )

                          faces = ['555', '535', '254', '234', '151', '131', '111']

                          def dice(n):
                          out = [rows[0]]
                          for u in faces[n]:
                          out.append(rows[int(u)])
                          out.append(rows[0])
                          return out

                          def multi_dice(*nums):
                          buf = [ for _ in range(5)]
                          for row, seg in zip(buf, zip(*[dice(n) for n in nums])):
                          row.extend(seg)
                          return 'n'.join(map(' '.join, buf))

                          # Test showing all 6 faces
                          print(multi_dice(1, 2, 3, 4, 5, 6))


                          output



                          + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                          | | | o | | o | | o o | | o o | | o o |
                          | o | | | | o | | | | o | | o o |
                          | | | o | | o | | o o | | o o | | o o |
                          + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +


                          We can reduce the dice function to one line, using a list comprehension:



                          def dice(n):
                          return [rows[0]] + [rows[int(u)] for u in faces[n]] + [rows[0]]


                          As a bonus, if you pass n=0 to dice, you get a blank face.






                          share|improve this answer
























                            up vote
                            1
                            down vote













                            Here's another variation on the theme. I encode the face patterns as numeric strings.



                            rows = (
                            "+ - - - - +",
                            "| o o |",
                            "| o |",
                            "| o |",
                            "| o |",
                            "| |",
                            )

                            faces = ['555', '535', '254', '234', '151', '131', '111']

                            def dice(n):
                            out = [rows[0]]
                            for u in faces[n]:
                            out.append(rows[int(u)])
                            out.append(rows[0])
                            return out

                            def multi_dice(*nums):
                            buf = [ for _ in range(5)]
                            for row, seg in zip(buf, zip(*[dice(n) for n in nums])):
                            row.extend(seg)
                            return 'n'.join(map(' '.join, buf))

                            # Test showing all 6 faces
                            print(multi_dice(1, 2, 3, 4, 5, 6))


                            output



                            + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                            | | | o | | o | | o o | | o o | | o o |
                            | o | | | | o | | | | o | | o o |
                            | | | o | | o | | o o | | o o | | o o |
                            + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +


                            We can reduce the dice function to one line, using a list comprehension:



                            def dice(n):
                            return [rows[0]] + [rows[int(u)] for u in faces[n]] + [rows[0]]


                            As a bonus, if you pass n=0 to dice, you get a blank face.






                            share|improve this answer






















                              up vote
                              1
                              down vote










                              up vote
                              1
                              down vote









                              Here's another variation on the theme. I encode the face patterns as numeric strings.



                              rows = (
                              "+ - - - - +",
                              "| o o |",
                              "| o |",
                              "| o |",
                              "| o |",
                              "| |",
                              )

                              faces = ['555', '535', '254', '234', '151', '131', '111']

                              def dice(n):
                              out = [rows[0]]
                              for u in faces[n]:
                              out.append(rows[int(u)])
                              out.append(rows[0])
                              return out

                              def multi_dice(*nums):
                              buf = [ for _ in range(5)]
                              for row, seg in zip(buf, zip(*[dice(n) for n in nums])):
                              row.extend(seg)
                              return 'n'.join(map(' '.join, buf))

                              # Test showing all 6 faces
                              print(multi_dice(1, 2, 3, 4, 5, 6))


                              output



                              + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                              | | | o | | o | | o o | | o o | | o o |
                              | o | | | | o | | | | o | | o o |
                              | | | o | | o | | o o | | o o | | o o |
                              + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +


                              We can reduce the dice function to one line, using a list comprehension:



                              def dice(n):
                              return [rows[0]] + [rows[int(u)] for u in faces[n]] + [rows[0]]


                              As a bonus, if you pass n=0 to dice, you get a blank face.






                              share|improve this answer












                              Here's another variation on the theme. I encode the face patterns as numeric strings.



                              rows = (
                              "+ - - - - +",
                              "| o o |",
                              "| o |",
                              "| o |",
                              "| o |",
                              "| |",
                              )

                              faces = ['555', '535', '254', '234', '151', '131', '111']

                              def dice(n):
                              out = [rows[0]]
                              for u in faces[n]:
                              out.append(rows[int(u)])
                              out.append(rows[0])
                              return out

                              def multi_dice(*nums):
                              buf = [ for _ in range(5)]
                              for row, seg in zip(buf, zip(*[dice(n) for n in nums])):
                              row.extend(seg)
                              return 'n'.join(map(' '.join, buf))

                              # Test showing all 6 faces
                              print(multi_dice(1, 2, 3, 4, 5, 6))


                              output



                              + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                              | | | o | | o | | o o | | o o | | o o |
                              | o | | | | o | | | | o | | o o |
                              | | | o | | o | | o o | | o o | | o o |
                              + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +


                              We can reduce the dice function to one line, using a list comprehension:



                              def dice(n):
                              return [rows[0]] + [rows[int(u)] for u in faces[n]] + [rows[0]]


                              As a bonus, if you pass n=0 to dice, you get a blank face.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 1 hour ago









                              PM 2Ring

                              42.2k43787




                              42.2k43787




















                                  up vote
                                  1
                                  down vote













                                  You don't need to generate every line in a dice. Dice are symmetrical; the bottom half is a rotation of the top half. You can create one half purely with a few boolean tests to decide between an eye and not an eye; here are the dice values for when the three eyes in a half (ignoring the middle eye) are on:



                                  + - - - - - - - - - - +
                                  | 2,3,4,5,6 4,5,6 |
                                  |
                                  | 6


                                  The middle eye is there when the number is odd. So you can determine if an eye is off with value < 2, value < 4 and value < 6, respectively.



                                  The following version generates such a half without the central eye, then combines two halves ('rotating' the second half by reversing the string), and inserting the middle eye between them:



                                  def ascii_dice(v, e='o '):
                                  half = f'+ - - - - +n| e[v < 2] e[v < 4] |n| e[v < 6] '
                                  return f'halfe[~v & 1]half[::-1]'


                                  This produces any of the 6 dice faces on demand:



                                  >>> for i in range(1, 7):
                                  ... print(ascii_dice(i))
                                  ...
                                  + - - - - +
                                  | |
                                  | o |
                                  | |
                                  + - - - - +
                                  + - - - - +
                                  | o |
                                  | |
                                  | o |
                                  + - - - - +
                                  + - - - - +
                                  | o |
                                  | o |
                                  | o |
                                  + - - - - +
                                  + - - - - +
                                  | o o |
                                  | |
                                  | o o |
                                  + - - - - +
                                  + - - - - +
                                  | o o |
                                  | o |
                                  | o o |
                                  + - - - - +
                                  + - - - - +
                                  | o o |
                                  | o o |
                                  | o o |
                                  + - - - - +


                                  Next, combining multiple dice next to each other is simply a function of splitting up multiple blocks of lines and grouping the lines of each block; all the first lines together, second lines together, etc, then rejoining those with a space in between. That's a job zip() and str.join() are very good at:



                                  def multi_dice(*d, sep=' '):
                                  zipped = zip(*(ascii_dice(v).splitlines() for v in d))
                                  return 'n'.join([sep.join(l) for l in zipped])


                                  Now you can print as many dice next to each other as you could want:



                                  >>> print(multi_dice(*random.sample(range(1, 7), 6)))
                                  + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                                  | o | | o o | | o o | | o | | | | o o |
                                  | | | o o | | o | | o | | o | | |
                                  | o | | o o | | o o | | o | | | | o o |
                                  + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +





                                  share|improve this answer


























                                    up vote
                                    1
                                    down vote













                                    You don't need to generate every line in a dice. Dice are symmetrical; the bottom half is a rotation of the top half. You can create one half purely with a few boolean tests to decide between an eye and not an eye; here are the dice values for when the three eyes in a half (ignoring the middle eye) are on:



                                    + - - - - - - - - - - +
                                    | 2,3,4,5,6 4,5,6 |
                                    |
                                    | 6


                                    The middle eye is there when the number is odd. So you can determine if an eye is off with value < 2, value < 4 and value < 6, respectively.



                                    The following version generates such a half without the central eye, then combines two halves ('rotating' the second half by reversing the string), and inserting the middle eye between them:



                                    def ascii_dice(v, e='o '):
                                    half = f'+ - - - - +n| e[v < 2] e[v < 4] |n| e[v < 6] '
                                    return f'halfe[~v & 1]half[::-1]'


                                    This produces any of the 6 dice faces on demand:



                                    >>> for i in range(1, 7):
                                    ... print(ascii_dice(i))
                                    ...
                                    + - - - - +
                                    | |
                                    | o |
                                    | |
                                    + - - - - +
                                    + - - - - +
                                    | o |
                                    | |
                                    | o |
                                    + - - - - +
                                    + - - - - +
                                    | o |
                                    | o |
                                    | o |
                                    + - - - - +
                                    + - - - - +
                                    | o o |
                                    | |
                                    | o o |
                                    + - - - - +
                                    + - - - - +
                                    | o o |
                                    | o |
                                    | o o |
                                    + - - - - +
                                    + - - - - +
                                    | o o |
                                    | o o |
                                    | o o |
                                    + - - - - +


                                    Next, combining multiple dice next to each other is simply a function of splitting up multiple blocks of lines and grouping the lines of each block; all the first lines together, second lines together, etc, then rejoining those with a space in between. That's a job zip() and str.join() are very good at:



                                    def multi_dice(*d, sep=' '):
                                    zipped = zip(*(ascii_dice(v).splitlines() for v in d))
                                    return 'n'.join([sep.join(l) for l in zipped])


                                    Now you can print as many dice next to each other as you could want:



                                    >>> print(multi_dice(*random.sample(range(1, 7), 6)))
                                    + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                                    | o | | o o | | o o | | o | | | | o o |
                                    | | | o o | | o | | o | | o | | |
                                    | o | | o o | | o o | | o | | | | o o |
                                    + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +





                                    share|improve this answer
























                                      up vote
                                      1
                                      down vote










                                      up vote
                                      1
                                      down vote









                                      You don't need to generate every line in a dice. Dice are symmetrical; the bottom half is a rotation of the top half. You can create one half purely with a few boolean tests to decide between an eye and not an eye; here are the dice values for when the three eyes in a half (ignoring the middle eye) are on:



                                      + - - - - - - - - - - +
                                      | 2,3,4,5,6 4,5,6 |
                                      |
                                      | 6


                                      The middle eye is there when the number is odd. So you can determine if an eye is off with value < 2, value < 4 and value < 6, respectively.



                                      The following version generates such a half without the central eye, then combines two halves ('rotating' the second half by reversing the string), and inserting the middle eye between them:



                                      def ascii_dice(v, e='o '):
                                      half = f'+ - - - - +n| e[v < 2] e[v < 4] |n| e[v < 6] '
                                      return f'halfe[~v & 1]half[::-1]'


                                      This produces any of the 6 dice faces on demand:



                                      >>> for i in range(1, 7):
                                      ... print(ascii_dice(i))
                                      ...
                                      + - - - - +
                                      | |
                                      | o |
                                      | |
                                      + - - - - +
                                      + - - - - +
                                      | o |
                                      | |
                                      | o |
                                      + - - - - +
                                      + - - - - +
                                      | o |
                                      | o |
                                      | o |
                                      + - - - - +
                                      + - - - - +
                                      | o o |
                                      | |
                                      | o o |
                                      + - - - - +
                                      + - - - - +
                                      | o o |
                                      | o |
                                      | o o |
                                      + - - - - +
                                      + - - - - +
                                      | o o |
                                      | o o |
                                      | o o |
                                      + - - - - +


                                      Next, combining multiple dice next to each other is simply a function of splitting up multiple blocks of lines and grouping the lines of each block; all the first lines together, second lines together, etc, then rejoining those with a space in between. That's a job zip() and str.join() are very good at:



                                      def multi_dice(*d, sep=' '):
                                      zipped = zip(*(ascii_dice(v).splitlines() for v in d))
                                      return 'n'.join([sep.join(l) for l in zipped])


                                      Now you can print as many dice next to each other as you could want:



                                      >>> print(multi_dice(*random.sample(range(1, 7), 6)))
                                      + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                                      | o | | o o | | o o | | o | | | | o o |
                                      | | | o o | | o | | o | | o | | |
                                      | o | | o o | | o o | | o | | | | o o |
                                      + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +





                                      share|improve this answer














                                      You don't need to generate every line in a dice. Dice are symmetrical; the bottom half is a rotation of the top half. You can create one half purely with a few boolean tests to decide between an eye and not an eye; here are the dice values for when the three eyes in a half (ignoring the middle eye) are on:



                                      + - - - - - - - - - - +
                                      | 2,3,4,5,6 4,5,6 |
                                      |
                                      | 6


                                      The middle eye is there when the number is odd. So you can determine if an eye is off with value < 2, value < 4 and value < 6, respectively.



                                      The following version generates such a half without the central eye, then combines two halves ('rotating' the second half by reversing the string), and inserting the middle eye between them:



                                      def ascii_dice(v, e='o '):
                                      half = f'+ - - - - +n| e[v < 2] e[v < 4] |n| e[v < 6] '
                                      return f'halfe[~v & 1]half[::-1]'


                                      This produces any of the 6 dice faces on demand:



                                      >>> for i in range(1, 7):
                                      ... print(ascii_dice(i))
                                      ...
                                      + - - - - +
                                      | |
                                      | o |
                                      | |
                                      + - - - - +
                                      + - - - - +
                                      | o |
                                      | |
                                      | o |
                                      + - - - - +
                                      + - - - - +
                                      | o |
                                      | o |
                                      | o |
                                      + - - - - +
                                      + - - - - +
                                      | o o |
                                      | |
                                      | o o |
                                      + - - - - +
                                      + - - - - +
                                      | o o |
                                      | o |
                                      | o o |
                                      + - - - - +
                                      + - - - - +
                                      | o o |
                                      | o o |
                                      | o o |
                                      + - - - - +


                                      Next, combining multiple dice next to each other is simply a function of splitting up multiple blocks of lines and grouping the lines of each block; all the first lines together, second lines together, etc, then rejoining those with a space in between. That's a job zip() and str.join() are very good at:



                                      def multi_dice(*d, sep=' '):
                                      zipped = zip(*(ascii_dice(v).splitlines() for v in d))
                                      return 'n'.join([sep.join(l) for l in zipped])


                                      Now you can print as many dice next to each other as you could want:



                                      >>> print(multi_dice(*random.sample(range(1, 7), 6)))
                                      + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +
                                      | o | | o o | | o o | | o | | | | o o |
                                      | | | o o | | o | | o | | o | | |
                                      | o | | o o | | o o | | o | | | | o o |
                                      + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - +






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited 19 mins ago

























                                      answered 49 mins ago









                                      Martijn Pieters♦

                                      678k11923172179




                                      678k11923172179




















                                          pythonwhizzkid is a new contributor. Be nice, and check out our Code of Conduct.









                                           

                                          draft saved


                                          draft discarded


















                                          pythonwhizzkid is a new contributor. Be nice, and check out our Code of Conduct.












                                          pythonwhizzkid is a new contributor. Be nice, and check out our Code of Conduct.











                                          pythonwhizzkid is a new contributor. Be nice, and check out our Code of Conduct.













                                           


                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52672240%2fdouble-dice-graphics-python%23new-answer', 'question_page');

                                          );

                                          Post as a guest













































































                                          Comments

                                          Popular posts from this blog

                                          Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                          Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                          Confectionery