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

Beginner attempt at a text adventure v2

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
beginnertextadventureattempt

Problem

Based upon feedback received in this post I've amended my game and would very much appreciate further feedback on it's current state(work in progress) and any suggestions on what I could implement in the future.

An @classmethod was introduced in Enemy() and these are completely new to me so a confirmation that all is correct with that would be very nice.

Code:

```
# A Countryside Adventure

#from adventureqmodule import *
from sys import exit
import random

def question(question, boolean = False, options = ["yes", "no"]):
"""
If boolean, returns True or False. Otherwise returns a string
regardless of type in options
"""
options = ["yes", "no"] if boolean else [str(option) for option in options]
while True:
print(question)
print("Options: {}".format(", ".join(options)))
response = input("Input: ").lower()
if boolean and response in ["y", "n"] + options:
return response[0] == "y"
if response in options:
return response
else:
print("That isn't a valid response.")

class Character(object):
"""A character in a fictional world"""

def __init__(self, name, health):
self.name = name
self.health = health
self.dead = False

def __str__(self):
rep = self.name + " has health: " + str(self.health)
return rep

def attack(self, other):
raise NotImplementedError

def take_damage(self, damage):
self.health -= damage

class Player(Character):
"""A player in a fictional world"""

def __init__(self, name, health = 10):
super(Player, self).__init__(name, health)
self.inventory = ["axe handle", "first aid kit"]
self.inventory_max = 2
self.strikes = {"headbutt" : 4 , "kick" : 3, "punch"\
: random.randrange(1, 4)}

def __str__(self):
rep = super(Player, self).__str__()
rep += "\nInventory: " + str(self.inventory)
r

Solution

I would use another nice python decorator, @property to make the check for dead easier:

class Character(object):
    ...
    @property
    def dead(self):
        return self.health <= 0
...
class Location(object):
    ...
    def battle(self, player, enemy):
        ...
        attacker, defender = enemy, player
        while True:
            attacker.attack(defender)
            if defender.dead:
                break
            print(defender)
            attacker, defender = defender, attacker
        action = "are killed by" if player.dead else "have defeated"
        print("You {} the {.name}!".format(action, enemy))


This means you can access player.dead like an attribute and on every access he will actually call player.dead() to check the health of the player. I also swapped around the checks, because if the player is dead it does not matter whether the enemy is also dead!

EDIT: I now transformed the while loop into an infinite loop of an attacker attacking a defender where the two roles are swapped around, starting with enemy attacking player. I also made the printing more generic, the two strings were quite similar.

Code Snippets

class Character(object):
    ...
    @property
    def dead(self):
        return self.health <= 0
...
class Location(object):
    ...
    def battle(self, player, enemy):
        ...
        attacker, defender = enemy, player
        while True:
            attacker.attack(defender)
            if defender.dead:
                break
            print(defender)
            attacker, defender = defender, attacker
        action = "are killed by" if player.dead else "have defeated"
        print("You {} the {.name}!".format(action, enemy))

Context

StackExchange Code Review Q#138751, answer score: 3

Revisions (0)

No revisions yet.