2

I am making a code where three dice are rolled and if all three dice are equal the values are added. If 2 of the dice are equal then the 2 equal dice values are added and the odd dice value is subtracted from the sum.

This is my code so far

import random

d1 = random.randint(1,6)
d2 = random.randint(1,6)
d3 = random.randint(1,6)

print(d1)
print(d2)
print(d3)

if d1 == d2 and d2 == d3:
    score = d1 + d2 + d3
elif d1 == d2 or d1 == d3 or d2 == d3:

Now I don't know how I would find out which of the 2 dice are equal to be able to add them together. How would I do this?

7
  • should anything happen if all the values are different? Commented Nov 17, 2017 at 18:35
  • Is there any distinction between the dice? Commented Nov 17, 2017 at 18:36
  • When all three are different then score = 0 @timgeb Commented Nov 17, 2017 at 18:37
  • All three dice are the same @MadPhysicist Commented Nov 17, 2017 at 18:38
  • What exactly do you mean by "previous sum". Do you mean another sum, or the one of the two numbers? Commented Nov 17, 2017 at 18:43

3 Answers 3

7

You can use a sequence of if-statements:

if d1 == d2:
    if d2 == d3:
        score = d1 + d2 + d3
    else:
        score = (d1 + d2) - d3
elif d2 == d3:
    score = (d2 + d3) - d1
elif d1 == d3:
    score = (d1 + d3) - d2
else:
    score = 0

The brackets aren't necessary, just make it a bit clearer

Sign up to request clarification or add additional context in comments.

2 Comments

You missed the case where d1 == d3 and d2 is different.
@leekaiinthesky Sorry about that!
3

I might use collections.Counter for this.

A Counter is a dict subclass that counts objects. In the resulting dictionary, the keys are the objects being counted while the values are the number of times those objects appear.

We can create a count of dice rolls by passing a list of the results of random.randint() to Counter's constructor, like so:

Counter(random.randint(1,6) for _ in range(3)) # 3 6-sided rolls

In addition to accessing the counts via dict's [] operator, we can also access them via Counter.most_common(), which returns a list containing all of the rolls and their associated counts.

In our program, rolls[0] is the most common roll and its count, rolls[0][0] is the value of the roll, rolls[0][1] is the number of times it was rolled. Similarly, rolls[1][0] is the second-most common value.

import random
from collections import Counter

rolls = Counter(random.randint(1,6) for _ in range(3)).most_common()

if len(rolls) == 1:
    score = rolls[0][0] * 3
elif len(rolls) == 2:
    score = rolls[0][0] * 2 - rolls[1][0]
else:
    score = 0

print (rolls, score)

You haven't specified what the correct score is when there are no matches. The above algorithm gives a score of 0 if there are no matches.

Here is another algorithm which scores the negative sum of all the dice if there are no matches. In essence, it adds up all of the matching dice and subtracts each singleton die. This gives the answer you request for each of the cases you describe but punishes non-matching rolls more severely. Notice how this version generalizes easily to different numbers of dice and different numbers of sides.

import random
from collections import Counter

rolls = Counter(random.randint(1, 6) for _ in range(3)).most_common()

score = sum(roll[0] * (-1 if roll[1]==1 else 1) * roll[1] for roll in rolls)

print(rolls, score)

3 Comments

Can you provide a little bit of additional clarification? Newbies (like myself) may get stuck in parts. I was able to follow along since I've used counters, but OP may be unfamiliar.
OP later clarified that the sum is indeed zero for no matches. Good guess.
For posterity: 2nd example can return 0 like so: if rolls[0][1] == 1: score = 0 / else: score=sum(...)
2

Using sets is probably the most elegant solution to determine if you have a repeat, but it does not tell you which element repeats.

You could maintain all your dice in a list:

d = [random.randint(1,6) for _ in range(3)]

You can sort the list. If all the elements are the same, the first and last value will match. If there is a repeat, the middle element will match either the first or the last one:

d.sort()
if d[0] == d[2]:
    score = sum(d)
elif d[0] == d[1]:
    score = d[0] + d[1] - d[2]
elif d[1] == d[2]:
    score = d[1] + d[2] - d[0]
else:
    score = 0

7 Comments

This will cause an error. Where is prev coming from? And how is it influencing the score?
@PauloAlmeida. prev is a placeholder for the "previous" sum OP is referring to in the question. I will fix as soon as OP has responded to my request for clarification.
@PauloAlmeida. Fixed
Ok, I see. I like your solution, because of the sort. It's similar to the accepted one but with less need for logic. I was wondering if it would be possible to come up with an elegant generic solution (for any number of dice), but that's a different question (and it would need additional conditions to decide what to sum and subtract).
@PauloAlmeida. This is probably the first step. The second step would be to determine what you want to do with matches. In either case, Rob's solution is infinitely more flexible that this one since it computes a proper histogram.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.