How can I get repeating functions of a script and variable changes - python

I need to make a game based on the 'drinking' game Ship, Captain, Crew. The game consists of rolling 5 dies, and if the numbers are equal to 6,5,4 (in that order), you win. 6 is the Ship, 5 is the Captain and 4 is the crew. I wrote basic script but I'm still having issues. I have an issue where when I execute the script, the rolls never stop as I'm having issues telling the "roll = random.randint(1,6)" to only run 5 times then stop. Also, 'Dice' Is trying to define the number of rolls. So for example: after the dice has been rolled 5 times, Dice would = 5. I need help making it so that the script recognises that the dice must be rolled 5 times, and when it is, if the numbers rolled were not 6,5 and 4, end the game. Can anyone help?
Code:
import random
Dice = 0
SHIP_CAPTAIN_CREW = 6, 5, 4
SHIP = 6
CAPTAIN = 5
CREW = 4
WINNING_SCORE = 6, 5, 4
while Dice != WINNING_SCORE:
roll = random.randint(1,6)
print ("You Rolled A", roll)
if roll == SHIP:
print("You found the ship!")
if roll == CAPTAIN:
print("You found the Captain")
if roll == CREW:
print("You found the Crew!")
if roll == SHIP:
score = +1
roll
else:
Dice = roll
if roll == CAPTAIN :
score = +1
roll
else:
Dice += roll
if Dice == 5:
break
print ("Dice:", roll)

Since you want to run it a set number of times, a for loop with a range would be better.
Additionally, the code you have now doesn't check to make sure the numbers are rolled in the correct order.
import random
needed_value = 6; #the next roll you need
for x in range(5) :
roll = random.randint(1,6)
print ("You Rolled A", roll)
if roll == 6:
print("You found the ship!")
if(needed_value == 6):
needed_value = 5 #update the next needed number
if roll == 5:
print("You found the Captain")
if(needed_value == 5):
needed_value = 4 #update the next needed number
if roll == 4:
print("You found the Crew!")
if(needed_value == 4):
print ("Win!") #all three were found in order
break #the game has been won so no need to continue with loop

If I understood your game and your expectation well, this might be the answer.
import random
def drinking():
names = ['crew', 'captain', 'ship']
winning_order = '654'
score = ''
for _ in range(5):
dice = random.randint(1, 6)
print(f"You Rolled A {dice}")
if 4 <= dice <= 6:
print(f'You found the {names[dice - 4]}')
score += str(dice)
elif score == winning_order:
return f'Dice:, {dice}' # You won the game would be ideal
return 'You lose the game'
print(drinking())
You Rolled A 6
You found the ship
You Rolled A 6
You found the ship
You Rolled A 5
You found the captain
You Rolled A 1
You Rolled A 3
You lose the game

I made some heavy modifications to your code. I was hoping to keep it easy to understand, while still doing everything you're expecting, and also making it easy to modify.
import random
# I put the logic inside a function so you can call it
# DiceRound() will return 0 on wins, and -1 on losses
def DiceRound():
SHIP = 6
CAPTAIN = 5
CREW = 4
Counter = 0 # keeps track of how many rolls we've made
WINNING_SCORE = 0 # modified to keep track of win-condition
dierolls = "" # used for output
while WINNING_SCORE != 3 and Counter < 5:
v = 0 # verbate
roll = random.randint(1,6)
Counter = Counter +1
dierolls = dierolls + "[%d] "%roll
# Any time we roll 6, we're 1-roll towards victory
if roll == SHIP:
WINNING_SCORE = 1
# If we roll a 5 when we've already rolled a 6
if roll == CAPTAIN and WINNING_SCORE == 1:
WINNING_SCORE = 2
# Elsewise if we just rolled a 5
elif roll == CAPTAIN and WINNING_SCORE != 1:
WINNING_SCORE = 0
# If we roll a 4 when we've already rolled a 6 and a 5
if roll == CREW and WINNING_SCORE == 2:
WINNING_SCORE = 3
print(dierolls)
print("... Round won!", end="")
return(0) # return; exits loop and returns 0 for Win-condition
# Elsewise if we just rolled a 4
elif roll == CREW and WINNING_SCORE != 2:
WINNING_SCORE = 0
# If we rolled below a 4, anytime
if roll < 4:
WINNING_SCORE = 0
# If we rolled all five times without winning
print(dierolls)
print("... Round lost.", end="")
return(-1) # return; exits loop and returns -1 for Lose-condition
Output from this script will look somewhat like this if you call DiceRound() until the return == 0:
[1] [6] [1] [5] [5] ... Round lost.
[3] [6] [4] [5] [3] ... Round lost.
[4] [2] [5] [4] [4] ... Round lost.
[2] [2] [6] [5] [4] ... Round won!

Related

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())

Python Dice Rolling game - How to check separate rolls and add total

Hi guys I am in the midst of creating a dice in game in python. Below is my working code. So far if a player were to roll the dice one time, I can easily check if the rolled number is 1, however how can I make it so that if I want to roll lets say 10 times, I want to be able to check if any of those 10 rolls, any of them equaled 1, and then stop it, if none equaled 1, I would add them all up.
Basically How do I check the result of each seperate roll, and adding them up if a 1 is not rolled.
import random
import sys
def rollingdice(roll): #define function
total = 0 #starting count
for i in range(roll):
total+= random.randint(1, 6)
if total == 1:
print("You rolled a 1: You have zero points for the round")
else:
print(total)
main()
def main():
roll=int(input("Player 1: How many times will you roll "))
rollingdice(roll)
main()
Just add a variable to hold the rolled number and check if it is 1, then break out of the loop if it is
def rollingdice(roll): #define function
total = 0 #starting count
for i in range(roll):
rolled = random.randint(1, 6)
if rolled == 1:
print("You rolled a 1: You have zero points for the round")
break
total += rolled
if rolled != 1: print(total)
main()
Another approach:
from itertools import takewhile
import random
def rollingdice(roll):
rolls = (random.randint(1, 6) for i in range(roll))
rolls = list(takewhile(lambda n: n != 1, rolls))
if len(rolls) == roll:
print(total)
else:
print("You rolled a 1: You have zero points for the round")

Ending a while loop

I'm currently writing code for a dice game in Python 3.6 I understand my coding is a little off in this, however, I'm really just wondering how to start my while loop. The instructions of the game are as follows...
A human player plays against the computer.
Player 1 rolls until they either win, decide to hold, or roll a 1.Same for player 2.
They take turns rolling two dice, and the totals of the dice are added together Unless a 1 is rolled.
If a one 1 is rolled, you get no score added and it's the next person's turn. If two 1's are rolled, you lose all of your points and its the next person's turn.
The first player to 100 score, wins the game.
My game works fine until Player 1 and Player 2 both hit "y" to hold back to back. Then the game quits switching between player's until "n" to not hold is hit again. Any idea why?
I was told I need variables to decide who's turn it is but I'm not sure how to incorporate them into my code.
Any help would be appreciated.
import random
def main():
print("Welcome to the Two Dice Pig Game. You are Player 1!")
Player1 = 0
Player2 = 0
while(Player1<100 and Player2<100):
p1dice=random.randrange(1,7)
p1dice2=random.randrange(1,7)
Player1+=p1dice+p1dice2
print("Player 1 dice 1 =",p1dice)
print("Player 1 dice 2 =",p1dice2)
print("Player 1 dice total =",Player1)
print("Does player 1 want to hold?")
choose1 = input("Enter y for yes or n for no.")
if(choose1=="n"):
p1dice=random.randrange(1,7)
p1dice2=random.randrange(1,7)
Player1+=p1dice+p1dice2
print("Player 1 dice 1 =",p1dice)
print("Player 1 dice 2 =",p1dice2)
print("Player 1 dice total =",Player1)
if(Player1>=100):
print("Player 1 wins!")
else:
print("Does player 1 want to hold?")
choose1 = input("Enter y for yes or n for no.")
while(choose1=="y"):
print("It's player 2's turn.")
p2dice=random.randrange(1,7)
p2dice2=random.randrange(1,7)
Player2+=p2dice+p2dice2
print("Player 2 dice 2 =",p2dice)
print("Player 2 dice 2 =",p2dice2)
print("Player 2 dice total =",Player2)
print("Does player 2 want to hold?")
choose2 = input("Enter y for yes or n for no.")
while(choose2=="n"):
p2dice=random.randrange(1,7)
p2dice2=random.randrange(1,7)
Player2+=p2dice+p2dice2
print("Player 2 dice 2 =",p2dice)
print("Player 2 dice 2 =",p2dice2)
print("Player 2 dice total =",Player2)
print("Does player 2 want to hold?")
choose2 = input("Enter y for yes or n for no.")
while(choose2=="y"):
print("It's player 1's turn.")
p1dice=random.randrange(1,7)
p1dice2=random.randrange(1,7)
Player1+=p1dice+p1dice2
print("Player 1 dice 2 =",p1dice)
print("Player 1 dice 2 =",p1dice2)
print("Player 1 dice total =",Player1)
print("Does player 1 want to hold?")
choose2 = input("Enter y for yes or n for no.")
main()
Use a dict to keep a score per player name, switch a turn that holds the player currently throwing dice.
Implemented some logic as when to change turn from one to the other:
import random
def score(players):
for k in players:
print("{} has {} points".format(k,players[k]))
def hold(player):
if input("Does {} want to hold? [y or anything]".format(player)).lower().strip() == "y":
return "y"
return "n"
def main():
dice = range(1,7)
players = {"p1":0, "p2":0}
turn = ""
change_player = "y"
print("Welcome to the Two Dice Pig Game. You are Player 1!")
while all(x < 100 for x in players.values()):
# initially changePlayer is
if change_player == "y":
# print both scores on player changed
score(players)
turn = "p1" if turn != "p1" else "p2"
dice1, dice2 = random.choices(dice,k=2)
print("{} threw {} and {} for a total of {}".format(turn,d1,d2,d1+d2))
if dice1 + dice2 == 2:
players[turn] = 0
print("Two 1 - you're done for now. Your points go back to 0.")
change_player = "y"
elif dice1 == 1 or dice2 == 1:
print("One 1 - you're done for now.")
change_player = "y"
else:
# only case where we need to add values and print new score
players[turn] += dice1 + dice2
print("Your score: {}".format(players[turn]))
if turn == "p1":
change_player = hold(turn)
else:
change_player = "n" # computer is greedy, never stops
winner, points = max(players.items(),key=lambda x: x[1])
print("The winner is {} with {} points.".format(winner,points))
main()
Output:
Welcome to the Two Dice Pig Game. You are Player 1!
p1 has 0 points
p2 has 0 points
p1 threw 5 and 1 for a total of 6
One 1 - you're done for now.
p1 has 0 points
p2 has 0 points
p2 threw 3 and 6 for a total of 9
Your score: 9
p2 threw 6 and 2 for a total of 8
Your score: 17
p2 threw 4 and 1 for a total of 5
One 1 - you're done for now.
p1 has 0 points
p2 has 17 points
p1 threw 4 and 5 for a total of 9
Your score: 9
Does p1 want to hold? [y or anything]
p1 threw 2 and 6 for a total of 8
Your score: 17
Does p1 want to hold? [y or anything]
p1 threw 4 and 6 for a total of 10
Your score: 27
[snipp]
One 1 - you're done for now.
p1 has 91 points
p2 has 51 points
p1 threw 6 and 4 for a total of 10
Your score: 101
Does p1 want to hold? [y or anything]
The winner is p1 with 101 points.
You would want to simplify your code by doing something like this:
# Keep track of whose turn it is
player = 1
# Keep a dictionary of scores for each player (1 or 2)
scores = {1: 0, 2: 0}
choice = 'n'
# While neither player has > 100
while max(d.values()) < 100:
# Roll until current player decides to keep roll
while choice == 'n':
print('Player', player, 'turn')
roll = random.randrange(1,7) + random.randrange(1,7)
print('You rolled', roll)
choice = input('Keep roll? y/n')
# Increment that player's score
scores[player] += roll
choice = 'n'
# Change to other player
player = (player % 2) + 1
Because once you've set a choice for choose1, it never gets set again. The quick way to fix this would be to add an input after the two while loops for choose2, although you may want to look into making your code neater through making functions for the common logic
while(choose2=="y"):
....
choose1 = input("Enter y for yes or n for no.")

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.'

While loop won't stop in python

We are trying to make a python program to simulate games of craps and display the probability of winning. I have narrowed down the answer to the while loop and as the title suggests, when it hits the loop it won't exit. As far as I can tell the loop should exit but instead just returns and endless train of "false". Here is the code for the whole program with comments, I'll type out the rules for craps (as far as what we're using for our program) at the bottom.
import random
def craps()
roll = random.randint(1,6) + random.randint(1,6)
if (roll == 7 or roll == 11): #Tests if the player should win. If so it adds a 1 to the win counter
return 1
elif (roll == 2 or roll == 3 or roll == 12): #Tests if player should lose. If so adds 0
return 0
else:
roll2 = 0 #initializes roll2 for the while
while (roll2 != roll or roll2 != 7): #The player keeps rolling until they get a 7 or the initial roll
roll2 == random.randint(1,6) + random.randint(1,6) #Rolls the dice
if (roll2 == roll): #Tests if the player should win
return 1
elif (roll2 == 7): #Tests if the player should lose
return 0
win = 0 #Start the win counter at 0
games = int(input("Enter the amount of games you want played: ")) #Accept how many games will be played
for i in range (games):
win = win + craps() #adds a 1 or a 0 depending on if a game was won
print ("The probability of winning is:", win, "/", games, " =", float(win)/games) #print the probability of winning
The basic rules we are using are: the player rolls 2 six sided dice, if the initial roll is a 7 or 11 the player wins (line 4). If the player rolls a 2, 3 or a 12 the player loses (line 6) If the player doesn't get either they keep rolling until they match the initial roll or roll a 7. If they match the initial roll they win, if they get a 7 they lose (lines 10-15). Our program is supposed to simulate and display the probability of the player winning.
This is my first time using this site so let me know if I screwed up on anything for the future. And thanks for helping!
A common, but very frustrating and time-wasting typo, which can get even the best Python developers. Replace roll2 == random.randint(1,6) + random.randint(1,6) with roll2 = random.randint(1,6) + random.randint(1,6).
Also, I think you need roll2 != roll and roll2 != 7. From a stylistic point of view, it's better to omit the parenthesis around the statement evaluated in an if or while line.
Your loop has a slight amount of redundancy in it though. You check for roll2 being roll or 7 at the top of each loop and at the end of each loop. You could also consider trying this:
while True:
# do everything in the same way as before
or
while roll2 != roll and roll2 != 7:
# do stuff with the roll
roll = random.randint(1,6) + random.randint(1,6)
return 1 if roll2 == roll else return 0 # a "ternary operator" in Python
A double equals sign tests for equality. Change it to single for your code to work. Here is your edited code:
import random
def craps()
roll = random.randint(1,6) + random.randint(1,6)
if (roll == 7 or roll == 11): #Tests if the player should win. If so it adds a 1 to the win counter
return 1
elif (roll == 2 or roll == 3 or roll == 12): #Tests if player should lose. If so adds 0
return 0
else:
roll2 = 0 #initializes roll2 for the while
while (roll2 != roll or roll2 != 7): #The player keeps rolling until they get a 7 or the initial roll
roll2 = random.randint(1,6) + random.randint(1,6) #Rolls the dice
if (roll2 == roll): #Tests if the player should win
return 1
elif (roll2 == 7): #Tests if the player should lose
return 0
win = 0 #Start the win counter at 0
games = int(input("Enter the amount of games you want played: ")) #Accept how many games will be played
for i in range (games):
win = win + craps() #adds a 1 or a 0 depending on if a game was won
print ("The probability of winning is:", win, "/", games, " =", float(win)/games) #print the probability of winning
Here is an example:
>>> import time
>>> x = 7
>>> x == 7
True
>>> while x != 6:
... x == 6
... time.sleep(1)
...
False
False
False
^CTraceback (most recent call last):
File "<stdin>", line 3, in <module>
KeyboardInterrupt
>>> while x != 6:
... x = 6
... time.sleep(1)
...
>>>
Your first issue is with this line:
while (roll2 != roll or roll2 != 7): #The player keeps rolling until they get a 7 or the initial roll
This will be an infinite loop if roll is not equal to 7. You should have an and here instead, because you want to change if one of these is false, not if both are. Make sense?
You want:
while (roll2 != roll and roll2 != 7): #as long as both are not `True` then keep rolling.
Your other issue is with this line:
roll2 == random.randint(1,6) + random.randint(1,6)
The double equals checks to see if roll2 is equal to the expression on the left. What you want to do is set it equal to the expression on the left, like so:
roll2 = random.randint(1,6) + random.randint(1,6)

Categories