HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Suggestions for a Dungeons and Dragons-like game

Submitted by: @import:stackexchange-codereview··
0
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 – 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//5


to

strength_difference = strength1 - strength2
if strength_difference < 0:
    strength_difference = strength2 - strength1
strength_difference = strength_difference // 5


Next, 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 character


Note 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 = skill


Our 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 character


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

Code Snippets

strdif=str1-str2
if strdif<0:
    strdif=str2-str1
strdif=strdif//5
strength_difference = strength1 - strength2
if strength_difference < 0:
    strength_difference = strength2 - strength1
strength_difference = strength_difference // 5
player1 = 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 character
player1 = generate_character()
player2 = generate_character()

Context

StackExchange Code Review Q#45137, answer score: 16

Revisions (0)

No revisions yet.