Is there a better way of printing my dice result in my dice roll function?

Question:

So I’m writing a dice_roll function for 2 dices to be rolled for my dice game project, currently I want to include the corresponding dice result in a dice format.

Although the code does work, I was wondering if there was a better way of printing out the dice format instead of putting it through an array like this so that the output doesn’t have additional brackets and only shows the dice result like this:

[0   0]
[  0  ]
[0   0]

I am a beginner at coding so I’m unsure of any other methods other than arrays.

This is the code I have:

def dice_roll(): # rolls 2 six-sided dice
  dice1 = random.randint(1,6)
  print("Dice 1: You rolled a", dice1, "n"

  if dice1 == 1:
    dice_layer1 = np.array(["[     ]"])
    dice_layer2 = np.array(["[  0  ]"])
    dice_layer3 = np.array(["[     ]"])
    roll_animation = np.array([dice_layer1, dice_layer2, dice_layer3])
    print(roll_animation, "n")

  elif dice1 == 2:
    dice_layer1 = np.array(["[0    ]"])
    dice_layer2 = np.array(["[     ]"])
    dice_layer3 = np.array(["[    0]"])
    roll_animation = np.array([dice_layer1, dice_layer2, dice_layer3])
    print(roll_animation, "n")
  
  elif dice1 == 3:
    dice_layer1 = np.array(["[0    ]"])
    dice_layer2 = np.array(["[  0  ]"])
    dice_layer3 = np.array(["[    0]"])
    roll_animation = np.array([dice_layer1, dice_layer2, dice_layer3])
    print(roll_animation, "n")
    
  elif dice1 == 4:
    dice_layer1 = np.array(["[0   0]"])
    dice_layer2 = np.array(["[     ]"])
    dice_layer3 = np.array(["[0   0]"])
    roll_animation = np.array([dice_layer1, dice_layer2, dice_layer3])
    print(roll_animation, "n")
  
  elif dice1 == 5:
    dice_layer1 = np.array(["[0   0]"])
    dice_layer2 = np.array(["[  0  ]"])
    dice_layer3 = np.array(["[0   0]"])
    roll_animation = np.array([dice_layer1, dice_layer2, dice_layer3])
    print(roll_animation, "n")
  
  elif dice1 == 6:
    dice_layer1 = np.array(["[0   0]"])
    dice_layer2 = np.array(["[0   0]"])
    dice_layer3 = np.array(["[0   0]"])
    roll_animation = np.array([dice_layer1, dice_layer2, dice_layer3])
    print(roll_animation, "n")
    

I then repeat this code but instead for dice2

Asked By: chenn_jr

||

Answers:

I would use a dictionary to store all the dot positions so you don’t have to repeat your code all the time:

dice_dict = {
    1: [4],
    2: [0, 8],
    3: [0, 4, 8],
    4: [0, 2, 6, 8],
    5: [0, 2, 4, 6, 8],
    6: [0, 2, 3, 5, 6, 8]
}

for roll, dots in dice_dict.items():
    for i in range(0, 9, 3):
        print(f'[{" ".join(["0" if j in dots else " " for j in range(i, i+3)])}]')
    print()

This example will print all dice in order.

Answered By: B Remmelzwaal

Repeating your code with dice1 replaced by dice2 falls foul of a principle of software development — don’t repeat yourself!

Instead, create a function that will print a die for a given value. You can define a list that contains strings that depict all the faces of the die:

die_faces = ["", # index = 0 doesn't have a face
             "[     ]n[  0  ]n[     ]", # index 1
             "[0    ]n[     ]n[    0]", # index 2
             "[0    ]n[  0  ]n[    0]", # index 3
             "[0   0]n[     ]n[0   0]", # index 4
             "[0   0]n[  0  ]n[0   0]", # index 5
             "[0   0]n[0   0]n[0   0]", # index 6
             ]

def print_die(value: int):
    print(die_faces[value])

Then, in your function you could do:

def dice_roll():
    die1 = random.randint(1,6)
    print(f"Die 1: You rolled a {die1}")
    print_die(die1)

    die2 = random.randint(1,6)
    print(f"Die 2: You rolled a {die2}")
    print_die(die2)

which prints, e.g.:

Die 1: You rolled a 2
[0    ]
[     ]
[    0]
Die 2: You rolled a 3
[0    ]
[  0  ]
[    0]

Since you mention that you want to print multiple dice side-by-side, recognize that you need to print the first lines of each die first, then the second lines, and then the third lines. You can do this quite easily by splitting the lines of each face, and then iterating over the zip of the resulting lists.

def print_dice(values: list[int]):
    faces = [die_faces[v].splitlines() for v in values]
    for line in zip(*faces):
        print(*line)

Now, you can call this function like:

print_dice([1, 2, 3])

which will print:

[     ] [0    ] [0    ]
[  0  ] [     ] [  0  ]
[     ] [    0] [    0]

Implementing this in your function,

def dice_roll(num_dice=2): # rolls `num_dice` six-sided dice
    all_dice = [random.randint(1,6) for _ in range(num_dice)]
    print(f"You rolled ", all_dice)
    print_dice(all_dice)

and calling it with, e.g.

dice_roll(3)
You rolled  [2, 5, 2]
[0    ] [0   0] [0    ]
[     ] [  0  ] [     ]
[    0] [0   0] [    0]
Answered By: Pranav Hosangadi

As others have mentioned, the visual representation can be documented within a string.

A simplified version of your code would be to put each dice string into a list, then use your random int to get the index of the corresponding dice:

def roll_dice():
    sides = ["[     ]n[  0  ]n[     ]", "[0    ]n[     ]n[    0]", "[0    ]n[  0  ]n[    0]", "[0   0]n[     ]n[0   0]", "[0   0]n[  0  ]n[0   0]", "[0   0]n[0   0]n[0   0]"]
    rolled_number = random.randint(1,6)
    return rolled_number, sides[rolled_number - 1]

def play_game():
    roll1, dice1 = roll_dice()
    roll2, dice2 = roll_dice()

    print(f"Dice 1: You rolled a {roll1}!n{dice1}nnDice 2: You rolled a {roll2}!n{dice2}")

play_game()

Output:

Dice 1: You rolled a 3!
[0    ]
[  0  ]
[    0]

Dice 2: You rolled a 2!
[0    ]
[     ]
[    0]
Answered By: jrlouis

Fun question. You can leverage symmetry:

def animate_dice(r: int) -> str:
    c='|'+'o '[r<1]+' '+'o '[r<3]+'|n|'+'o '[r<5]
    print(c+'o '[r&1]+c[::-1])

NB: starts at 0:

>>> animate_dice(dice1 - 1)
|o o|
| o |
|o o|
Answered By: M.G.Poirot
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.