apparently ran_num is not defined - python

So I've remade part of my dicegame's code and it's works somewhat decently, however after ROLL'ing the dice and attempting to display the users score, I run in to an error where is says 'name p1_score is not defined'. It says the same thing for the variable p2_score aswell. However I defined p1_score as ran_num+ran_num so I don't get why I'm getting an error.
import random
import time
player_1 = input("")
player_2 = input("")
def rollDice(player_1):
ran_num = random.randint(1,6)
if ran_num == 1:
print("You rolled a",ran_num)
else:
print("You rolled a",ran_num)
p1_score = ran_num+ran_num
def rollDice(player_2):
ran_num = random.randint(1,6)
if ran_num == 1:
print("You rolled a",ran_num)
else:
print("You rolled a",ran_num)
p2_score = ran_num+ran_num
print("Please press ENTER to roll the dice")
input()
rollDice(player_1)
print("Good job",player_1,)
print("Your score is now",p1_score)
time.sleep(5)
print(player_2,"Press ENTER to roll the dice")
input()
rollDice(player_2)
print("Nice work",player_2)
print("Your score is now",p2_score)
def main():
rollDice(player1, player2)
main()

This is a variable scoping issue, you either need to use a global (globals can be dangerous if used incorrectly) the same way you have with player_1 and player_2, OR return from that function and use the returned value for the output.
http://python-textbok.readthedocs.io/en/1.0/Variables_and_Scope.html
"Not affiliated with that website, just did a quick google to see if I could find a resource for you to read so you can understand"
import random
import time
def rollDice():
ran_num = random.randint(1,6)
print("You rolled a " + str(ran_num))
raw_input()
resolved_score = ran_num+ran_num
return str(resolved_score)
player_1 = raw_input("Enter player one name: ")
player_2 = raw_input("Enter player two name: ")
print("Please press ENTER to roll the dice")
raw_input()
p1_result = rollDice()
print("Good job "+player_1)
print("Your score is now "+p1_result)
time.sleep(5)
print(player_2+" Press ENTER to roll the dice")
raw_input()
p2_result = rollDice()
print("Nice work "+player_2)
print("Your score is now "+p2_result)
I've rationalised your code a bit, there were some logic errors. Notice in the def I have a return statement, the return statement adds two numbers together, converts it to a string using str() and I use RETURN to spit the value back out to the calling code. In this case the calling code is first encountered where we see:
p1_result = rollDice()
Now p1_result will equal whatever the ran_num+ran_num resolved to inside the function.

Related

getting Python 3.9 to recognize parameters and act accordingly (Interactive storytelling)

I'll try to keep it short and sweet.
I'm writing an interactive story that changes based on the "roll" of a d20 dice. I've managed to figure out getting started, but I've hit a point where I don't think Python is actually listening to the parameters I'm giving it, because it kind of just does whatever.
Essentially, here's what's supposed to happen:
Player agrees that they want to play the game -> Player Rolls dice -> Game uses the randomly rolled number to determine which start that the player will have.
What's currently happening is, all goes well until it's supposed to spit out the start that the player has. It doesn't seem to actually decide based on my parameters. For example, you're supposed to have the "human" start if the player rolls 5 or less, and an "elf" start for anything between 6 and 18. Here's what happened yesterday:
venv\Scripts\python.exe C:/Users/drago/PycharmProjects/D20/venv/main.py
Hello! Would you like to go on an adventure? y/n >> y
Great! Roll the dice.
Press R to roll the D20.
You rolled a 15!
You start as a human.
As a human, you don't have any special characteristics except your ability to learn.
The related code is below:
def NewGame():
inp = input("Hello! Would you like to go on an adventure? y/n >> ")
if inp == "y" or inp == "yes":
print("Great! Roll the dice.")
input("Press R to roll the D20.")
print("You rolled a " + str(RollD20()) + "!")
PostGen()
else:
input("Okay, bye! Press any key to exit.")
sys.exit()
def PostGen():
if RollD20() <= 5:
print("You start as a human.")
PostStartHum()
elif RollD20() >= 6:
print("You start as an elf.")
PostStartElf()
elif RollD20() >= 19:
print("You lucked out, and can start as a demigod!")
PostStartDemi()
def RollD20():
n = random.randint(1, 20)
return n
def PostStartHum():
print("As a human, you don't have any special characteristics except your ability to learn.")
def PostStartElf():
print("As an elf, you have a high intelligence and a deep respect for tradition.")
def PostStartDemi():
print("As a demigod, you are the hand of the gods themselves; raw power incarnated in a human form...")
print("However, even mighty decendants of gods have a weakness. Be careful."
Thanks for all your help.
Turn your PostGen function into the following:
def PostGen(rollValue):
if rollValue <= 5:
print("You start as a human.")
PostStartHum()
elif rollValue >= 6:
print("You start as an elf.")
PostStartElf()
elif rollValue >= 19:
print("You lucked out, and can start as a demigod!")
PostStartDemi()
Change your NewGame function to the following:
def NewGame():
inp = input("Hello! Would you like to go on an adventure? y/n >> ")
if inp == "y" or inp == "yes":
print("Great! Roll the dice.")
input("Press R to roll the D20.")
rollValue = RollD20()
print("You rolled a " + str(rollValue) + "!")
PostGen(rollValue)
else:
input("Okay, bye! Press any key to exit.")
sys.exit()
You are generating a new random number every time you call RollD20(). You need to store the value somewhere and reuse it for the game session.
Each time you call RollD20, you get a new random number. So if you want to use the same random number in multiple ifs, you need to tuck that value into another variable.
def NewGame():
inp = input("Hello! Would you like to go on an adventure? y/n >> ")
if inp == "y" or inp == "yes":
print("Great! Roll the dice.")
input("Press R to roll the D20.")
result = RollD20()
print("You rolled a " + str(result) + "!")
PostGen(result)
else:
input("Okay, bye! Press any key to exit.")
sys.exit()
And from there you change PostGen() to accept the result:
def PostGen(result):
if result <= 5:
print("You start as a human.")
PostStartHum()
elif result >= 6:
print("You start as an elf.")
PostStartElf()
elif result >= 19:
print("You lucked out, and can start as a demigod!")
PostStartDemi()

Restarting a function once condition returns True

Trying my hand at writing a very simple Game of Chance game on Codecademy while working through their Python course. I was doing ok (I think) for a while and the code returned what I expected it to, but now it feels I'm stuck and googling things frantically hasn't really helped me and I don't just want to look at the actual solution because where's the fun in that so here goes.
My thought process was the game should initially ask the player to input their guess and their bid, then run the code in game() and print the outcome. This was then to be locked in a while loop to check if the user wanted to continue playing or not and if the answer was "Yes" to restart the game() function again. This is where I am stuck as I just can't figure out what to put in line 26 after the "Yes" check returns True.
I guess the TL/DR version of my actual question is how do you (without giving the actual code away) call a function from within a while loop? Wondering if perhaps I'm simply headed in the wrong direction here and need to review while loops once more.
Thanks!
# Import stuff
import random
# Generate random number from 1 - 9
num = random.randint(1, 10)
# The actual game, asking user for input and returning the outcome
def game():
guess = int(input("Guess the number: "))
bid = int(input("Bet on the game: "))
money = 100
if guess == num:
money = (money + bid)
print("You Won")
print("You now have: " + str(money) +" money")
return money
else:
money = (money - bid)
print("You lost, you will die poor")
print("You now have: " + str(money) +" money")
return money
# Run game() while there's still money left in the pot
def structure():
while money > 0:
another_go = input("Would you like to play again? Yes or No: ")
if another_go == "Yes":
game() # This is where I'm stuck
elif another_go == "No":
print("Oh well, suit yourself")
break
else:
print("Pick Yes or No")
print(another_go)
game()
Ok so a few things to go through here.
First off, the concept of a local variable is coming into play here and is why your money variable is not communicating properly between your two functions. Each of your functions uses it's own money variable, which is completely independent of the other.
So this is the root of your current problem, where your money > 0 loop never actually runs. Secondly, although this might have just been done for troubleshooting, you don't actually call structure which is supposed to control game().
Lets try something like this where we keep money in the structure function and pass an update version to the game function as a parameter. Then, because you have game() returning money, you can just update the money value in your structure() call.
# Import stuff
import random
# Generate random number from 1 - 9
num = random.randint(1, 10)
# The actual game, asking user for input and returning the outcome
def game(money):
guess = int(input("Guess the number: "))
bid = int(input("Bet on the game: "))
if guess == num:
money = (money + bid)
print("You Won")
print("You now have: " + str(money) +" money")
return money
else:
money = (money - bid)
print("You lost, you will die poor")
print("You now have: " + str(money) +" money")
return money
# Run game() while there's still money left in the pot
def structure():
money = 100
money = game(money)
while money > 0:
another_go = input("Would you like to play again? Yes or No: ")
if another_go == "Yes":
money = game(money) # This is where I'm stuck
elif another_go == "No":
print("Oh well, suit yourself")
break
else:
print("Pick Yes or No")
print(another_go)
structure()
Notice because of how your while loop is written, in order to get game() to run the first time I had to call it before the while loop. Maybe as a challenge, see if you can be rewrite the structure of your loop so that you don't have to do this!
Welcome to SO. Your code is overall fine. Here's one way to slightly change your code to make it work:
... Most of the code ...
money = 10
def structure():
another_go = "Yes" # initialize to 'Yes', so we'll
# always have a first game.
while money > 0:
if another_go == "Yes":
game() # This is where I'm stuck
elif another_go == "No":
print("Oh well, suit yourself")
break
else:
print("Pick Yes or No")
print(another_go)
# move 'another go' to the end of the loop
another_go = input("Would you like to play again? Yes or No: ")
structure() # call this function to start
# make money a global parameter with a -ve value
money = -1
def game():
global money
guess = int(input("Guess the number: "))
bid = int(input("Bet on the game: "))
# Then, if money has default(game started for first time), update it
if(money < 0):
money = 100
.
.
.
.
while money > 0:
global money
another_go = input("Would you like to play again? Yes or No: ")
if another_go == "Yes":
game(money) # Pass remaining money to game()
.
.
.

Python - Loop Escaping unexpectedly and not iterating over list as expected

import random
import time
def closest_num(GuessesLog, CompNum):
return GuessesLog[min(range(len(GuessesLog)), key=lambda g: abs(GuessesLog[g] - CompNum))]
GameModeActive = True
while GameModeActive:
Guesses = None
GuessesLog = []
while not isinstance(Guesses, int):
try:
Guesses = int(input("How many guesses do you have?: "))
except ValueError:
print("Please enter a whole number")
print(" ")
CompNum = random.randint(1,99)
print(CompNum)
Players = None
while not isinstance(Players, int):
try:
Players = int(input("How many players are there?: "))
except ValueError:
print("Please enter a whole number")
print(" ")
NumberOfPlayers = []
for i in range(Players):
NumberOfPlayers.append(i+1)
NumberOfGuesses = []
for i in range(Guesses):
NumberOfGuesses.append(i+1)
print(NumberOfGuesses)
print(NumberOfPlayers)
print(len(NumberOfGuesses))
print(len(NumberOfPlayers))
for Guess in NumberOfGuesses:
if Guess != len(NumberOfGuesses):
print("ITS ROUND {}! GET READY!".format(Guess))
print(" ")
PlayersForRound = NumberOfPlayers
for Player in PlayersForRound:
print("It is Player {}'s Turn >>>".format(Player))
print(PlayersForRound)
print(NumberOfPlayers)
PlayerEntry = None
while not isinstance(PlayerEntry, int):
try:
PlayerEntry = int(input("Enter guess number {}: ".format(Guess)))
print(" ")
except ValueError:
print("Please enter a whole number")
print("CALCULATING YOUR RESULT!")
time.sleep(1)
print("***5***")
time.sleep(1)
print("***4***")
time.sleep(1)
print("***3***")
time.sleep(1)
print("***2***")
time.sleep(1)
print("***1***")
if PlayerEntry == CompNum:
print("Congratulations player {}, you have successfully guessed the number on round {}!".format(Player, Guess))
print(" ")
NumberOfPlayers.pop(Player-1)
if len(NumberOfPlayers) == 1:
print("Only {} Player remains".format(len(NumberOfPlayers)))
PlayersForRound
elif len(NumberOfPlayers) > 1:
print("Only {} Players remain".format(len(NumberOfPlayers)))
continue
elif PlayerEntry < CompNum:
print("Your guess was too low!")
print(" ")
GuessesLog.append(PlayerEntry)
continue
elif PlayerEntry > CompNum:
print("Your guess was too high!")
print(" ")
GuessesLog.append(PlayerEntry)
continue
if Guess == len(NumberOfGuesses):
print("ITS ROUND {}! THIS IS THE LAST ROUND! GOOD LUCK!".format(Guess))
print(" ")
print(NumberOfGuesses)
print(NumberOfPlayers)
print(len(NumberOfGuesses))
print(len(NumberOfPlayers))
PlayersForRound = NumberOfPlayers
for Player in PlayersForRound:
print("It is Player {}'s Turn >>>".format(Player))
PlayerEntry = None
while not isinstance(PlayerEntry, int):
try:
PlayerEntry = int(input("Enter guess number {}: ".format(Guess)))
print(" ")
except ValueError:
print("Please enter a whole number")
print("CALCULATING YOUR RESULT!")
time.sleep(1)
print("***5***")
time.sleep(1)
print("***4***")
time.sleep(1)
print("***3***")
time.sleep(1)
print("***2***")
time.sleep(1)
print("***1***")
if PlayerEntry == CompNum:
print("Congratulations player {}, you have successfully guessed the number on round {}!".format(Player, Guess))
print(" ")
NumberOfPlayers.pop(Player-1)
if len(NumberOfPlayers) == 1:
print("Only {} Player remains".format(len(NumberOfPlayers)))
elif len(NumberOfPlayers) > 1:
print("Only {} Players remain".format(len(NumberOfPlayers)))
continue
elif PlayerEntry < CompNum:
print("Your guess was too low!")
print(" ")
GuessesLog.append(PlayerEntry)
continue
elif PlayerEntry > CompNum:
print("Your guess was too high!")
print(" ")
GuessesLog.append(PlayerEntry)
continue
print("The closest guess was ", closest_num(GuessesLog, CompNum))
print(" ")
while True:
Answer = input("Would you like to play again? Y/N: ")
if Answer.lower() not in ('y', 'n'):
print("Please enter either Y for Yes, or N for No.")
else:
break
if Answer == 'y':
GameActiveMode = True
elif Answer == 'n':
GameActiveMode = False
print("Thankyou for playing ;)")
break
holdCall = str(input("Holding the console, press enter to escape."))
In my above code, when there are multiple players and multiple guesses(Rounds) then it works fine unless someone successfully guesses the code. If the code is guessed the code deletes the correct record from the player list. But for some reason fails to iterate over the rest of the list or if the correct guess comes from the second user it skips the next player altogether and moves onto the next round.
I have absolutely no idea why. Anyone have any ideas? Thanks in advance.
For example, if you run this in console and then have 3 guesses with 3 users, on the first player you guess incorrectly. On the second you guess correctly, it skips player 3 and goes straight to round 2. Despite only remove player 2 from the list after a correct guess.
Or if you guess it correctly the first time around it skips to the 3rd player?
You are keeping track of players in the current round using a list of player numbers. So, if you start with three players, PlayersForRound will start as [1,2,3].
You then proceed to loop over this list to give each player their turn by using for Player in PlayersForRound. However, PlayersForRound and NumberOfPlayers are the exact same list (not a copy), so when you remove a player from one, it is removed from both.
Once a player guesses correctly, you remove them from the list you were looping over with NumberOfPlayers.pop(Player-1). For example if the second player guesses correctly, you remove their "index" from the list and the resulting list is now [1,3].
However, because Python is still looping over that same list, player 3 never gets their turn, because their "index" is now in the position where the "index" of player 2 was a moment ago.
You should not modify the list you're looping over, this will result in the weird behaviour you are seeing. If you want to modify that list, you could write a while loop that conditionally increases an index into the list and checks whether it exceeds the length of the list, but there are nicer patterns to follow to achieve the same result.
As for naming, please refer to https://www.python.org/dev/peps/pep-0008/ - specifically, your variables like PlayersForRound should be named players_for_round, but more importantly, you should name the variables so that they mean what they say. NumberOfPlayers suggests that it is an integer, containing the number of players, but instead it is a list of player numbers, etc.
The selected bits of your code below reproduce the problem, without all the fluff:
# this line isn't in your code, but it amounts to the same as entering '3'
Players = 3
NumberOfPlayers = []
for i in range(Players):
NumberOfPlayers.append(i+1)
PlayersForRound = NumberOfPlayers
for Player in PlayersForRound:
# this line is not in your code, but amounts to the second player guessing correctly:
if Player == 2:
NumberOfPlayers.pop(Player-1)
if Player == 3:
print('this never happens')
# this is why:
print(PlayersForRound, NumberOfPlayers)
When you pop the list, you intervene in the for loop. Here, you can play with this and see yourself.
players = 3
player_list = []
for p in range(players):
player_list.append(p + 1)
for player in player_list:
print(player)
if player == 2:
print("popped:",player_list.pop(player-1))
Output
1
2
popped: 2

Guess the highest number issue

I am creating a Python Dice game called Beat That. I have gotten everything to work so far except for taking the players guess and comparing it to the highest possible number you can make. So let's say you roll a 5 and a 2 the highest number you could make it 52. So far when I enter the correct number it always says incorrect. Any help is appreciated.
In the screenshot below everything works except for the def turn section where it says "The highest number you could've made out of your roll is ...". It prints out the correct number but it marks it as incomplete.
This is the whole code:
import random
import time
from random import randint
play_again = True
#greeting the players to the game
print("Welcome to Beat That, a small game made by Mats Muche.")
#as long as play_again is true this will repeat itself until the user decides to end the game
while play_again:
totalnumber = []
def rollDice(numOfDice):
num = []
for i in range(1,numOfDice+1):
num = randint(1, 6)
print("Rolling the dice... You rolled a",num)
totalnumber.append(num)
time.sleep(1.5)
return num
return totalnumber
#this part checks the players guess to the highest number that can be made
def turn(numOfDice):
roll = rollDice(numOfDice)
totalnumber.sort(reverse = True)
print(*totalnumber , sep="")
guess = int(input("What is the biggest number you can make?"))
if guess == totalnumber:
print("Correct!")
else:
if totalnumber != guess:
print("Incorrect!")
print("The highest number you could've made out of your roll is ", *totalnumber , sep="")
time.sleep(1)
return totalnumber
#main code
#rules
print("*" * 80)
print("Here are the rules!")
time.sleep(1)
print("-Players may take turns rolling a set number of dice.")
time.sleep(1)
print("-The aim of the game is to get the biggest number from your dice roll.")
print("*" * 80)
time.sleep(2)
#amount of dice players want to use
numOfDice = int(input("How many dice would you like to use? "))
#start of game
print("Player 1's turn:")
time.sleep(1)
p1 = turn(numOfDice)
print("*" * 80)
time.sleep(2)
print("Player 2's turn:")
time.sleep(1)
totalnumber = []
p2 = turn(numOfDice)
print("*" * 80)
#seeing who won the game (highest number made wins)
if p1 > p2:
print("Player 1 has won the game! Congrats!")
time.sleep(1)
elif p2 > p1:
print("Player 2 has won the game! Congrats!")
time.sleep(1)
else:
print("It's a tie! Try again.")
print("*" * 80)
#seeing if players want to play again
again = input("Do you want to play again? Press any key except from 'n' to continue. ")
if again[0].lower() == 'n':
play_again = False
#if players say "n" then this message pops up and the game ends
print("End of game. Thank you for playing!")
Thanks for reading :)
As I am a beginner who is in school. I do not really have much knowledge of how to fix something like this issue.
This is the line that is the problem.
print("The highest number you could've made out of your roll is ", *totalnumber , sep="")
The problem would be this line:
def turn(numOfDice):
roll = rollDice(numOfDice)
totalnumber.sort(reverse = True)
print(*totalnumber , sep="")
guess = int(input("What is the biggest number you can make?"))
if guess == totalnumber:
print("Correct!")
Here, totalnumber is a list, not an int. therefore, you can try to make the input similarly a list too. change:
guess = int(input("What is the biggest number you can make?"))
into:
guess = list(map(int, input("What is the biggest number you can make?")))
Which should fix the issue.

first python program, what am i doing wrong

This is my attempt at a simple dice game. when I run the program it asks me how many dice I want to roll when I enter 1, it just asks again and then closes the program.
I feel like at least one of my problems is that the input maybe isn't being read as an integer?
I'm not really sure.
In the mean time, I'm gonna stare at it for a while and maybe ill figure it out.
import random
def roll1Dice():
roll = random.randint(1,6)
print("You rolled a " + roll)
def roll2Dice():
roll1 = random.randint(1,6)
roll2 = random.randint(1,6)
print("You rolled a " + roll1)
print("You rolled a " + roll2)
def main():
input("roll 1 or 2 dice? ")
if input == 1:
roll1Dice()
elif input == 2:
roll2Dice()
else:
print("Please enter a 1 or a 2.")
main()
input is a function that returns a str. You need to capture this return and then compare it.
def main():
user_input = input("roll 1 or 2 dice? ")
if user_input == '1': # notice that I am comparing it to an str
roll1Dice()
elif user_input == '2':
roll2Dice()
else:
print("Please enter a 1 or a 2.")
main() # add this line to request input again
Alternatively, you could cast to an int:
def main():
user_input = int(input("roll 1 or 2 dice? "))
if user_input == 1: # notice that I am comparing it to an int here
roll1Dice()
elif user_input == 2:
roll2Dice()
else:
print("Please enter a 1 or a 2.")
main()
If you cast to an int, however, be aware that a non-int will cause an exception.
You weren't assigning the value of input to anything (input is the function that actually accepts user input) Also, your print statements were failing because they were trying to combine an int with a string, so I've replaced it using string formatting. The below code should help
import random
def roll1Dice():
roll = random.randint(1,6)
print("You rolled a %s" % roll)
def roll2Dice():
roll1 = random.randint(1,6)
roll2 = random.randint(1,6)
print("You rolled a %s" % roll1)
print("You rolled a %s" % roll2)
def main():
myinput = input("roll 1 or 2 dice? ")
if myinput == 1:
roll1Dice()
elif myinput == 2:
roll2Dice()
else:
print("Please enter a 1 or a 2.")
main()

Categories