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)
Related
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!
I have this question for an assignment:
Your friend has devised a game with two players. The two players,
called A and B, take turns rolling an ordinary six-sided die, with A being
the first to roll.
The first player who rolls a six wins the game.
You and your friend do not agree about what the probability of A winning
the game is, and you therefore decide to simulate the game with a
computer.
Thus: write a Python program that performs 10 trials, each consisting of
10000 games, and for each trial prints the fraction of the games won by
player A.
This is the code I've gotten so far, it's just returning a number in and around 1667 every time. I'm mainly wondering how to differentiate between A or B winning the game.
Any help would be appreciated!
EDITED CODE
import random
def rollDie():
return random.choice([1,2,3,4,5,6])
def roll_first():
if random.choice([0,1]) == 0:
return 'A'
else:
return 'B'
def rollSim():
while True:
turn = roll_first()
numTrials = 10
numThrows = 10000
totalThrows = numTrials*numThrows
game_on = True
winsA = 0
winsB = 0
while game_on:
for n in range(numTrials):
games = 0
for i in range(numThrows):
throw = rollDie()
if turn == 'A':
if throw == 6:
winsA += 1
games += 1
break
else:
turn = 'B'
else:
if throw == 6:
winsB += 1
games += 1
break
else:
turn = 'A'
return winsA/totalThrows
The best way to achieve a clean code would be to separate in functions each one of the tasks in hand, meaning:
1. Run a play -> For each dice rolling
2. Run a game -> Alternation of plays between A and B, until the first one gets a 6 on the dice (here considering that if A gets a 6, B doesn't even need to play, as A won)
3. Run a trial -> Consisting of a specific number of plays
4. Run the main program -> Consisting of playing all the number of trials required
So, below, is one of the possible solutions (here you see that my play function already returns the result, meaning if the player won or not):
import random
def play():
won = True
keepPlaying = False
rollDice = random.choice([1,2,3,4,5,6])
if rollDice == 6:
return won
return keepPlaying
def run_game(winsA, winsB):
while True:
playA = play()
playB = play()
if playA:
winsA += 1
return winsA, winsB
elif playB:
winsB += 1
return winsA, winsB
def run_trial(numGames):
winsA = 0
winsB = 0
for i in range(numGames):
wins = run_game(winsA, winsB)
winsA = wins[0]
winsB = wins[1]
print("winsA:", winsA, "| winsB:", winsB, "| Fraction of A wins:", "{} %".format(winsA / ( winsA + winsB ) * 100))
numTrials = 10
numGames = 10000
for i in range(numTrials):
run_trial(numGames)
You really only need to count wins for player A. Since you play 10000 games per trial, if you know the number of games that A won, you know the other games must have been won by B, and A+B=10000.
You seem to decide randomly who has the first turn, but the task states that it should always be player A taking the first turn.
You can use a boolean isPlayerA to know whose turn it is. Start with isPlayerA = True and then toggle it with isPlayerA = not isPlayerA.
Here is how you could code it:
import random
def rollDie():
return random.choice([1,2,3,4,5,6])
def winFraction(): # Perform one trial of 10000 games and return fraction of wins for A
winsA = 0 # only count wins for A
for numTrow in range(10000):
isPlayerA = True # Player A always takes the first turn
throw = rollDie()
while throw != 6: # While the game is not over yet:
isPlayerA = not isPlayerA # Switch to the other player
throw = rollDie()
if isPlayerA:
winsA += 1 # Only count the wins for player A
return winsA/10000.0 # This is the fraction: we know the number of played games
def sim():
for trial in range(10): # Perform 10 trials
print(winFraction()) # Print the result of the trial
sim() # Start the simulation
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")
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.")
Roll a pair of 6-sided dice (a.k.a. D6) until they both come up '1'. Count the number of rolls this took.
Run 100 trials of this. Print out the result of each roll and report the average number of rolls required.
Use nested loops. The outer loop runs 100 trials; the inner loop continues rolling until 1-1 appears. Then update the running counts and go to the next trial.
import random
dice1, dice2 = " ", " "
roll = " "
for roll in range(1, 101):
roll = 0
dice1 = random.randint(1, 6)
dice2 = random.randint(1, 6)
print(dice1, ",", dice2)
while dice1 == 1 and dice2 == 1:
break
this doesn't stop when 2 1's a rolled and i need help accumulating the roll number and trial number
The problem is that your inner loop really doesn't do anything.
You have to give it the work you described: keep rolling two dice until they both come up 1. I'll outline the logic you described, but have trouble implementing. I'll leave the detailed work to you. :-)
roll_count = 1
while not (dice1 == 1 and dice2 == 1):
roll both dice
increment roll_count
running_total += roll_count
You also need to initialize running_total somewhere.
Does this get you unstuck?
import random
from itertools import count
for roll in range(1, 101):
for c in count(1):
dice1 = random.randint(1, 6)
dice2 = random.randint(1, 6)
print(c, ':', dice1, ",", dice2)
if dice1 == 1 and dice2 == 1:
break