patternpythonModerate
Suggestions for a Dungeons and Dragons-like game
Viewed 0 times
dragonsandlikedungeonsgameforsuggestions
Problem
This game is similar to a Dungeons and Dragons game. How could I improve the efficiency of the program? For example, where can I add functions, records etc? This is for a school Controlled Assessment so any help would really be appreciated.
import random
play1 = True
str1 = int(input("Enter a value for strength"))
print("you have chosen",str1,)
skl1=int(input("Please enter a value of skill, and then press enter"))
print("you have chosen: ",skl1,)
str2 =int(input("Enter a value for strength"))
print("you have chosen: ",str2,)
skl2=int(input("Please enter a value of skill, and then press enter"))
print("you have chosen: ",skl2,)
strdif=str1-str2
if strdifnum2:
str1+=strdif
skl1+=skldif
str2-=strdif
skl2-=skldif
if num2>num1:
str2+=strdif
skl2+=skldif
str1-=strdif
skl1-=skldif
if skl1 str2:
print("Character 1 won the encounter, now has",str1,"strength and",skl1,"skill")
print("Character 2 lost the encounter, now has",str2,"strength and",skl2,"skill")
else:
print("Character 2 won the encounter, now has",str2,"strength and",skl2,"skill")
print("Character 1 lost the encounter, now has",str1,"strength and",skl1,"skill")Solution
There are two huge improvements you can make to increase readability of your code:
-
Choose better names for some variables –
-
Put whitespace around operators rather than trying to write your code as compact as possible. For example, change
to
Next, there are a number of small issues that could be improved:
-
-
When calculating the differences of strength and skill, you could use the
-
You roll two random numbers from 1–6, then compare whether they are greater or smaller than each other. Instead, we could directly figure out the probabilities:
which means we only have to roll one value from 1–12
-
Instead of naming our variables
This looks more verbose, but allows us to remove a lot of duplication in a minute.
-
We can stuff the character initialization into a function that returns a player dictionary:
Note that I use
We can then initialize the players like this:
Because all info about a player is conveniently bundled, we can do neat stuff like this:
which sorts the players by their strength. This simplifies printing out the stats at the end of a round:
Using dictionaries for this is easy, but awkward. Instead we could write a class that represents characters, and create one instance of this class for each player:
Our
If we combine all these points (and a few other minor quibbles), we might end up with something like the following code:
```
import random
class Character:
def __init__(self, name, strength, skill):
self.name = name
self.strength = strength
self.skill = skill
def hit(self, other):
strength_difference = abs(self.strength - other.strength)
self.strength += strength_difference
other.strength = max(0, other.strength - strength_difference)
skill_difference = abs(self.skill - other.skill)
self.skill += skill_difference
other.skill = max(0, other.skill - skill_difference)
def generate_character():
name = raw_input("name: ")
strength = int(input("strength: "))
skill = int(input("skill: "))
character = Character(name, strength, skill)
print("Your character is %s (strength: %d, skill: %d)" % (character.name, character.strength, character.skill))
return character
def run(player1, player2):
while True:
print("Encounter!")
roll = random.randint(1, 12)
if roll <= 5:
player1.hit(player2)
elif roll <= 10:
player2.hit(player1)
else:
pass # draw
if player1.strength <= 0:
print("%s won the game" % player1.name)
return
if player2.s
-
Choose better names for some variables –
skill1 is better than skl1, and strength2 is better than str2 (str usually means “string”, which adds even more confusion). play1 should be play or play_on.-
Put whitespace around operators rather than trying to write your code as compact as possible. For example, change
strdif=str1-str2
if strdif<0:
strdif=str2-str1
strdif=strdif//5to
strength_difference = strength1 - strength2
if strength_difference < 0:
strength_difference = strength2 - strength1
strength_difference = strength_difference // 5Next, there are a number of small issues that could be improved:
-
while play1 == True could be abbreviated to while play1. However, setting a variable to False in order to exit a loop isn't very elegant: You could break out of the loop instead, or put the loop into a function from which you can return.-
When calculating the differences of strength and skill, you could use the
abs function instead: strength_difference = abs(strength1 - strength2) // 5.-
You roll two random numbers from 1–6, then compare whether they are greater or smaller than each other. Instead, we could directly figure out the probabilities:
- 2/12: draw
- 5/12: player 1 deals a blow
- 5/12: player 2 deals a blow
which means we only have to roll one value from 1–12
-
Instead of naming our variables
foo1 or foo2, let's create dictionaries that hold variables for each player:player1 = dict()
player1["name"] = "Character 1"
player1["strength"] = ...
player1["skill"] = ...This looks more verbose, but allows us to remove a lot of duplication in a minute.
-
We can stuff the character initialization into a function that returns a player dictionary:
def generate_character():
character = dict()
character["name"] = raw_input("name: ")
character["strength"] = int(raw_input("strength: "))
character["skill"] = int(raw_input("skill: "))
print("Your character is %s (strength: %d, skill: %d)" % (character["name"], character["strength"], character["skill"]))
return characterNote that I use
raw_input instead of input, as this avoids executing the input as if it were code.We can then initialize the players like this:
player1 = generate_character()
player2 = generate_character()Because all info about a player is conveniently bundled, we can do neat stuff like this:
(loser, winner) = sorted((player1, player2), key = lambda player: player["strength"])which sorts the players by their strength. This simplifies printing out the stats at the end of a round:
for player, status in [(winner, "won"), (loser, "lost")]:
print("%s %s the encounter, now has %d strength and %d skill" %
(player["name"], status, player["strength"], player["skill"]))Using dictionaries for this is easy, but awkward. Instead we could write a class that represents characters, and create one instance of this class for each player:
class Character:
def __init__(self, name, strength, skill):
self.name = name
self.strength = strength
self.skill = skillOur
generate_character changes to this:def generate_character():
name = raw_input("name: ")
strength = int(raw_input("strength: "))
skill = int(raw_input("skill: "))
character = Character(name, strength, skill)
print("Your character is %s (strength: %d, skill: %d)" % (character.name, character.strength, character.skill))
return characterIf we combine all these points (and a few other minor quibbles), we might end up with something like the following code:
```
import random
class Character:
def __init__(self, name, strength, skill):
self.name = name
self.strength = strength
self.skill = skill
def hit(self, other):
strength_difference = abs(self.strength - other.strength)
self.strength += strength_difference
other.strength = max(0, other.strength - strength_difference)
skill_difference = abs(self.skill - other.skill)
self.skill += skill_difference
other.skill = max(0, other.skill - skill_difference)
def generate_character():
name = raw_input("name: ")
strength = int(input("strength: "))
skill = int(input("skill: "))
character = Character(name, strength, skill)
print("Your character is %s (strength: %d, skill: %d)" % (character.name, character.strength, character.skill))
return character
def run(player1, player2):
while True:
print("Encounter!")
roll = random.randint(1, 12)
if roll <= 5:
player1.hit(player2)
elif roll <= 10:
player2.hit(player1)
else:
pass # draw
if player1.strength <= 0:
print("%s won the game" % player1.name)
return
if player2.s
Code Snippets
strdif=str1-str2
if strdif<0:
strdif=str2-str1
strdif=strdif//5strength_difference = strength1 - strength2
if strength_difference < 0:
strength_difference = strength2 - strength1
strength_difference = strength_difference // 5player1 = dict()
player1["name"] = "Character 1"
player1["strength"] = ...
player1["skill"] = ...def generate_character():
character = dict()
character["name"] = raw_input("name: ")
character["strength"] = int(raw_input("strength: "))
character["skill"] = int(raw_input("skill: "))
print("Your character is %s (strength: %d, skill: %d)" % (character["name"], character["strength"], character["skill"]))
return characterplayer1 = generate_character()
player2 = generate_character()Context
StackExchange Code Review Q#45137, answer score: 16
Revisions (0)
No revisions yet.