Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am trying to create a turn based rpg game in python. Currently i am using the list method to display and create individual values for each role. For example, the game allows player to setup a team of units for battle (minimum of 1 unit, default is 3). Each unit has a unique name and attributes like health point (HP), attack point (ATK), defence point (DEF), experience point (EXP) and a rank (default is level 1).
A unit can be either a Warrior, a Tanker or a Wizard whom have different strength in ATK and DEF point. In addition, a Wizard has special ability to cast spells that can impact friendly and enemy units (Heal, Poison, Cure, Freeze).
The suggested initial values for each unit’s attribute point are described in requirement details under Part A – Game Setup section.
The game will automatically setup either (1) player vs Artificial Intelligence (AI) or (2) two-player mode, of which both teams are made up of same number of units.
For AI team, the type of units will be assigned randomly or by specific AI algorithm. The name of units will be specified by the player, whereas AI unit names can be defined with prefix + random numbers (eg AI87). For two-player mode, each player will be able to go through the same unit selection process either through console or GUI.
For each turn, player can select an active friendly unit (non-frozen or dead) to perform an action on a target unit. Units which are severely damaged (i.e. HP equals to or less than 0) will be considered killed (or flagged as “dead”).
How do I use Object Oriented Programming method to create the 3 characters with input name for each team (can display the name keyed and the information of each character), instead of use list method.
#Menu page
print('Welcome to PSB Battle Game! \n(N)ew game\n(S)ave game\n(Q)uit')
def main():
selection = input('Choose your option then hit <ENTER> ==> ')
if selection.upper() == 'N':
new_game()
elif selection.upper() == 'S':
print('Loading save game...')
pass
elif selection.upper() == 'Q':
print('Exit game...')
pass
else:
print("I don't understand what are you typing.")
return main()
def new_game():
print('\nSetting up Player 1 team...\n')
name_list = []
for unit_name in range(1,4):
print(f'Enter a unique name for unit #{unit_name}-> ', end='')
name = input('')
repeated = False
while repeated:
if name == "":
continue
repeated = True
if name in name_list:
print('\nUnit name must be unique.\n')
return new_game()
if not name.strip():
print('\nUnit name could not be blank.\n')
return new_game()
else:
print('Name looks good!')
name_list.append(name)
print(f'Select unit #{unit_name}, type: (W)arrior, (T)anker, or Wi(Z)ard ==> ', end='')
role = input('')
if role.upper() == 'W':
print('Added ' + str(name_list))
warrior()
elif role.upper() == 'T':
print('Added ' + str(name_list))
tanker()
elif role.upper() == 'Z':
print('Added ' + str(name_list))
wizard()
else:
print("I don't understand what are you typing.")
return role()
def warrior ():
charac = [1,50,8,3,0,'True','False','False']
print ('\nWarrior Level 1: ','HP =',charac[1],',''ATK =',charac[2],',''DEF =',charac[3],',''EXP =',charac[4],',''ALIVE =',charac[5],',''POISONED =',charac[6],',''FROZEN =',charac[7])
print ()
def tanker ():
charac = [1,60,5,5,0,'True','False','False']
print ('\nTanker Level 1: ','HP =',charac[1],',''ATK =',charac[2],',''DEF =',charac[3],',''EXP =',charac[4],',''ALIVE =',charac[5],',''POISONED =',charac[6],',''FROZEN =',charac[7])
print ()
def wizard ():
charac = [1,40,3,2,0,'True','False','False']
print ('\nWizard Level 1: ','HP =',charac[1],',''ATK =',charac[2],',''DEF =',charac[3],',''EXP =',charac[4],',''ALIVE =',charac[5],',''POISONED =',charac[6],',''FROZEN =',charac[7])
print ()
main()
Your game is far from functional. I took the liberty of setting up a small sketch of a game after your design with battle functionality and character classes. From this code you can work forward to include other functionalities, such as chance, moving, changing skill points, and other stuff.
class Char:
def __init__(self, name = '', cclass = "Warrior", stats = [1,50,5,5,0,'True','False','False']):
self.c = cclass
self.name = name
self.stats = {'LVL':stats[0],
'HP':stats[1],
'ATK':stats[2],
'DEF':stats[3],
'EXP':stats[4],
'ALIVE':stats[5],
'POISONED':stats[6],
'FROZEN':stats[7]}
self.calc_level()
def __repr__(self):
outs = ''
outs+="Character Name: {0} of class {1}:\n---------------".format(self.name,self.c)
for k,v in self.stats.items():
outs+='\n {0}: {1}'.format(k,v)
return outs
def calc_level(self):
self.stats['LVL'] = int(self.stats['EXP']**.5)+1
def attack(self,other):
print("\n{0} furiously attacks {1} with {2} attack. {1} has {3} defense.".format(self.name,other.name,self.stats['ATK'],other.stats['DEF']))
if self.stats['ATK']>=other.stats['DEF']:
other.stats['HP'] -= self.stats['ATK']
print("\nThat was a hit! The HP of {0} is now {1}".format(other.name,other.stats['HP']))
else:
print("\nYou missed and only made him angrier!")
def new_char(existing):
cc = ''
accept = False
while not accept:
n = input("\nPlease input a new name: ")
accept = True
for c in existing:
if n == c.name:
accept = False
print("This name is taken, already")
while not cc in ['w','t','z']:
cc = input("\nPlease input a class, noble {0}. (W)arrior, (T)ank, Wi(z)ard: ".format(n)).lower()
cclasses = {'w':'Warrior','t':'Tank','z':'Wizard'}
newc = Char(n,cclasses[cc])
print('\nCharacter successfully created:')
print(newc)
return newc
def play(chars):
print("May the games begin. The following characters are present:\n")
for c in chars:
print(c)
print('')
game_over = False
turn = 0
while not game_over:
print("It's the turn of noble {0} {1}. Please select a player to attack:".format(chars[turn].c,chars[turn].name))
possible = []
for i in range(len(chars)):
if not i==turn:
possible.append(i)
print(" - ({0}): {1} named {2}".format(i,chars[i].c,chars[i].name))
sel = -1
while not sel in possible:
s = input('Selection: ')
try:
sel = int(s)
except:
print("That's not a valid choice")
chars[turn].attack(chars[sel])
if chars[sel].stats['HP']<=0:
game_over=True
print("That was it! {0} has died and the game is over.".format(chars[sel].name))
turn +=1
if turn==len(chars):turn=0
def main():
chars = []
entry = ''
print("Welcome to PSB Battle Game!")
while not entry.lower() in ['q','p']:
entry = input('\n(N)ew character\n(P)lay game\n(Q)uit\nSelection: ').lower()
if entry == 'p' and len(chars)<2:
print("\nYou can't play with only one character. Create characters first")
entry = '' ## You can't play with only one char
elif entry == 'n':
chars.append(new_char(chars))
entry = ''
elif entry == 'p':
play(chars)
elif entry == 'q':
print("\nOK, good bye")
main()
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Hey ya'll I'm brand new to python/programming and have been doing some online courses. I decided to take the day off of taking notes and such and try to challenge myself with some random while loops that simulate different things in dnd. I'm currently stuck on my simulated combat, and I know I'm on the right track but obviously it's not working. Some pointers would be much appreciated.
import random
monster_hp = 25
strength = 5
ac = 17
hp = 25
combat = True
current_hp = monster_hp
dmg = 0
hit = False
def roll_to_hit(hit, ac):
hit = random.randint(1, 20)
return hit
if hit >= ac:
return True
# print(roll_to_hit(hit))
def roll_4_dmg(dmg, strength):
dmg = random.randint(1, 10) + strength
return dmg
print(f"You hit and did {dmg} damage.")
# print(roll_4_dmg())
def damage(current_hp, monster_hp, dmg):
current_hp = monster_hp - dmg
return current_hp
# print(damage())
while combat:
if current_hp > 0:
inp = input(r"A monster has appeared what will you do? ").lower()
if inp == "attack":
roll_to_hit(hit, ac)
if True:
roll_4_dmg(dmg, strength)
damage(current_hp, monster_hp, dmg)
else:
print("You missed!")
inp = input(
r"A monster has appeared what will you do? ").lower()
else:
print("You have slain the beast!")
break
Ok so there are a lot of problems with your code and I will try going through them one-by-one.
In your first function -
def roll_to_hit(hit, ac):
hit = random.randint(1, 20)
return hit
if hit >= ac:
return True
The moment you return hit the function is going to end and will not check the hit against the AC. And you dont need to pass in hit as an argument. What I think you were looking for was something more like this -
def roll_to_hit(ac):
hit = random.randint(1, 20)
if hit >= ac:
return True
return False
Your second function as a similar problem where you return a value and then try to execute another command. It also takes in an unnecessary argument dmg. It should look more like this -
def roll_4_dmg(strength):
dmg = random.randint(1, 10) + strength
print(f"You hit and did {dmg} damage.")
return dmg
Your third function is fine apart from the unused argument current_hp it can simply be -
def damage(monster_hp, dmg):
current_hp = monster_hp - dmg
return current_hp
Now in your combat loop there are a whole lot of errors mainly due to the fact that you don't seem to be storing/using the values returned from your functions (I highly recommend you read up on how functions are expected to work in python) From my understanding of what you are trying to achieve here is what I think you were going for -
while current_hp > 0:
inp = input(r"A monster has appeared what will you do? ").lower()
if(inp == "attack"):
if(roll_to_hit(ac)):
damage_done = roll_4_dmg(strength)
current_hp = damage(current_hp, damage_done)
else:
print("You missed!")
print("You have slain the beast!")
Frankly its a pretty good effort for someone new to programming, you need to read up on how stuff stored in variables actually changes (given your extra arguments in the functions I have a feeling there a slight misunderstanding there)
*Also on a different note, your roll_to_hit function is only going to 'hit' 15% of the time as it is right now so it might take a few 'attack' rolls to test out the program
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm made a program that calculates the current health of a player and switches between them. I need help switching between players. This is what i have so far:
class Player():
def turn(life):
players = ['Player 1', 'Player 2']
life = 100
for player in players:
while life >= 0:
print (life)
print ("+, -, or end turn")
choice = input("> ")
if choice == "+":
print ("Damage taken")
healing = int(input("> "))
life += healing
elif choice == "-":
print ("Damage taken")
damage = int(input("> "))
life -= damage
elif choice == "end turn" or "end":
return
else:
print ("You lose!")
play = Player()
play.turn()
I've been in a similar position before. I would recommend doing something a bit different than the answer you might be looking for. Instead of looking for a solution to this individual problem, I would recommend looking at resources for game design patterns.
While I think that the learning curve might be a bit high initially, I think that if you learn to work with proper design patterns for game mechanics, you will find it much easier to build what you are after.
There are a few different resources that you can choose from. I used http://gameprogrammingpatterns.com/ (I have no association with this individual), but I also have a background in c++. I would look around for what might be the most intuitive for you and give it a try.
All the best!
Here is a start:
class Player:
def __init__(self, name, health=100):
self.name = name
self.health = health
def hit(self, n):
assert n >= 0
self.health -= n
def heal(self, n):
assert n >= 0
self.health += n
#property
def is_dead(self):
return self.health <= 0
class Game:
def __init__(self):
self.players = [Player("Adam"), Player("Bert")]
def turn(self, me, him):
# fill this in!
def play(self):
a, b = self.players
while True:
self.turn(a, b)
if b.is_dead:
print("{} won!".format(a.name))
break
else:
# swap players
a, b = b, a
if __name__ == "__main__":
Game().play()
Absolute beginner here, trying to make a simple coin toss game to practice the first couple of chapters I've read. I tried to add a score board to the game but the score is constantly stuck at 0 to 0. also any other tips would be appreciated as well. I don't know anyone that programs so I could use the advice.
"""This will be an attempt to create a simple
coin toss game in which the player chooses heads or
tails and a random generator will pick one from a list
of either heads or tails and return whether or not
the player chose correctly. I also hope to
create a scoreboard"""
from random import randint
coin = ['heads' , 'tails']
side = coin[0]
guess = 'heads'
token = int(raw_input('how many games?'))
wins = 0
losses = 0
def getinfo(token):
guess = raw_input('Heads or Tails?')
def flipcoin(guess, side, wins, losses):
side = coin[randint(0,1)]
print 'You Chose: %s' %(guess)
print 'Coin Is: %s' %(side)
if guess == side:
print 'you win'
wins = wins + 1
else:
print 'you lose'
losses = losses + 1
def main(token):
while token > 0:
getinfo(token)
flipcoin(guess, side, wins, losses)
if wins > losses:
print "You are winning %s to %d" %(wins , losses)
elif wins == losses:
print "You are tied %s to %d" %(wins , losses)
else:
print "You are losing %s to %d" %(losses, wins)
token -= 1
print '%d games left' %(token)
print 'wins: %s' %(wins)
print 'losses: %s' %(losses)
main(token)
Your problem is that the variables are declared at "module scope", outside the functions, and then you try to modify them from inside the functions.
Instead of modifying the module-scope variables, the functions are creating their own local variables.
One way to solve the problem is to add global declarations for the variables.
Use of "global" keyword in Python
Another, possibly better, way is to put the variables in a class, like so:
class GameState(object):
def __init__(self):
self.wins = 0
self.losses = 0
state = GameState()
# later, in code:
state.wins += 1 # for a win
Global variables make a program messy and hard to figure out. You can improve the program by putting them together in a class. You can improve the program even more by making the connections explicit: add arguments to your functions where you pass in the class instance for the functions to modify, instead of having one instance at module level.
Other answers are suggesting just moving the variables into main(). That's a valid approach as well, especially for a small and simple program like this one. My preference for packing all the variables together into a class comes from my experience with small programs growing into larger programs over time. If you keep related things together it makes it easier to scale up a program. But for this program, just putting the variables into main() is fine.
As mentioned already, you should be returning in your functions. Limit the use of global variables.
"""This will be an attempt to create a simple
coin toss game in which the player chooses heads or
tails and a random generator will pick one from a list
of either heads or tails and return whether or not
the player chose correctly. I also hope to
create a scoreboard"""
from random import randint
coin = ['heads' , 'tails']
def getinfo(token):
return raw_input('Heads or Tails?')
def flipcoin(guess, side, wins, losses):
side = coin[randint(0,1)]
print 'You Chose: %s' %(guess)
print 'Coin Is: %s' %(side)
if guess == side:
print 'you win'
wins = wins + 1
else:
print 'you lose'
losses = losses + 1
return side, wins, losses
def main():
token = int(raw_input('how many games?'))
wins = 0
losses = 0
side = coin[0]
guess = 'heads'
while token > 0:
guess = getinfo(token)
side, wins, losses = flipcoin(guess, side, wins, losses)
if wins > losses:
print "You are winning %s to %d" %(wins , losses)
elif wins == losses:
print "You are tied %s to %d" %(wins , losses)
else:
print "You are losing %s to %d" %(losses, wins)
token -= 1
print '%d games left' %(token)
print 'wins: %s' %(wins)
print 'losses: %s' %(losses)
if __name__ == '__main__':
main()
Your "guess, side, wins, losses" variables are globals, so you shouldn't be passing them into the "flipcoin" function. Doing this creates new local variables with the same name, and the global ones are never updated.
If you change these lines, it seems to work:
def flipcoin():
global wins, losses
side = coin[randint(0,1)]
print 'You Chose: %s' %(guess)
print 'Coin Is: %s' %(side)
if guess == side:
print 'you win'
wins = wins + 1
else:
print 'you lose'
losses = losses + 1
def main(token):
while token > 0:
getinfo(token)
flipcoin()
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
hi I have made a game in python were you need to input the specified number before the time runs out. I want to be able to save the top 5 high scores and display them at the end. i have surfed the web looking for solutions but being a amateur at python, I just cant tailor them to my coding. I want to save the name and the score preferably on one line using \t to separate them.
any answers would be much appreciated.
the game:
# number press game
import time
import random
print "Welcome to my Number Press Game"
print "the computer will display a number"
print "you will have to enter the number before the time runs out"
name = raw_input ("please enter your name: "+"\n")
print "\n"+"welcome to the game "+name
print "ready"
time.sleep (1)
print "steady"
time.sleep (1)
print "GO!"
#game
loop = -1
t = 3
while True:
loop = loop+1
x = random.randint(1,3)
print x
start = time.time()
num = input("the number is: ")
end = time.time()
elapsed = end - start
if elapsed > t and num == x:
print "CORRECT, but too slow"
break
elif num != x and elapsed < t:
print "\n"+"WRONG, but in time"
break
elif num != x and elapsed > t:
print "WRONG and too slow"
break
if num == x and elapsed< t:
print "CORRECT and in time"
if t>0.7:
t =t*0.9
print "you loose"
print name+" scored: "+str(loop)
Run this and see if it gives what you have in mind: This runs simulates playing the game n number of times. Then the highest scores is printed out as a list of all scores. Right here I have used y = 5, if you need 5 highest scores, I presume you need to play the game at least 5 times then the scores compared and the highest values printed as your highest scores: in the for loop. The highest_scores is then sorted to pick out the n highest scores you require. That said, you should review your logic it seems to be problematic. vote the answer if it helps. Cheers
import time
import random
high_score = []
def play_game():
print "Welcome to my Number Press Game"
print "the computer will display a number"
print "you will have to enter the number before the time runs out"
name = raw_input ("please enter your name: "+"\n")
print "\n"+"welcome to the game "+name
print "ready"
time.sleep (1)
print "steady"
time.sleep (1)
print "GO!"
loop = -1
t = 3
score = 0
while True:
loop = loop+1
x = random.randint(1,3)
print x
start = time.time()
num = input("the number is: ")
end = time.time()
elapsed = end - start
if elapsed > t and num == x:
print "CORRECT, but too slow"
break
elif num != x and elapsed < t:
print "\n"+"WRONG, but in time"
break
elif num != x and elapsed > t:
print "WRONG and too slow"
break
if num == x and elapsed< t:
print "CORRECT and in time"
score += 1
if t>0.7:
t = t*0.9
high_score.append(score)
print "you loose"
print name + " scored: "+ str(score)
print "All highest_scores =", high_score
highest_scores = sorted(high_score, reverse = True)
print "All highest_scores =",highest_scores[0:3]
y = 5
for i in range (y):
play_game()