Thoughts on Assignment 5

I feel like I’m understanding the syntax of Python (and that of Java) a lot better than I was just a few weeks ago. To me this has always been the biggest hurdle because I have no coding experience other than CIS 210 last term. I feel very comfortable with the concepts discussed in the book/class and I understand the design patterns just fine, but actually implementing things into code has always been a major hurdle for me, one that I finally feel I’m progressing past (to a small but noticeable extent).

Unfortunately, I feel that my code has become a bit of a mess and there’s a lot of things that I now understand better and would like to go back and address. I am finding that as I understand the technical aspects better, the way I envision my project keeps shifting (evolving hopefully) but in a way this is problematic because rather than moving forward I want to go back and fix things which is difficult due to time constraints.

I’m still struggling a bit with implementing the strategy pattern in a meaningful manner. I’ve got various “behavior” interfaces implemented for things such as attacking, moving, and having characters declare themselves (make a vocal announcement for the time being). I also created a HealthBehavior interface which allows any class that implements it to have access to methods that set their initial health and decrease health (if attacked). I didn’t feel that it was properly utilizing the strategy pattern though as the behavior types contained in it weren’t as generic as they should be. I set the HealthBehavior interface up a bit differently than the interfaces we created for our soldiers classes in lab. My confusion about the strategy pattern stems from the examples in lab where there was so little actually happening in the interfaces that it didn’t seem very useful to use them as well as the fact that much of what was in them seemed duplicated in the actually classes and subclasses that implemented them. So I initially tried to make HealthBehavior a bit more useful by reusing more code, but since I didn’t feel it was correct use of the strategy pattern I ended up scrapping it and moving to a more simplified health system. Here’s a snippet of the HealthBehavior interface code I initially had. Maybe you could provide some feedback on if it was a valid use of the strategy pattern or not?


class HealthBehavior(object):
 """interface for health behaviors"""
 def __init__(self):
 super(HealthBehavior, self).__init__()
 self.health = None

def setHealth(self):
 pass

def decreaseHealth(self):
 pass

class GodzillaHealth(HealthBehavior):
 """Godzilla's health behavior"""
 def __init__(self):
 super(GodzillaHealth, self).__init__()

def setHealth(self):
 self.health = 1000

def decreaseHealth(self):
 while self.health >= 10: ####DELETE THIS LINE
 print "Godzilla's health is " + str(self.health)
 self.health -= 10
 if self.health == 0:
 print "Godzilla is dead!"

class MothraHealth(HealthBehavior):
 """Mothra's health behavior"""
 def __init__(self):
 super(MothraHealth, self).__init__()

def setHealth(self):
 self.health = 100

def decreaseHealth(self):
 while self.health >= 10: ####DELETE THIS LINE
 print "Mothra's health is " + str(self.health)
 self.health -= 10
 if self.health == 0:
 print "Mothra is dead!"

And how it was actually implemented in a concrete class using self.healthBehavior.setHealth():


class Godzilla(Monster):
 """a subclass of Monster"""
 def __init__(self):
 super(Godzilla, self).__init__()
 self.attackBehavior = AttackFireBreath()
 self.moveBehavior = MoveWalk()
 self.declareBehavior = DeclareRoar()
 self.healthBehavior = GodzillaHealth()
 self.healthBehavior.setHealth()

There’s a few lines that needed to be deleted, as marked by comments, but I they were just there to test the decreaseHealth method. As I though about it, it seems to make more sense not to use the strategy pattern for health as it’s not really something that has a bunch of different versions or changes particularly (other than decreasing in value when attacked). I ended up switching it to the following which simply initializes each object with a value for self.health and uses the various attack interfaces to decrease the health of enemies.

class AttackBehavior(Observable, Observer):
"""interface for attack behaviors"""
 def attack(self, victim):
 pass

class AttackFireBreath(AttackBehavior):
 """breath fire attack behavior"""
 def attack(self, victim):
 victim.health -= 20
 self.notifyObservers()
 print "I'm breathing fire at you!"

class Godzilla(Monster):
 """a subclass of Monster"""
 def __init__(self):
 super(Godzilla, self).__init__()
 self.attackBehavior = AttackFireBreath()
 self.moveBehavior = MoveWalk()
 self.declareBehavior = DeclareRoar()
 self.health = 1000

I’m currently working on using the observer pattern to make it so Godzilla can attack a unit and it will use the decreaseHealth method to lower their health. I’m admittedly struggling a bit to get this to incorporate the observer pattern. I have an attack system working as shown above but I want it to happen automatically when Godzilla observes an enemy or destroyable inanimate object within range. I’m just not certain how to implement this at the moment. The main use I’m currently making of the observer pattern is having every object watch when Godzilla moves and having Godzilla watch when every object moves. One object moves and the other responds by readying them self to move. I’m really eager to get graphics implemented so that I can visually see how these things are interacting – I’m hoping to work on that over the next few days. I’ve already found some sprites that I’ll likely use for the final version. I want to have it be a top down isometric viewpoint of Godzilla rampaging through city and an ocean locations and encountering different animate and inanimate objects which he can destroy. I initially started off with the intentions of having it be a scripted world where you just observe what’s happening but I’m now toying with the idea of giving the user control of Godzilla’s moving directions and attack ability.

Here’s a simple driver making use of the observer pattern (Godzilla & Mothra observing each other moving, Godzilla attacking Mothra) and the strategy pattern (Godzilla’s firebreath attack gets changed to a punch attack and back to firebreath, Mothra’s health decreasing, both objects move behaviors).

def main():

 godzilla = Godzilla()
 mothra = Mothra()
 mothra.display()

godzilla.addObserver(mothra)
 mothra.addObserver(godzilla)

godzilla.planMove()
 godzilla.act()
 mothra.act()
 godzilla.performAttack(mothra)
 mothra.display()
 godzilla.performAttack(mothra)
 mothra.display()

godzilla.setAttackBehavior(AttackPunch())
 godzilla.performAttack(mothra)
 mothra.display()
 godzilla.display()
 mothra.performAttack(godzilla)

godzilla.display()
 godzilla.declareBehavior.declare()
 godzilla.act()

godzilla.setAttackBehavior(AttackFireBreath())
 godzilla.performAttack(mothra)
 mothra.display()
 godzilla.performAttack(mothra)
 mothra.display()
 godzilla.performAttack(mothra)
 mothra.declareBehavior.declare()
 mothra.display()

main()

And the output:

/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python /Users/jasonjkeller/PycharmProjects/GodzillaSim/GodzillaSimDriver.py
I'm Mothra!!! My health is 100.
Godzilla is planning to move.
I'm walking around!
Mothra is planning to move.
I'm flying around!
Godzilla is planning to move.
I'm breathing fire at you!
I'm Mothra!!! My health is 80.
I'm breathing fire at you!
I'm Mothra!!! My health is 60.
I'm punching you!
I'm Mothra!!! My health is 55.
I'm Godzilla!!! My health is 1000.
I'm shooting a laser beam at you!
I'm Godzilla!!! My health is 985.
ROOOAAAAAR!!!
I'm walking around!
Mothra is planning to move.
I'm breathing fire at you!
I'm Mothra!!! My health is 35.
I'm breathing fire at you!
I'm Mothra!!! My health is 15.
I'm breathing fire at you!
BZZZzzz!!!
Mothra is dead.

Process finished with exit code 0
Advertisements

One comment

  1. dellswor

    It’s common to realize part way through a project that there are much better ways to implement it… It’s extremely hard to understand a problem until after trying to solve it a few times. That you want to change a lot of your older code is a good thing, it indicates that you’re learning a lot about the problem you’re solving.
    I think the strategy pattern for health was probably a bad fit; I thing your newer representation for health is better. Strategies are about accomplishing something; so they’ll have some set of steps in them. Health is an attribute/value; there are no steps, it’s just a number.
    Regeneration strategies (where different regeneration strategies would refresh different amounts of health) might make sense. Each turn, the moster would add the amount of health returned by the regeneration strategies regenAmount() method. Maybe one strategy regenerates a lot but only lasts 10 turns and another strategy would only regenerate a little on alternating turns. The steps in the regenAmount() method might update some internal counter of the number of turns and then return some amount of health to be added by the moster based on that turn counter.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s