Changing a local variable in multiple functions in Python? - python

background: I'm currently writing a text-based adventure and each enemy has a certain amount of turns you can attack it before it attacks back.
So to handle this the code sets an argument in the function for the fight dictating how many times you can attack.
def fight_sequence(rounds):
while rounds > 0:
attack = input()
if attack == magic:
magic("you teleport away to safety. Congratulations you have stayed alive through your journey and found a few souvenoirs. nice job!", 1, "you muster up all of your energy, chant the spell.... and nothing happens.Cthulu... seems unimpressed", 1, "")
elif attack == sword:
sword(1)
def magic(teleportmessage, teleportsuccess, firemessage, firefail, winmessage):
x = 0
while x == 0:
fightorflight = input("""you open the book to cast a spell
Do you want to try teleporting or use a fireball?""").lower()
if "teleport" in fightorflight:
if teleportsuccess = 1:
print(teleportmessage)
x = 1
else:
choice = input("You can't teleport out of this battle. Would you like to try a fireball?")
if choice == yes:
fightorflight = "fireball"
else:
x = 1
elif "fire" in fightorflight:
print(firemessage)
if firefail == 1:
choice = input("do you want to try to teleport instead?").lower()
if "yes" in choice:
fightorflight = "teleport"
else:
x = 1
else:
print(winmessage)
else:
print("Sorry not sure what you mean")
def sword(attacksuccess):
if attacksuccess == 1:
print("You pull out the sword and swing at the monster damaging it severely.")
else:
print("You pull out the sword and swing at the monster, but its immune to blunt objects.")
fight_sequence(3)
both magic() and sword() need to be able to decrease rounds by 1, originally i just did that before entering the magic or sword function. however some items to attack with allow you to attack more than once if you want so that won't work for them. Such as magic if they also choose to teleport. Is there a way to allow me to change the variable rounds while inside of another function?
I think using a return value might help but I'm not sure how to go about it

You can simply add a new argument to the magic function, and pass the 'rounds' variable through when you call it.
e.g.
def fight_sequence(rounds):
...
magic("some message", false, "fired", false, "you won", rounds)
def magic(teleportmessage, teleportsuccess, firemessage, firefail, winmessage, rounds):
Your passing through the variable (not just the value) so it will change in every context where rounds can be seen.
HTH.

I would recommend using classes to create this game rather than lots of functions, an example of a class in a hero game below.
class Hero:
def __init__(self):
self.health = 10
def eatApple(self):
self.health += 1
def takeDamage(self):
self.health -= 1
init function runs as class is initialized.
player = Hero()
print(player.health) # will print 10
player.takeDamage()
print(player.health) # will print 9
This way you can have global variables for you functions which can be changed in each function and is much more organised.

Related

How to make a Cage Fighting Simulation with user input instead of random for Python

Here is my code so far using random to pick moves:
import time
import random
PHealth = 10
CHealth = 10
PShots = [
"Great Body Shot To Your Opponent!",
"Nice Take Down!",
"Nice Punch!",
"Strong Kick!",
"You Have Him Pinned Against The Cage!",
"Excellent Counter-Shot!"
]
CShots = [
"You Took a Shot to the Body!",
"You Got Taken Down!",
"Strong Kick Hit You!",
"You Took A Big Punch!",
"You Are Pinned Against The Cage",
"Counter-Shot Got Ya!"
]
for i in range(20):
i = random.randint(0, 100)
if i >= 51:
print(random.choice(PShots))
CHealth = CHealth -1
if CHealth >= 1:
print("Player Health", PHealth)
print("Computer Health", CHealth)
time.sleep(5)
if i <= 50:
print(random.choice(CShots))
PHealth = PHealth -1
if PHealth >= 1:
print("Player Health", PHealth)
print("Computer Health", CHealth)
time.sleep(5)
if CHealth < 1:
print("What A Shot!")
time.sleep(1)
print("Down He Goes!")
time.sleep(1)
print("The Referee Has Stopped The Fight!!")
time.sleep(1)
print("Player Wins!!!")
break
if PHealth < 1:
print("What A Shot!")
time.sleep(1)
print("Down You Go!")
time.sleep(1)
print("The Referee Has Stopped The Fight!!")
time.sleep(1)
print("Computer Wins!!!")
break
Basically I'd like to understand how a player can input one move. So if a player inputs body shot it beats take down. If a player inputs kick it beats punch. If a player inputs take down it beats pinned against the cage, etc. Thinking 6-7 variations and counters.
Here is an idea of how you could implement something akin to what you seem to be looking for using a mix of classes and functions.
The following code should work with Python 3.9+ and has no additional dependencies.
First we define a Move class, instances of which need to have a name, a text_used (for when the player successfully uses the move), and a text_affected (for when move is used against the player). Each instance also stores a set of other Move objects, which it trumps, as well as a set of those it is trumped by. We have a helper method should_beat to easily define such a relationship between two moves.
class Move:
def __init__(self, name: str, text_used: str, text_affected: str, damage: int = 1) -> None:
self.name: str = name
self.text_used: str = text_used
self.text_affected: str = text_affected
self.damage: int = damage
self.trumps: set['Move'] = set()
self.trumped_by: set['Move'] = set()
def __str__(self) -> str:
return self.name
def should_beat(self, other_move: 'Move') -> None:
self.trumps.add(other_move)
other_move.trumped_by.add(self)
Next we define a Player class. Its instances have a name and an optional starting_health set to a previously defined constant by default.
A Player also has a use_move method that takes a Move object, another Player object (the opponent), and a second Move object (the move used by the opponent). That method checks which move beats which and calculates the health subtraction accordingly.
Finally, the Player object has win and lose methods that can be called to print out the win/loss statements when necessary.
class Player:
def __init__(self, name: str, starting_health: int = DEFAULT_STARTING_HEALTH) -> None:
self.name: str = name
self.health: int = starting_health
def __str__(self) -> str:
return self.name
def use_move(self, move: Move, vs_player: 'Player', vs_move: Move) -> None:
if vs_move in move.trumped_by:
self.health -= vs_move.damage
print(vs_move.text_affected)
elif move in vs_move.trumped_by:
vs_player.health -= move.damage
print(move.text_used)
else:
print(TEXT_NO_EFFECT)
def win(self, vs: 'Player') -> None:
print("What A Shot!")
sleep(1)
print(f"{vs} Goes Down!")
sleep(1)
print("The Referee Has Stopped The Fight!!")
sleep(1)
print(f"{self} Wins!!!")
def lose(self, vs: 'Player') -> None:
print("What A Shot!")
sleep(1)
print(f"Down You Go, {self}!")
sleep(1)
print("The Referee Has Stopped The Fight!!")
sleep(1)
print(f"{vs} Wins!!!")
Next, we want a function to define our moves and one that conveniently prints a list of moves to the terminal. Obviously you will want to expand the define_moves function to incorporate all your desired moves and their relationships. It should return a list of all your Move objects.
def define_moves() -> list[Move]:
kick = Move("kick", "Strong Kick!", "Strong Kick Hit You!")
punch = Move("punch", "Nice Punch!", "You Took A Big Punch!")
...
kick.should_beat(punch)
...
return [
kick,
punch,
]
def print_moves(moves_list: list[Move]) -> None:
print("Available moves:")
for i, move in enumerate(moves_list):
print(i, "-", move.name)
Now for the fun part, we need our main fighting loop. In each iteration, we prompt the player for a number that corresponds to an index in our list of moves defined earlier. (The player may also type h to see the moves again.) We do some checks to make sure we received a valid number to get our Move object.
Then we randomly chose a move for the computer opponent out of our moves list, and call our use_move method. It does the health calculations for us. So after that we just check, if someone is done to call the appropriate win or lose method and break out of the loop. Otherwise we print the current health stats and continue.
def fight_computer(player: Player, moves_list: list[Move]) -> None:
computer = Player(name="Computer")
while True:
string = input('Choose your move! (or type "h" to see available moves again)\n').strip().lower()
if string == 'h':
print_moves(moves_list)
continue
try:
i = int(string)
except ValueError:
print("You need to pick a number!")
continue
try:
move = moves_list[i]
except IndexError:
print("No move available with number", i)
continue
computer_move = choice(moves_list)
print(computer, "chose", computer_move)
player.use_move(move, vs_player=computer, vs_move=computer_move)
if player.health < 1:
player.lose(vs=computer)
break
if computer.health < 1:
player.win(vs=computer)
break
print(player, "health:", player.health)
print(computer, "health:", computer.health)
sleep(1)
Lastly, we need a main function to put it all together, prompt the player for his name, etc.
def main() -> None:
player_name = input("Enter your name: ").strip()
player = Player(player_name)
moves_list = define_moves()
print_moves(moves_list)
fight_computer(player, moves_list)
if __name__ == '__main__':
main()
Don't forget to add your imports and constant definitions to the start of the module:
from random import choice
from time import sleep
DEFAULT_STARTING_HEALTH = 10
TEXT_NO_EFFECT = "Your move had no effect!"
All together, this should give you a crude version of the game you described. Try it out. Hope this helps.

How can i create multiple if statments that uses a def function as a condtion without having the def function repeat itself

I'm creating a game where one of the bosses (Suru) acts differently based on what the user inputs. The user input is created in a def() function inside a class (Player) and has to use returns to pass the results to the main def() function (boss_battle). However, whenever i try to use an if code to set conditions for the battle function, the user input repeats itself until the last line of the if statement.
Here is the if code that's causing the problem:
if player.attack(boss)== 'mercy':
kind = True
break
#If the player input returns 'mercy' then the battle will stop
#However the results don't show as the code moves on to repeat itself in the next line
elif player.attack(boss) in ('heal, no_mercy'):
pass
#If the player chooses to heal or fails to give mercy then the battle will continue as normal, however Suru won't be able to attack the player that turn
#The same happens with this line
elif player.attack(boss)==('attack'):
wait = 'no'
#If the player chooses to fight then the battle will commence as normal, however Suru will no be able to attack throughout the rest of the battle
#This line prints out the results but the results end up being inaccurate as 'mercy' or 'heal' aren't taken into effect
What is supposed to happen is whatever the user inputs (and the code returns) will affect what Suru does: 'heal' and 'no_mercy) causes him to wait (not attacking on that turn), 'mercy' causes the battle to end and 'attack' causes Suru to attack the player back (and continue to do so for the rest of the battle).
However what is does instead is repeat the player input 3 times, only taking the third input into account. This causes the code to be inaccurate as the condition meet by the third input will only work for attack (allowing the Suru to attack the player) and not for mercy or heal / no_mercy.
Keep in mind that even if you enter the correct condtions for the statement, the code will continue to go through each if statement (causing the user input to be requiered 3 times instead of 1).
Below is a sample code to run if needed while explaining the bases of the code and what im trying to achieve.
class Character:
#Creates the base for the Player and the enemy setup
def __init__(self, health, power, speed, core, max_health):
self.health = health
self.power = power
self.speed = speed
self.core = core
def attack(self, other):
raise NotImplementedError
#Allows for the enemy_attack and attack_enemy methods (functions) to be placed into separate classes
#Allows for the player and enemy to be able to attack each other
class Player(Character):
#Creates Data and stats for the Player
def __init__(self, name, health, power, speed, core, max_health, heal, counter, endure):
super().__init__(health, power, speed, core, max_health)
#Creates the base for the stats required for the player
#Super() allows for the parent class in (charecter class) to be called and used to create stats the child class (Player)
self.name = name
self.power = power
self.speed = speed
self.core = core
self.max_health = max_health
self.heal = heal
self.counter = counter
self.endure = endure
def attack(self, other):
action = input("\nWhat move would you like to make (fight, heal or mercy)? ").lower()
print()
sleep(1)
#Asks the user what to do
if action in ('fight', 'heal', 'mercy'):
if action == 'heal':
print("\nYou try to heal your wounds")
sleep(1)
self.health += self.heal
print("You have {0.health} hp.\n".format(self))
sleep(1)
return 'heal'
#Returns that the user has healed that turn and did not attack, allowing wait to remain as 'yes' - unless the user has attacked before
elif action == 'mercy':
chance = (random.randint(1, 10))
response = random.choice(["You tell the {0.name} that you don't want to fight.".format(other),
"You refuse to fight.", "You remain still to show the {0.name} that you don't wan't to fight.",
"You try to give the {0.name} mercy.".format(other)])
re_response = random.choice(response)
print(response)
sleep(1)
if chance >= other.mercy_count:
response_fail = random.choice(["But you were unable to convince the {0.name} not to fight.".format(other),
"But the {0.name} didn't believe you.".format(other),
"Yet the {0.name} still wants to fight.".format(other),
"But it didn't work."])
print(response_fail)
sleep(1)
return 'no_mercy'
elif chance < other.mercy_count:
response_pass = random.choice(["You were able to convince the {0.name} not to fight.".format(other),
"The {0.name} decided believe you.".format(other),
"As it turns out, the {0.name} didn't want to fight.".format(other),
"It worked."])
print(response_pass)
return 'mercy'
sleep(1)
#Mercy is based on a selective chance, if the player is able to spare Suru, then it returns 'mercy', causing the battle to end
elif action == 'fight':
print("You attack the {0.name}.".format(other))
other.health -= int(self.power * random.randint(1,3))
sleep(1)
#other.health = enemy health
#uses the Player's power to randomly (within reason) generate the damage taken by the enemy
#Also allows for a way to bypass the problem of not being able to convert player.power to a numeric figure
return 'attack'
#Returns attack - stating that the user has chosen to fight - and allows for the code to inishiate Suru's attack pattern
else:
print("you stumble...")
sleep(1)
#If the entry isn't valid then the message is diplayed and the sequence is conitnued
class Boss(Character):
def __init__(self, name, health, power, speed, core, max_health, mercy_count):
super().__init__(health, power, speed, core, max_health)
self.name = name
self.power = power
self.speed = speed
self.mercy_count = mercy_count
self.max_health = max_health
def attack(self, other):
print("The {0.name} attacks...".format(self))
sleep(1)
other.health -= int(self.power * random.randint(1,3)
def boss_battle(player, boss):
#Battle Function
kind = False
#variable used for mercy
wait = 'yes'
#variable used to determine whether on not Suru is to attack on that turn
print ("\n{0.name} confronts you!".format(boss))
sleep(0.5)
print ("{0.name} has {0.health} hp.".format(boss))
sleep(1)
print("\nYour stats are: {0.health} hp {0.power} atk {0.speed} spd\n".format(player))
sleep(0.75)
while player.health > 0 and boss.health > 0:
#Loop runs while both the player and Suru have hp left
#The following if code sparks the requested problem
if player.speed >= boss.speed:
#If the player's speed is greater than the bosses
if player.attack(boss)== 'mercy':
kind = True
break
#If the player input returns 'mercy' then the battle will stop
#However the results don't show as the code moves on to repeat itself in the next line
elif player.attack(boss) in ('heal'. 'no_mercy'):
pass
#If the player chooses to heal then the battle will continue as normal, however Suru won't be able to attack the player that turn
#The same happens with this line
elif player.attack(boss)==('attack'):
wait = 'no'
#If the player chooses to fight then the battle will commence as normal, however Suru will no be able to attack throughout the rest of the battle
#This line prints out the results but the results end up being inaccurate as 'mercy' or 'heal' aren't taken into effect
#End of problem if code
if boss.health <= 0:
break
#If Suru is dead (health lower than 0) then the battle ends
print ("{0.name} has {0.health} hp.\n".format(boss))
#Displays a message telling the user the hp stsatus of the enemy
sleep(0.5)
if boss.name == 'Suru':
if wait == 'yes':
b_response = random.choice(["Suru is watching you.", "Suru seems hesitant to strike."])
print(b_response)
#Suru skips it's turn
else:
boss.attack(player)
# Suru attacks the player
if player.health <= 0:
break
#If the player is dead (health lower than 0) then the battle ends
print("You have {0.health} hp.\n".format(boss))
sleep(1)
#Displays the player's health
if kind:
print("\nYou part ways with {0.name}.\n\n".format(boss))
sleep(1)
else:
if player.health > 0:
print("\nYou killed {0.name}.".format(boss))
print()
sleep(1)
elif boss.health > 0:
print("\nThe {0.name} has killed you.".format(boss))
print()
if __name__ == '__main__':
#Allows for the main script to be run and variables to be created and entered
players = (Player("Hero", 100, 18, 50, 300, 100, 50, 0, 0))
#Player list allows for the player to have stats that can be changed
bosses = [Boss("Feng", 100, 15, 70, 50, 100, 8), Boss("Shen", 150, 15, 80, 100, 150, 5),
Boss("Suru", 200, 20, 20, 200, 200, 3), Boss ("Mlezi", 45, 10, 60, 0, 45, 6)]
boss_battle(players, bosses[2])
#Allows for Suru boss battle
This is what the code displays:
(Not sure how to display a picture, sorry)
Suru confronts you!
Suru has 200 hp.
Your stats are: 100 hp 18 atk 50 spd
What move would you like to make (fight, heal or mercy)? fight (user input)
You attack the Suru.
What move would you like to make (fight, heal or mercy)? fight
(it repeats due to the second line of the if code even though it's not supposed to)
You attack the Suru.
What move would you like to make (fight, heal or mercy)? heal
(it repeats a third time due to the third line of the if code even though it's not supposed to)
You try to heal your wounds
You have 100 hp.
Suru has 110 hp.
Suru is watching you.
You have 110 hp.
(Finally displays the result but is in accurate as i initially entered 'fight' which causes Suru to attac'; however, i change the final input to 'heal' to show how the code doesn't accept the first input (even though it should) and only accepts the third input (despite the fact the third and second inputs shouldn't exists)
What move would you like to make (fight, heal or mercy)?
(Repeats for the next turn)
I've already tried researching my question on stackflow, and other sites, using phrases such as 'how to check multiple conditions in if statement' (since i thought a way to anwser my question was to have python check the condtions in one line, limiting the amount of elifs and player.attack()) however this only turned up with ways to make multiple if statments / condtions more visualy appealing). Another search i tried was 'if statement in user defined function' but that didn't give me the results that i needed (or found useful).
I would really appreciate any feedback, not only on my code (however this is what's mainly addressed) but also any feedback on way i could improve my overall code (not as important).
Thanks in advance
It sounds like you're just asking how to store a value in a variable:
attack_result = player.attack(boss)
if attack_result == 'mercy':
# etc.
elif attack_result in ('heal, no_mercy'):
# etc.
elif attack_result == 'attack':
# etc.
This way, instead of calling player.attack(boss) over and over, we just call it once, and then use the result over and over.
While we're at it, as pointed out by David in a comment, in ('heal, no_mercy') probably isn't testing what you wanted.
'heal, no_mercy' is a single string. So ('heal, no_mercy') is a single string wrapped in meaningless parentheses. It's very different from ('heal', 'no_mercy'), which is a pair of strings.
What you've written will do a substring search—which will actually be true for heal and no_mercy, but also for mercy and al and any other substring. You probably want to change it to:
elif attack_result in ('heal', 'no_mercy'):

Passing on the parameters of a function into another one?

I'm not really sure how to word this, but I'll try my best. I've created a function for a zombie, and another one for attacks. But I don't know how to pass on the parameters of the zombie function into the attack function. Also if there is a more technical way to word this please let me know. Here is my test code for it, I'm sure this community will be able to figure out what I mean. The end goal is to create a function where I can plug in a monster name and have it's assigned parameters (health, defense, etc..) be run in through the combat function. ie def combat(monster_name): Any and all advice is much appreciated. Thank you!
#Functions
def zombie():
global zombie_hp
zombie_hp = 10
print "Zombie encounter"
print "Current Health:", zombie_hp
def attack(monster):
if monster > 0:
while monster > 0:
user_action = raw_input("Do you attack the zombie? [y]: ")
if user_action == "y":
monster_hp = monster_hp - 1
print "Health remaining: ", monster_hp
def user_action():
global user_action
user_action = raw_input("Do you attack the zombie? [y]: ")
# Zombie Encounter (attack_testing)
attack(zombie())
if zombie_hp == 0:
print "Zombie Defeated"
I suggest you use a class:
class Zombie:
def __init__(self):
self.defense = 10
self.hp = 100
def hit(self, hp):
self.hp-=hp
def upgrade(self, level):
self.defense+=level
This will remember the hp and defense for every zombie that you create
>>> Max = Zombie()
>>> Max.hit(17)
>>> Max.upgrade(2)
>>> Max.hp
83
>>> Max.defense
12
>>>

Need help writing algorithm in Python/Sage

I'm a complete novice to python and sage so I need some help and clarification on the steps all the way through. This is a question concerning game theory.
First I will describe the algorithm and then I will propose a solution the best I can.
The algorithm:
I want to start the program with a random variable from 1-100. This
variable will be defined 'S'. I also want to define a set of variables
'C' which can be deducted from S every turn, this set is {1,2,3,4,5,6}
(in other words the user and computer can deduct 1, 2, 3, 4, 5 or 6
from S. If variable S is divisible by 7 (e.g. 21), then print: "I
lose". If not, the game can begin.
Let's say that the random variable turns out to be 20. The player is
now prompted to enter a number within the range of C. When the player
has entered the number, I want the program to deduct that number from
S, so if the player enters 4 (a legal move), S is then 20-4=16. The
computer then calculates mod(S,7) and finds out that modulo 16,7 is 2
so it deducts 2 from S, in other words, 16-2=14.
If the player enters a number which results in S being divisible by 7, such as 6 (20-6=14) then the computer simply deducts 1 and attempts to get to such a number again next round.
The game continues until the computer eventually wins as the player is
eventually placed at 7 and has to deduct a number which the computer
can finish with (user deducts 6, computer deducts the last one and
wins). Print: "I win".
So like I said, I have literally no experience in python and sage so I can only go by my (limited) java experience:
I would attempt to establish a variable S with some 'ran' element (no idea what it's called in python). I would then attempt something like:
if S%7=0 then print "I lose"
else
prompt "Pick a number between 1 and 6, those included".
Declare user input as variable U.
Do S-U=S
Now do S-S%7=S
Now I want the program to realize when S=7 and then print: "You lose". If you can help me go all the way, though, that would be great.
import random
def playgame():
s = random.randint(1,100) #grabs a random integer between 1 and 100
POSS = range(1,7) #range ignores the last number, so this is [1,2,3,4,5,6]
if not s % 7: #if s%7 != 0
print("I lose")
return #exit the function
while s > 0: #while s is still positive
choice = 0 #set choice to 0 (this may as well have been "foo",
# I just needed it to not be in POSS)
while choice not in POSS: #until the user picks a valid number
choice = int(input("Select a number between 1 and 6: ")) #prompt for input
s -= choice #subtract choice from s, then set the difference to s
print("You subtracted {}, leaving {}".format(choice,s)) #print for the user
comp_choice = s%7 #the computer's choice is always s%7
s -= comp_choice #subtract the comp's choice from s, then set the diff to s
print("I subtracted {}, leaving {}".format(comp_choice,s)) #print for user
print("I win!") #since we know computer will always win, I don't have to do a check
playgame() #run the function
Here's a vastly more complicated function that does essentially the exact same thing ;-)
class Entity(object):
"""Base class that should not be instantiated on its own -- only
exists to be inherited from. Use Player() and Computer() instead"""
def __init__(self,name=None):
if name is None:
name = input("What's your name? ")
self.name = name
self.myturn = False
def __str__(self):
# this magic function means calling str(self) returns str(self.name)
# included so I can do print(player)
return self.name
def makemove(self,choice):
"""finds the global s and subtracts a given choice from it,
printing the choice and the result to the user."""
global s
s -= choice
print("{} chooses {}, leaving {}".format(self,choice,s))
return choice
def activate(self):
self.myturn = True
return self
def deactivate(self):
"""does exactly self.myturn = False"""
self.myturn = False
class Player(Entity):
"""A player-controlled Entity"""
def getchoice(self):
"""Prompts the user for a choice, ensuring it's between 1 and 6, then
calls Entity's makemove() with that as an argument"""
choice = None
while choice not in range(1,7):
choice = int(input("Pick a number between 1 and 6: "))
return super().makemove(choice)
class Computer(Entity):
def __init__(self):
super().__init__(name="Computer Player")
#overrides to ensure every Computer object has the name Computer Player
def getchoice(self):
"""grabs a number for the computer, and makes its move"""
global s
choice = s%7
if choice == 0: #edge case where computer goes first on an s where s%7==0
choice = random.randint(1,6)
return super().makemove(choice)
class Game(object):
"""Class defining an instance of the Game
FUNCTIONS:
Game.start() <-- use this to start the game"""
def __init__(self,playerArray=[]):
"""defines s as a global, ensures the players array is built
correctly, and gives s a random int value between 1-100"""
global s
if type(playerArray) is Player:
playerArray = [playerArray]
while len(playerArray) < 2:
playerArray.append(Computer())
self.players = playerArray
s = random.randint(1,100)
def start(self):
"""Let's play!"""
global s
print ("""
====================================
THE GAME BEGINS NOW!!!
We will begin with a value of: {:3}
====================================""".format(s).lstrip())
turn = random.randint(1,len(self.players))-1
while True:
try:active_player = self.players[turn].activate()
except IndexError: print(turn)
choice = active_player.getchoice()
if s <= 0: break
active_player.deactivate() # is active_player.myturn = False
turn += 1
if turn == len(self.players): turn = 0 #wrap the list
for player in self.players:
#this will execute the turn s becomes zero
if player.myturn:
winner = player
break
print("Winner: {}".format(winner))
import random
game = Game()
game.start()
S=random.randint(1,100) #will pick a random number
user_input = int(raw_input("Enter a number:")) #will get an integer from the user
#subtraction and modulo work just like in any other language ...
if(condition):
do_something() #is the format for if statements
does that cover all your questions? or did I miss some?

calling method outside class python

I'm relatively new to Python and OOP, I'm trying to write a mini adventure game with classes and have gotten stuck with my BattleEngine class.
The idea is to have options to fight or outwit an opponent based on your characters and the opponents 'strength' and 'wit'.
I get an error when I try to call my attack method here:
class Armory(Scene):
def enter(self):
print "This room appears to be some kind of armory. There are shelves full of weaponry lining"
print "the walls. You walk around admiring the shiny weapons, you reach out to pick up a"
print "massive battleaxe. Right as your fingers touch it you hear voices from behind the"
print "next door. They sound like they're getting closer. As the voices grow nearer you must make"
print "a decision. Will you stand and fight (enter 'fight') or will you use your wit to outsmart"
print "your opponent(enter 'wit')?"
decision = raw_input("> ")
battle = BattleEngine()
if decision == "fight":
attack(self, Player.strength, 3)
if player_wins:
print "A man in light armour walks in and sees you with your sword drawn. A look of"
print "shock and disbelief is on his face. You act quickly and lunge at him."
print "The soldier struggles to unsheath his sword as you run him through."
print "He collapses to the ground wearing the same look of disbelief."
print "Your strength has increased by 1."
Player.strength += 1
elif decision == "wit":
outwit(self, Player.wit, 3)
Here is where I defined my BattleEngine class:
class BattleEngine(object):
def attack(self, player_strength, nonplayer_strength):
player_roll = randint(1,6)
nonplayer_roll = randint(1,6)
if (player_roll + player_strength) >= (nonplayer_roll + nonplayer_strength):
return player_wins
else:
return 'death'
def outwit(self, player_wit, nonplayer_wit):
player_roll = randint(1,6)
nonplayer_roll = randint(1,6)
if (player_roll + player_wit) >= (nonplayer_roll + nonplayer_wit):
return player_wins
else:
return 'death'
Once I get to this point in my program is receive the error that : 'attack global name is not defined'
I'm not sure what I'm doing wrong exactly. Any help would be fantastic!
You need to call attack on your BattleEngine instance, and you do not need to pass in self:
battle = BattleEngine()
if decision == "fight":
player_wins = battle.attack(Player.strength, 3)
Note that you need to receive the return value of the .attack() method.
The same applies to the .outwit() method further on:
elif decision == "wit":
player_wins = battle.outwit(Player.wit, 3)
You probably need to fix the return values in the .attack() and .outwit() methods; instead of return player_wins and return 'death', return True or False perhaps.
The self parameter is taken care of for you by Python, and will refer to the specific BattleEngine instance.
Not that you really need classes here, your BattleEngine() class currently has no per-instance state, for example. You don't use self in any of the methods, because there is nothing on the instance to refer to.

Categories