Camel Game, trouble with native distance values - python

I'm trying to write the Camel game using functions instead of so many nested if statements. I think I've done something wrong though, I've had to tinker with the native distance portion a lot as I kept getting into parts where they only got further away not closer. But now after trying to change the randomint values I can never escape them. Any suggestions for improvement are much appreciated!
Here is my code:
import random
def quitGame():
print("I am guitting now.")
return True
def status(milesTraveled, thirst, camelTiredness, distanceNativesTraveled, drinks):
print(
"""
You have traveled %d miles
Your Camel Status is %d (lower is better)
You have %d drinks left in your canteen
Your thirst is %d (lower is better)
The Natives are %d miles behind you
"""%(milesTraveled,camelTiredness,drinks,thirst,distanceNativesTraveled))
def rest():
print("The camel is happy")
distanceN = random.randint(7,14)
return(distanceN)
def fullSpeed():
distanceT = random.randint(10,20)
print("You travel %d miles"%distanceT)
camelT = random.randint(1,3)
distanceN = random.randint(7,14)
return(distanceT,camelT,distanceN)
def moderateSpeed():
distanceB = random.randint(5,12)
print("You travel %d miles"%distanceB)
nativesB = random.randint(7,14)
return(distanceB,nativesB)
def thirsty(drinksLeft):
drinksL = drinksLeft - 1
return(drinksL)
def main():
choice = ""
done = False # loop variable
#variables for game
milesTraveled = 0
thirst = 0
camelTiredness = 0
distanceNativesTraveled = -20
drinks = 5
print(
"""
Welcome to the Camel Game!
You have stolen a camel to make your way across the great Mobi desert.
The natives want their camel back and are chasing you down. Survive your
desert trek and out run the native.
"""
)
while not done:
findOasis = random.randint(1,20)
print(
"""
Here are your choices:
A - Drink from you canteen.
B - Ahead moderate speed.
C - Ahead full speed.
D - Stop and rest for night.
E - Status check.
Q - Quit the Game
"""
)
choice = input(" Your choice?\n")
if choice.upper() == "Q":
done = quitGame()
elif findOasis is 1 :
print("Wow! You've found an Oasis. Your thirst is quenched, canteen topped off, \
and your camel is now well rested and happy.")
drinks = 5
thirst = 0
camelTiredness = 0
elif choice.upper() == "A":
if drinks > 0:
drinks = thirsty(drinks)
thirst = 0
else:
print("Error: Uh oh! No water left.")
elif choice.upper() == "B":
milesB,nativesB = moderateSpeed()
milesTraveled += milesB
camelTiredness += 1
thirst += 1
distanceNativesTraveled += nativesB
elif choice.upper() == "C":
milesT,camelTired,nativesT= fullSpeed()
milesTraveled += milesT
camelTiredness += camelTired
distanceNativesTraveled += nativesT
thirst += 1
elif choice.upper() == "D":
distanceT = rest()
camelTiredness = 0
distanceNativesTraveled += distanceT
elif choice.upper() == "E":
statusCheck = status(milesTraveled, thirst, camelTiredness, distanceNativesTraveled, drinks)
else:
print("That was not a correct choice - Enter (A through E or Q)")
if thirst > 4 and thirst <= 6:
print("You are thirsty")
elif thirst > 6:
print("GAME OVER \nYou died of thirst!")
done = True
elif camelTiredness > 5 and camelTiredness <= 8:
print("Your camel is getting tired")
elif camelTiredness > 8:
print("GAME OVER \nYour camel is dead.")
done = True
elif distanceNativesTraveled >= 0:
print("GAME OVER \nThe natives have captured you!")
done = True
elif distanceNativesTraveled > -15:
print("The natives are getting close!")
elif milesTraveled >= 200:
print("YOU WIN \nCongrats, you made it across the desert!")
done = True
# call main
main()

The game ends when distanceNativesTraveled >= 0 and yet there's no code at all to decrease distanceNativesTraveled. So with every turn distanceNativesTraveled keeping increasing, the game is bound to end quickly.
What you really want here is to check if distanceNativesTraveled has surpassed milesTraveled, so change:
elif distanceNativesTraveled >= 0:
to:
elif distanceNativesTraveled >= milesTraveled:
And for the check to see if natives are getting close, change:
elif distanceNativesTraveled > -15:
to:
elif distanceNativesTraveled - milesTraveled > -15:
And to properly show the how many miles the natives are behind you, you should show the difference between the miles you and the natives traveled, so change:
"""%(milesTraveled,camelTiredness,drinks,thirst,distanceNativesTraveled))
to:
"""%(milesTraveled,camelTiredness,drinks,thirst,milesTraveled - distanceNativesTraveled))

Related

Doesn't run IF statement even though condition is true, but loops other IF

import random
player_health = 100
boss_health = 80
guard1_health = 10
guard1_status = "alive"
guard2_health = 15
gladiator_health = 20
weapon = 0
level = 0
turn = 0
def choose_weapon():
global weapon
global level
weapon = int(input("Choose your weapon:\n 1: Sword \n 2: Daggers \n 3: Bow \n Type here to choose:"
"\n--------------------------"))
if weapon == 1:
weapon = str("Sword")
print("You have chosen", weapon)
elif weapon == 2:
weapon = str("Daggers")
print("You have chosen", weapon)
else:
weapon = str("Bow")
print("You have chosen", weapon)
level += 1
choose_weapon()
def level_1_enemy():
global guard1_status
global guard1_health
global level
global turn
global weapon
print("Player turn")
if guard1_status == "alive" and guard1_health > 0 and turn == 1:
print("test")
if weapon == 1:
guard1_health -= 8
print("Guard health:", guard1_health)
turn -= 1
elif weapon == 2:
guard1_health -= 5
print("Guard health:", guard1_health)
turn -= 1
elif weapon == 3:
bow_crit = random.randint(1, 10)
if bow_crit == 1:
guard1_health -= 20
print("Guard health:", guard1_health)
else:
guard1_health -= 5
print("Guard health:", guard1_health)
if guard1_health <= 0:
print("You defeated the Guard, next level!")
guard1_status = "dead"
level += 1
return
def level_1_player():
global player_health
global weapon
global level
global turn
if player_health > 0 and turn == 0:
if weapon == 2:
dodge = random.randint(1, 3)
if dodge == 1:
print("You dodged the attack!")
return
else:
player_health -= 5
print("\n\nThe enemy hit you! (-5 hp)")
print("Enemy health: ", guard1_health)
print("Your health: ", player_health)
return
else:
player_health -= 5
print("\n\nThe enemy hit you! (-5 hp)")
print("Enemy health: ", guard1_health)
print("Your health: ", player_health)
return
print("You have died, Game Over.")
return
while level == 1:
if turn == 0:
level_1_player()
turn += 1
elif turn == 1:
level_1_enemy()
turn -= 1
I want to have the game loop through player and enemy turns until either the player is dead or the enemy. It reaches the first IF in level_1_enemy and prints "test", but does not continue to the next if statement even though the condition "weapon == 1" is true.
The last while loop is meant to repeat the level_1_enemy and level_1_player functions. It does do both but will also not stop looping once the guard or player is dead.

Loop continues looping, even after termination message

I am having some trouble with getting user input to stop looping after the termination message. Basically, once 0 (zero) is entered in the Enter bet field, the program must print a termination message and end. However, it continues to loop by asking for the next line of input "Choose a number between 2 and 12" when it should be skipped.
I know a break or exit() will fix my problem, but those are not acceptable solutions. Once 0 (zero) is entered in the Enter bet field, I need it to finalize and print a termination messag. Not continue on with the program.
Example NEEDED output:
you have $500 in your bank # starting amount
Enter bet (or 0 to quit): 0
Thanks for playing!
What I am getting instead:
Enter bet (or 0 to quit): 0
Thanks for playing!
Choose a number between 2 and 12: # where the program continues to run
# when it shouldn't. The user should only see this input field if they enter
# number above 0
This is the code
import random
def rollDice(cnt):
die1 = random.randint(1,6)
die2 = random.randint(1,6)
x = int(die1 + die2)
print('Roll #', cnt, 'was', x)
return x
def total_bank(bank):
bet = 0
while bet <= 0 or bet > min([500,bank]):
print(f'You have ${bank} in your bank.')
get_bet = input('Enter your bet (or 0 to quit): ')
bet = int(get_bet)
if get_bet == '0':
print('Thanks for playing!')
return bank, bet
return bank, bet
def get_guess():
guess = 0
while (guess < 2 or guess > 12):
try:
guess = int(input('Choose a number between 2 and 12: '))
except ValueError:
guess = 0
return guess
prog_info()
bank = 500
guess = get_guess
rcnt = 1
while rcnt < 4:
rcnt = 0
bank,bet = total_bank(bank)
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * 1.5
elif guess == rollDice(rcnt+3):
bank = bank
else:
bank = bank - bet
if bank == 0:
print(f'You have ${bank} in your bank.')
print('Thanks for playing!')
Create a “bank” (variable) with a starting value of $500.
Ask the player for a bet
Must be 0 (zero) or greater and cannot exceed the amount currently in the bank.
Roll the 2 die
If the players guess matched the 1st roll then add double the amount bet to the “bank”
If the players guess matched the 2nd roll then add 1 ½ times the amount bet to the “bank”.
If the players guess matched the 3rd roll than add the amount bet to the bank.
-If the players guess did NOT match any roll then subtract the bet from the “bank”.
Let the player keep on playing until they enter a “0” (zero) as the bet OR when their bank reaches “0” (zero).
NO USE OF BREAK OR EXIT()
The 0 check should call exit
if get_bet == '0':
print('Thanks for playing!')
exit()
If you prefer not to use exit or break, you need to exit the main loop using a condition
Update total_bank
if get_bet == '0':
print('Thanks for playing!')
return bank, bet
Update the main loop
bet = 1 # to start loop
while rcnt < 4 and bet: # exit loop if bet=0
rcnt = 0
bank,bet = total_bank(bank)
if not bet: continue # exit game if bet = 0
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * 1.5
elif guess == rollDice(rcnt+3):
bank = bank
else:
if bet: # bet = 0 if game end
bank = bank - bet
if bank == 0:
print(f'You have ${bank} in your bank.')
print('Thanks for playing!')
you're returning to
while rcnt < 4:
rcnt = 0
bank,bet = total_bank(bank)
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * 1.5
elif guess == rollDice(rcnt+3):
bank = bank
after breaking from loop inside total_bank(bank):
you can modify the main loop to break if bet==0 by modifying it as follows
while rcnt < 4:
rcnt = 0
bank,bet = total_bank(bank)
if bet==0 :
break;
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * 1.5
elif guess == rollDice(rcnt+3):
bank = bank
EDIT - doing it without a break.
Check if bet!=0 before executing the loop.
Just initialise bet to any value other than zero.
bet=1
while (rcnt < 4) and (bet!=0):
rcnt = 0
bank,bet = total_bank(bank)
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * 1.5
elif guess == rollDice(rcnt+3):
bank = bank
to get your first line of needed output change your print statement to
print('You have ${} in your bank.'.format(bank))

NameError, variable not defined in Python

so the ultimate goal is to run best 2 out of 3 games of rock, paper, scissors, lizard, spock. i haven't added a loop yet or anything like that i'm trying to get the game itself running first but I'm coming across a NameError, it's saying the 'result' variable is undefined.
I've tried returning it but that doesn't appear to be working, but I also maybe don't know what I'm doing?
def number_to_name(number):
if number == 1:
return 'scissors'
elif number == 2:
return 'rock'
elif number == 3:
return 'paper'
elif number == 4:
return 'lizard'
elif number == 5:
return 'spock'
else:
print ("Error: Invalid number")
def name_to_number(name):
if name == 'scissors':
return 1
elif name == 'rock':
return 2
elif name == 'paper':
return 3
elif name == 'lizard':
return 4
elif name == 'spock':
return 5
else:
print ("Error: Invalid number")
def rpsls(name):
player_score, computer_score = (0, 0)
player_input = name_to_number(name)
computer_input = random.randint(1,5)
result = (player_input - computer_input) % 5
if result == 1 or result == 2:
print("player wins")
player_score += 1
print("Player {}, Computer {}". format(player_score, computer_score))
elif result == 3 or result == 4:
game = "computer wins"
computer_score += 1
print("Player {}, Computer {}". format(player_score, computer_score))
elif result == 0:
game = "it's a tie"
print("Player {}, Computer {}". format(player_score, computer_score))
else:
print("error")
rpsls("rock")
rpsls("spock")
rpsls("paper")
rpsls("lizard")
rpsls("scissors")
Your conditions should be inside the rpsls function.Because you result variable is local variable. You can't fetch this variable globally.
> def rpsls(name):
> player_score, computer_score = (0, 0)
> player_input = name_to_number(name)
> computer_input = random.randint(1, 5)
> result = (player_input - computer_input) % 5
>
>
> if result == 1 or result == 2:
> print("player wins")
> player_score += 1
> print("Player {}, Computer {}".format(player_score, computer_score))
>
> elif result == 3 or result == 4:
> game = "computer wins"
> computer_score += 1
> print("Player {}, Computer {}".format(player_score, computer_score))
>
> elif result == 0:
> game = "it's a tie"
> print("Player {}, Computer {}".format(player_score, computer_score))
>
> else:
> print("error")
Your variable result is inside the function rpsls. So the scope of result lies to the function only.
A easy solution would be assign a 0 value to result before the function 'rpsls'
This way your updating a globally defined variable inside the function.
result = 0
def rpsls(name):
#Your code
The best way would be to write a class, have a class level variable result, and put all this code into the class.
First of all, since result is only defined in the function, it is only accessable inside that specific function, unless you choose to use the global method, which I wouldn't recommend.
Second, since you called result before you called the function that actually defines result, even if you use global, it will still not be defined for that specific line.

Returning Value from Function to Variable

So I'm currently having some trouble with working out how to basically create a "count" function work within my Rock, Paper, Scissors game. I'm new to Python and this is my first foray into the use of multiple functions to execute game logic. Here's my code...
import random
from random import choice
cpu_score = 0
player_score = 0
# dictionary from which gestures are pulled
gestures = ["rock","paper","scissors"]
n_rounds = int(input("How many rounds would you like to play? "))
while n_rounds % 2 == 0 or n_rounds <= -1:
print("Number of rounds must be an odd number! Select an odd number!")
n_rounds = input("How many rounds?")
break
print("Lets play",n_rounds,"rounds!")
rounds_to_win = ((n_rounds + 1)//2)
rounds_to_win = round(rounds_to_win)
print("You must win",rounds_to_win,"rounds to beat the game!")
def computer_choice():
"""Movement made by the computer"""
comp = random.choice(gestures)
return comp
def player_gesture():
"""Movement by player"""
player = input("Please select, rock, paper or scissors")
if player not in gestures:
print("That's not an option! Please try again.")
player = input("Please select, rock, paper or scissors")
return player
def who_won_round(comp, player):
'''Who is the winner of the round.'''
winner = 0
if ((player == "rock") and (comp == "paper")) or \
((player == "paper") and (comp == "scissors")) or \
((player == "scissors") and (comp == "rock")):
winner = 1
elif ((comp == "rock") and (player == "paper")) or \
((comp == "paper") and (player == "scissors")) or \
((comp == "scissors") and (player == "rock")):
winner = 2
else:
winner = 0
return winner
def win_counter(winner, cpu_score,player_score):
rounds = 1
if winner == 1:
player_score += 1
print("This is round",rounds)
rounds += 1
return player_score
if winner == 2:
cpu_score += 1
print("This is round",rounds)
rounds += 1
return cpu_score
def count_round(winner, player, comp, cpu_score, player_score):
if winner == 0:
print("It's a tie!")
elif winner == 1:
print("The player chose",player)
print("The computer chose",comp)
print("The computer won the round!")
print("The computer has won",cpu_score,"rounds!")
elif winner == 2:
print("The player chose",player)
print("The computer chose",comp)
print("The player won the round!")
print("The player has won",player_score,"rounds!")
def game_structure():
while rounds_to_win < n_rounds:
comp = computer_choice()
player = player_gesture()
winner = who_won_round(comp,player)
win_count = win_counter(winner, cpu_score,player_score)
count = count_round(winner, player, comp, cpu_score, player_score)
game_structure()
Basically I'm having issues returning the variables in order to keep count of the scores of the "number of rounds" and "cpu_score" and "player_score". I prefer to not declare global variables as I realise they can be messy to use, but I'm not quite sure how to avoid this.
If you must avoid the use of global variables, you should take an object oriented approach. That way you can store the variables in the object.
So basically you do something like this:
newgame = mytictactoe()
while True #infinite loop
input("wanna play?")
if input == yes:
newgame.start
else:
break
From what I see, the cpu_score and player_score are never updated. You only have the newest result in win_count, that is not assigned to cpu_score or player_score at anytime. It could be something like:
win_count = win_counter(winner, cpu_score,player_score)
if winner == 1:
cpu_score = win_count
if winner == 2:
player_score = win_count
rounds_to_win = max(player_score, cpu_score)
count_round(winner, player, comp, cpu_score, player_score)
I did not run it, but this modifications should do the trick. There are better ways of doing it; maybe using a list to keep the scores and use winner as the index, or an object approach as someone else said, but I do not want to change too much the code.
Also, bear in mind that the round variable in win_counter does nothing.

How to automatically change a number to zero once it reaches a negative value?

while opponentHealth >= 0 or userHealth >= 0:
userInput = input()
if userInput == "attack":
opponentOne = "Larry"
userDamage = random.randint(0, 100)
opponentDamage = random.randint(0, 20)
opponentHealth = opponentHealth - userDamage
if(userDamage < 25) and (userDamage > 0):
print("You roundhouse kick {} in the abdomen and he begins to vomit." .format(opponentOne) or "You punch {} in the stomach and he begins to tear up." .format(opponentOne))
print("You did {} damage to him" .format(userDamage))
print("He has {} health remaining." .format(opponentHealth))
elif(userDamage < 100) and (userDamage > 25):
print("You drive your foot into {}'s groin with as much force as possible. You hear a high-pitched scream emit from his vocal chords." .format(opponentOne) or "{} is intimidated by you and decides to slap himself mindlessly, in hopes that he will lose faster." .format(opponentOne))
print("You did {} damage to him; a CRITICAL HIT!" .format(userDamage))
print("He has {} health remaining." .format(opponentHealth))
elif userDamage == 100:
print("{} forfeits... Coward." .format(opponentOne))
print("You did {} damage to him. INSTANT K.O" .format(userDamage))
print("He has {} health remaining." .format(opponentHealth))
else:
print("Swing and a miss. You missed {}." .format(opponentOne) or "You underestimated {}" .format(opponentOne))
print("You did {} damage to him." .format(userDamage))
print("He has {} health remaining." .format(opponentHealth))
else:
print("Type 'attack' to attack.")
continue
So this is basically a mini fighting game I'm trying to make (first program ever, besides "Hello World" lol). Whenever the variable opponentHealth goes into the negatives, I want it to automatically turn into a 0 instead. So for instance, rather than it saying "He has -13 health remaining.", I want it to say "He has 0 health remaining." Any advice?
Thanks in advance!
Whenever you assign to opponentHealth, just take the max with 0. For example:
opponentHealth = max(0, opponentHealth - userDamage)
opponentHealth = opponentHealth - userDamage
if opponentHealth < 0:
opponentHealth = 0

Categories