Dice throwing simulator - python

I am making a dice throwing simulator that generates N rolls for me, but assigns a name to each roll, for example:
[5,7,8]
then print
Player 1: 5
Player 2: 7
Player 3: 8
this is my code:
import random
players = int(input("Number of players:"))
throw_i = [random.randint(1, (30 * 1)) for _ in range(players)]
print(throw_i)
#Print results
for i in range (1, players+1):
print('Player', i,':', throw_i[0]+1)
An example output of my code is:
[22, 13, 18, 13]
Player 1 : 23
Player 2: 23
Player 3 : 23
Player 4 : 23
It does not work!

The last two lines are the problem.
for i in range (1, players+1):
print('Player', i,':', throw_i[0]+1)
This reads:
For every number between 1 and (players+1), print out some text followed by the first throw, plus one
That throw_i[0] always refers to the very first number generated. Maybe you mean to do throw_i[i], which will be off-by-one since lists start with zero and you're starting with 1, so throw_i[i-1]?

Replace
print('Player', i,':', throw_i[0]+1)
with
print('Player', i,':', throw_i[i-1])

You are using 30 as max range of randint but a dice has 6.
import random
players = int(input("Number of players:"))
throw_i = [random.randint(1, 6) for _ in range(players)] # As far as i know a dice has numbers from 1 to 6.
print(throw_i)
#Print results
for i in range (0, players):
print('Player', i+1,':', throw_i[i])
Input: Number of players:4
Output:
[4, 5, 6, 4]
Player 1 : 4
Player 2 : 5
Player 3 : 6
Player 4 : 4
EDIT: As pointed out by #Adam that die can be of other sides as well. Then you should just change:
for i in range (0, players):
print('Player', i+1,':', throw_i[i])

Related

While loop doesn't work/loops forever | Beginner question [duplicate]

This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 1 year ago.
Below is my attempted solution to this problem: The top prize in a lottery is won by matching three numbers between 1 and 30 to three random numbers drawn in the same order. When a ball is drawn it is put back into the machine before another ball is drawn. There are always 30 balls in the machine before a ball is drawn and a player may choose the same ball more than once. A draw takes place once a week. Write a function that takes three numbers as parameters, draws three random numbers between 1 and 30 and returns the number of weeks it took to win the jackpot. (E.g. Numbers chosen: 17, 12, 25 must match: ball one is 17, ball two is 12, ball three is 25.)
My attempt:
import random
chosen = []
for i in range(0, 3, 1):
chosen.append(input("Please input your lucky number: "))
drawn_numbers = []
count = 0
week_count = 0
print("Your chosen numbers are: {}, {}, {}".format(chosen[0], chosen[1], chosen[2]))
while count != 3:
for i in range(0, 3, 1):
random_number = random.randint(1, 30)
drawn_numbers.append(random_number)
for i in range(0, 3, 1):
if drawn_numbers[i] in chosen:
count += 1
week_count += 1
drawn_numbers = []
print("It took you {} weeks to win.".format(week_count))
For some reason the while loop just ignores the count += 1 part and loops randomly generated drawn_numbers lists forever.
Obviously there is something wrong with my loop, but I can't see it D:
Some advice on how to make that loop work would be nice. Thanks.
First of all - welcome to the world of Python!
You have several mistakes:
The input function returns a string and not an int. Meaning, the comparison you try to do implicitly in if drawn_numbers[i] in chosen would never be true, thus count is always 0 and you got yourself an infinite loop.
Assuming that you've fixed the mistake above, you still have a chance of count never hitting 3 at the evaluation of the loop. Consider the following scenario:
A user enters the numbers [1, 2, 3]
The drawn_numbers are [1, 2, 4]
Thus, count will be now 2
The while condition is count != 3 is True and thus the loop continues.
The numbers are drawn again are [1, 2, 4]
The count will be now 4
From now on, count can only increase and will never be equal to 3!
Do you see where this is going? Try to reset the count at the start of loop (inside)!
a lottery is won by matching three numbers ... in the same order
But the comparison you've implemented only looks for existence in the list instead of comparing element by element.
So, a working (not written in the most Pythonic way) version will be:
import random
chosen = []
for i in range(0, 3, 1):
chosen.append(int(input("Please input your lucky number: "))) # notice the int cast
drawn_numbers = []
count = 0
week_count = 0
print("Your chosen numbers are: {}, {}, {}".format(chosen[0], chosen[1], chosen[2]))
while count != 3:
count = 0 # notice that count is reset here
for i in range(0, 3, 1):
random_number = random.randint(1, 30)
drawn_numbers.append(random_number)
for i in range(0, 3, 1):
if drawn_numbers[i] == chosen[i]: # notice that we compare the elements in the same location
count += 1
week_count += 1
drawn_numbers = []
print("It took you {} weeks to win.".format(week_count))
If you're interested, here is a more Pythonic way:
import random
chosen = [int(input("Please input your lucky number: ")) for _ in range(3)]
print(f'Your chosen numbers are: {chosen}')
matched = False
week_count = 0
while not matched:
drawn_numbers = [random.randint(1, 30) for _ in range(3)]
matched = drawn_numbers == chosen
week_count += 1
print(f"It took you {week_count} weeks to win.")
In which you might find several features that might be new to you but I strongly encourage you to master them:
List comprehension
range(3) is equivalent to range(0, 3, 1)
Formatting string literals
The == operator actually compares two lists element by element!
Funny side note: Running this code without the order restriction results in much less weeks to wait to win the lottery :)
Have you checked your if-statement ever becomes true?
One thought is, that chosen might includes string-values as numbers. Try running:
print(type(chosen[0]))
This should be a int. Fix it by:
chosen.append(int(input("Please input your lucky number: ")))

ahtzee Upper Section Scoring

Description
The game of Yahtzee is played by rolling five 6-sided dice, and scoring the results in a number of ways. You are given a Yahtzee dice roll, represented as a sorted list of 5 integers, each of which is between 1 and 6 inclusive. Your task is to find the maximum possible score for this roll in the upper section of the Yahtzee score card. Here's what that means.
For the purpose of this challenge, the upper section of Yahtzee gives you six possible ways to score a roll. 1 times the number of 1's in the roll, 2 times the number of 2's, 3 times the number of 3's, and so on up to 6 times the number of 6's. For instance, consider the roll [2, 3, 5, 5, 6]. If you scored this as 1's, the score would be 0, since there are no 1's in the roll. If you scored it as 2's, the score would be 2, since there's one 2 in the roll. Scoring the roll in each of the six ways gives you the six possible scores:
0 2 3 0 10 6
it has been 3 days i am trying to program it right, but i have a problem in the elif len() == 1, when there is for example [1,1,2,6,4] it prints out 6 while it has to print 2 (bcs 1 is repeated twice)
import random
dice1 = random.randint(1,6)
dice2 = random.randint(1,6)
dice3 = random.randint(1,6)
dice4 = random.randint(1,6)
dice5 = random.randint(1,6)
result = [dice1,dice2,dice3,dice4,dice5]
one_rep = result.count(1)
two_rep = result.count(2)
three_rep = result.count(3)
four_rep = result.count(4)
five_rep = result.count(5)
six_rep = result.count(6)
reps = [one_rep,two_rep,three_rep,four_rep,five_rep,six_rep]
repsnum = [one_rep*1,two_rep*2,three_rep*3,four_rep*4,five_rep*5,six_rep*6]
repeated= []
test = [1]
def yahtzee():
for x in reps:
if x > 1:
repeated.append(x*(reps.index(x)+1))
s = repeated[0]
if reps.count(1) == 5:
score = max(result)
elif len(repeated) == len(test):
score = s
else:
score = max(repsnum)
return f'Your result is {dice1},{dice2},{dice3},{dice4},{dice5}\nYour score is {score}'
yahtzee()
print(yahtzee())
i have found the solution and here is the code:
import random
def yahtzee(result = [random.randint(1,6),random.randint(1,6),random.randint(1,6),random.randint(1,6),random.randint(1,6)]):
reps = [result.count(1),result.count(2),result.count(3),result.count(4),result.count(5),result.count(6)]
repsnum = [result.count(1)*1,result.count(2)*2,result.count(3)*3,result.count(4)*4,result.count(5)*5,result.count(6)*6]
repeated= []
for x in reps:
if x > 1:
repeated.append(x)
if reps.count(1) == 5:
score = max(result)
elif len(repeated) == 1:
score = repeated[0]*(reps.index(repeated[0])+1)
else:
score = max(repsnum)
return f'Your result is {result[0]},{result[1]},{result[2]},{result[3]},{result[4]}\nYour score is {score}'
print(yahtzee())

Counting/random int in while loop

I want this while loop to change numbers with every iteration (both the count and random int.) but when I run the program, the loop just goes on with the same numbers on the count and random int.:
# if 4 sides
die1 = random.randint(1,4)
die2 = random.randint(1,4)
count = 1
while sides == 4 and die1 != die2:
print (count, ". die number 1 is", die1, "and die number 2 is", die2,".")
count == count + 1
print ("You got snake eyes! Finally! On try number", count,".")
Each time you call random.randint(1,4), you are creating a single random number. It does not magically change to a new random number whenever you print it.
Generate new random numbers with random.randint(1, 4) inside your while loop.
The second problem is that count == count + 1 checks for equality (and returns False in your case). To do an assignment, use the assignment operator = or count += 1 to increment count by one.
If you want a generator that endlessly spits out random numbers, write one:
>>> import random
>>> def rng(i, j):
... while True:
... yield random.randint(i, j)
...
>>> random_gen = rng(1, 4)
>>> next(random_gen)
2
>>> next(random_gen)
3
>>> next(random_gen)
2
>>> next(random_gen)
2
>>> next(random_gen)
1
You need to do the random calls also inside the while loop otherwise they will not change. And the other thing is that you compare == and not set = the counter:
import random
sides = 4
count = 1
die1 = random.randint(1,4)
die2 = random.randint(1,4)
while sides == 4 and die1 != die2:
print (count, ". die number 1 is", die1, "and die number 2 is", die2,".")
count += 1
die1 = random.randint(1,4)
die2 = random.randint(1,4)
print ("You got snake eyes! Finally! On try number", count,".")
Trying a test run gives me:
1 . die number 1 is 4 and die number 2 is 3 .
2 . die number 1 is 2 and die number 2 is 1 .
3 . die number 1 is 1 and die number 2 is 2 .
4 . die number 1 is 3 and die number 2 is 4 .
5 . die number 1 is 1 and die number 2 is 4 .
You got snake eyes! Finally! On try number 6 .
One alternative that is almost identical but uses break instead of conditions on the while loop would be:
import random
sides = 4
count = 1
def tossdie():
"""Function to create a random integer for a die"""
return random.randint(1,4)
while True:
die1 = tossdie()
die2 = tossdie()
print (count, ". die number 1 is", die1, "and die number 2 is", die2,".")
if die1 == die2:
break
count += 1
print ("You got snake eyes! Finally! On try number", count,".")
Not sure why you needed the sides variable, so I left it out.
You want to roll the die in every loop, which means you have to re-assign die1 and die2 to a random number in each loop.
import random
# Initial parameters
die1 = random.randint(1,4)
die2 = random.randint(1,4)
count = 1
# Loop and roll die each time
while die1 != die2:
print(count, ". die number 1 is", die1, "and die number 2 is", die2,".")
die1 = random.randint(1,4)
die2 = random.randint(1,4)
count += 1
# Print on which die roll you got two equal die numbers rolled
print ("You got snake eyes! Finally! On try number", count,".")
You can use a for loop with iter to spit out pairs of random numbers , enumerate will do the counting, for snake-eyes you should also be checking that both are 1's not a random matching pair:
from random import randint
def repeating_rand(i, j):
for count, (r1, r2 ) in enumerate(iter(lambda: (randint(i, j), randint(i, j)), None), 1):
if r1 == 1 and r2 == 1:
return "You got snake eyes! Finally! On try number {}.".format(count)
print("Try no. {}, die number 1 is {} and die number 2 is {}".format(count, r1, r2))
Output:
In [12]: repeating_rand(1, 4)
Try no. 1, die number 1 is 1 and die number 2 is 2
Try no. 2, die number 1 is 4 and die number 2 is 1
Try no. 3, die number 1 is 1 and die number 2 is 2
Try no. 4, die number 1 is 1 and die number 2 is 3
Try no. 5, die number 1 is 1 and die number 2 is 3
Try no. 6, die number 1 is 3 and die number 2 is 4
Try no. 7, die number 1 is 4 and die number 2 is 2
Try no. 8, die number 1 is 1 and die number 2 is 2
Try no. 9, die number 1 is 3 and die number 2 is 2
Try no. 10, die number 1 is 4 and die number 2 is 3
Try no. 11, die number 1 is 1 and die number 2 is 3
Try no. 12, die number 1 is 3 and die number 2 is 4
Out[12]: 'You got snake eyes! Finally! On try number 13.'

Trouble correctly adding numbers in a python program

I am trying to simulate dice being rolled. Die_1 + Die_2 five times. The program runs, but the math is wrong. I have tried this multiple ways, but cannot get the math correct. The die are only being rolled one at a time, so a 1 and a six are possibilities. It must be an overly tired oversight. Any ideas would be fantastic. Code and output below. Thank you to anyone who can help.
# This program will simulate dice rolls 5 different
# times and add the total of each roll.
import random
import math
MIN = 1
MAX = 6
ROLLS = 5
def main():
for count in range(ROLLS):
die_1 = (random.randint(MIN, MAX))
die_2 = (random.randint(MIN, MAX))
combined_roll = point(die_1, die_2)
print('Here are the combined rolls for the dice!')
print(random.randint(MIN, MAX))
print(random.randint(MIN, MAX))
print('The combined roll is:', combined_roll)
def point(die_1, die_2):
roll_1 = die_1 + die_2
combined_roll = roll_1
return combined_roll
main()
Here are the combined rolls for the dice!
4
3
The combined roll is: 4
Here are the combined rolls for the dice!
2
2
The combined roll is: 7
Here are the combined rolls for the dice!
5
4
The combined roll is: 5
Here are the combined rolls for the dice!
3
5
The combined roll is: 9
Here are the combined rolls for the dice!
3
1
The combined roll is: 11
The math and everything is correct. It is indeed a symptom of being tired.
You're printing out entirely new numbers in these 2 lines:
print(random.randint(MIN, MAX))
print(random.randint(MIN, MAX))
Compared to what your die rolls actually were, earlier in time.
die_1 = (random.randint(MIN, MAX))
die_2 = (random.randint(MIN, MAX))
Time has passed so your random number generation is going to be in a different state.
So change the prints to:
print(die_1)
print(die_2)
This is best achieved with a simple function and random.randint:
>>> from random import randint
>>> def roll_dice(n=1):
... return [randint(1, 6) for _ in range(n)]
...
1-die roll:
>>> roll_dice()
[2]
>>> roll_dice()
[2]
>>> roll_dice()
[5]
2-die roll:
>>> roll_dice(2)
[6, 2]
>>> roll_dice(2)
[6, 2]
>>> roll_dice(2)
[5, 5]
>>>
You can easily sum a 2-die roll by:
>>> sum(roll_dice(2))
6
>>> sum(roll_dice(2))
7
>>> sum(roll_dice(2))
8
The second set if print statements mean to print die_1 and die_2, nit calls to random again. If you call random again, you get new random numbers.

Python dice rolling simulation

I'm having trouble with a code where I need to roll a six-sided die 1000 times and then return a list of how many times each number on the die was rolled.
The code runs just fine and I can get a list at the end, but my list keeps having 0 in place of four so it appears that my function is not keeping tabs on the number 4 being rolled or it's not being rolled at all.
I'm kind of stumped and I thought maybe someone here could help. Any and all help is appreciated.
Here's my code.
def rollDie(number):
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
for i in range(0, number):
roll=int(random.randint(1,6))
if roll == 1:
one = one+1
elif roll == 2:
two = two+1
elif roll == 3:
three = three+1
elif roll == 4:
four == four+1
elif roll == 5:
five = five+1
elif roll == 6:
six = six+1
return [one,two,three,four,five,six]
You have a small typo; you are testing for equality, not assigning:
four == four+1
should be:
four = four+1
However, you already have a number between 1 and 6, why not make that into an index into the results list? That way you don't have to use so many if statements. Keep your data out of your variable names:
def rollDie(number):
counts = [0] * 6
for i in range(number):
roll = random.randint(1,6)
counts[roll - 1] += 1
return counts
I can't improve on Martijn Pieters's answer. :-) But this problem can be more conveniently solved using a list.
import random
def rollDie(number):
# create a list with 7 values; we will only use the top six
rolls = [0, 0, 0, 0, 0, 0, 0]
for i in range(0, number):
roll=int(random.randint(1,6))
rolls[roll] += 1
return rolls
if __name__ == "__main__":
result = rollDie(1000)
print(result[1:]) # print only the indices from 1 to 6
And, this is a little bit tricky, but here is a better way to create a list of 7 entries all set to zero:
rolls = [0] * 7
Why count the zeros yourself? It's easier to just make Python do the work for you. :-)
EDIT: The list is length 7 because we want to use indices 1 through 6. There is also a position 0 in the list, but we don't use it.
Another way to do it is to map the dice rolls onto indices. It's a pretty simple mapping: just subtract 1. So, a die roll of 1 would go into index 0 of the list, a die roll of 2 would go into index 1, and so on. Now we will use every position in the list.
Here's that version:
import random
def rollDie(number):
rolls = [0] * 6
for i in range(0, number):
roll=int(random.randint(1,6))
rolls[roll - 1] += 1
return rolls
if __name__ == "__main__":
result = rollDie(1000)
print(result)
You should do random.randint(1, 7), otherwise you will never get a 6.
...
roll = random.randint(1, 7)
import random
def dice():
print random.randint(1,6)
dice()

Categories