Assignment 8 – Integrating the Visitor Pattern

I was really able to make a lot of progress with my project this week, due in large part to the versatility of the visitor pattern. I finally got the attack ability to work via a key press as I wanted to, the only lingering issue with that is the concurrency issue I mentioned last week. When I attack, it switches Godzilla’s sprite to one shooting a fireball and I would like for it to reset after a few moments. This was not my focus for this week however.

I implemented three different uses for the visitor pattern in a Visitors.py module, two of which are working properly. The two that are working are AttackSpriteVisitor and DisplayVisitor.

DisplayVisitor simply visits each object after it has been attacked and prints out its current health. I would like each objects life to be displayed on the canvas and visually reflect the changes but I’m not entirely sure about how to achieve that at the moment.

The AttackSpriteVisitor switches each enemy’s sprite to an attacking sprite as they automatically strike back each time they’re attacked by Godzilla. In the case of inanimate objects, that obviously don’t retaliate, it simply switches their sprite to one that reflects the damage done by Godzilla’s attack. I’m really excited that I got this working as intended because I was able to successfully wrap my head around and implement the visitor pattern using reflection, which I was previously struggling to understand. Here’s how this was implemented:

class AttackSpriteVisitor(Visitor):
    """visitor class: """
    def __init__(self):
        super(AttackSpriteVisitor, self).__init__()

    def visit(self, node, *args, **kwargs):
        enemy = None
        for cls in node.__class__.__mro__:
            enemy_name = 'visit_' + cls.__name__
            enemy = getattr(self, enemy_name, None)
            if enemy:
                break

        if not enemy:
            enemy = self.visit_Generic
        return enemy(node, *args, **kwargs)

    def visit_Mothra(self, node, *args, **kwargs):
        # print('visit_Mothra ' + node.__class__.__name__)
        node.setSprite(Tk.PhotoImage(file='../resources/MothraLaserLeft.gif'))

    def visit_Military(self, node, *args, **kwargs):
        # print('visit_Military ' + node.__class__.__name__)
        node.setSprite(Tk.PhotoImage(file='../resources/militaryAttack.gif'))

    def visit_Tank(self, node, *args, **kwargs):
        # print('visit_Tank ' + node.__class__.__name__)
        node.setSprite(Tk.PhotoImage(file='../resources/tankAttack.gif'))

    def visit_Building(self, node, *args, **kwargs):
        # print('visit_Building ' + node.__class__.__name__)
        node.setSprite(Tk.PhotoImage(file='../resources/buildingFire.gif'))

    def visit_Tree(self, node, *args, **kwargs):
        # print('visit_Tree ' + node.__class__.__name__)
        node.setSprite(Tk.PhotoImage(file='../resources/treesFire.gif'))

    def visit_Generic(self, node, *args, **kwargs):
        pass

Finally, the DeathVisitor is the visitor that isn’t yet fully implemented. What I want is to have DeathVisitor visit an object after its health reaches zero and remove it from the world. I can’t quite wrap my brain around how to achieve this though. I’m trying to have it reach into GameWorld.py and call the GameWorld’s removeWorldObject() method. I’m getting hung up on how to refer to the game world though (the self it requires here: def removeWorldObject(self, oldObject)). Since the GameWorld is created in the driver at runtime I don’t have a reference to it to work with. Here’s what I currently have (where it passes in need_world_reference as an argument to visit() is what I’m having trouble with):

class DeathVisitor(Visitor):
    """visitor class: removes an object from the GameWorld when its health is zero"""
    def __init__(self):
        super(DeathVisitor, self).__init__()

    def visit(self, visitable):
        GameWorld.removeWorldObject(need_world_reference, visitable)

Assignment 7 Progress: The State Pattern

I was able to somewhat successfully incorporate the state pattern into my project this week. As of now it’s simply being used to change the image of the user controlled character, Godzilla. I created two states for Godzilla depending on whether he’s engage with an enemy or not. When he engages an enemy by calling his performAttack() method on them it will switch his state to the EngagedState which will cause his sprite to change to one where he’s shooting a fireball. I say that I was somewhat successful because I’ve encountered two stumbling blocks related to how I want the performAttack() method and state pattern to function.

The first issue, and really the only part of my use of the state pattern that isn’t working, is making the sprite change back to the not engaged sprite after an attack has been performed. I basically want the fire breathing sprite to be displayed for a few seconds when I perform an attack and then for it to change back to the notEngaged sprite (not breathing fire). I’ve tried, in numerous places throughout the chain of commands, to reset the state to notEngaged. It works, in that it does reset the state, but it does so instantaneously such that you never even see the fire breathing sprite displayed. I’ve tried using the sleep function imported from time, thinking that I could make it pause for a few seconds before resetting the sprite but so far that’s only had the effect of pausing the canvas from being displayed and then when it is the sprite has already been reset to notEngaged. My attack behaviors are implemented using the strategy pattern and are the final step in the chain of actions when I call performAttack(), thus they seem like a logical spot reset the the sprite to me. Here’s what I was trying to no avail (the two commented out lines):

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

The second issue is that I want the performAttack() method to be called with the press of a key. I was able to get this functionality working properly as far as binding the proper keys and having a keyPressHandler send instructions to the GameWorld to call the performAttack() method. What I’m getting stuck on is how to make it perform that attack on an actual enemy on the screen. My train of thought is that when the performAttack() method is called I somehow need to cycle through each object in the gameWorlds object list, test if any of them are within some defined attackRange, perform attack if they are, else pass. Testing the distance between them is what I haven’t successfully implemented yet; I’m attempting to do it using the provided getLocation() method (in GameWorld.py) and the distance() method imported into GameWorld.py from Locations.py. Here’s screenshot of the hybrid code/pseudocode I currently have for this (in GameWorld.py):

playerAttack

Week 6 – Refactoring

I’ve managed to refactor my Godzilla simulator taking advantage of the sample code and structure provided to us in our last lab. I’d be lying if I said I understood everything going on in the code that was provided, but I’ve got a decent grasp on the way things are structured both in the code and in the directory hierarchy provided. My biggest improvement is using the provided GameUnit class and having all of my other classes, both animates and inanimates, subclassing it. I was also able to finally get crude graphics implemented so that I can start to get some visual feedback on the things that are happening. Right now I just have various animate and inanimate objects being displayed on the canvas, but most actions are still being outputted as text. My enemy animates are currently using the random movement code provided while my main character Godzilla can be moved around the screen using the arrow keys. I  plan on also mapping his attack ability to a key press but I’m not completely sure how to achieve that at the moment.

GodzillaSimV2

I’ve starting planning out how to utilize the state pattern and I’ve hashed out a bit of code in a separate project to test it out. So far, so good but there are still some details I need to work out. I didn’t go overboard with this refactoring, as far as behaviors and interactions are concerned, because I already know I’m going to change a number of things with my use of the state pattern. I wasn’t far enough along with some of those ideas to implement them in time for this assignment though, so I opted to do some things in the refactoring that I know will change. The main thing is the way I’m currently making use of the strategy pattern to set/change behaviors will likely be completely overhauled when the state pattern is implemented. I’m also not currently making use of the decorator pattern and struggling a bit to make good use of it in my program. I was considering using it to maybe change the images dynamically (say change Godzilla to Godzilla with fireball when attacking, for example), but I’m not sure if it makes more sense or not to have images change using the state pattern (if Godzilla switched to an attackState).

Another thing that I’d like to have happen is for my destructible objects (both animate and inanimate) to appear randomly throughout the game world rather than having to create and place them in the driver. I really have no clue how this is achieved though, or if it’s reasonable for this project.

Overall I feel like I’m making some positive progress and maintaining a grasp on the program even though it keeps growing in complexity.

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

Porting the Observer Pattern to Python

Porting a simplified version of the Weather Observer program to Python proved to be pretty straight forward, especially since most of the classes and methods were already provided to us ported over. The one issue I initially encountered came when I tried to implement humidity into the display. My first thought was to simply copy the following method:

    def setTemperature(self, temperature):
        self.temperature = temperature
        self.notifyObservers()

and create another version for Humidity:

    def setHumidity(self, humidity):
        self.humidity = humidity
        self.notifyObservers()

I then would call each method in the driver to set a value using:

weatherData.setTemperature(78.0)
weatherData.setHumidity(30.0)

The problem with this was that as soon as the program got through the setTemperature method it would then notify the observers without running through the setHumidity method and the output would initially be 78.0 and None, rather than 78.0 and 30.0.

When I finally tracked down what was happening it occurred to me to make a single setMeasurements method as below:

    def setMeasurements(self, temperature, humidity):
        self.temperature = temperature
        self.humidity = humidity
        self.notifyObservers()
weatherData.setMeasurements(78.0, 30.0)

Once I implemented those changes the appropriate output was produced:

Current Conditions: 78.0F degrees and 30.0% humidity

Step-by-Step: Using the Observer Pattern

1. Create two interfaces: Observable and Observer.

2. The Observable interface should contain the following methods:

  • registerObserver() – registers Observers to receive updates
  • removeObserver() – removes Observers from receive updates
  • notifyObservers() - notify Observers of an updates using Push/Pull
  • setChanged() – Optional, but let’s you control what updates should be sent

3. The Observer interface should contain the following method:

  • update() – retrieves updated data from the Observable for Observers

Reflections on Using the Observer Pattern

I’m not sure I entirely grasp how to implement the observer pattern in my project as of yet, but I want virtually everything (except for the locations) to have the ability to interact amongst each other. My simulation, as previously noted, will be based around Godzilla rampaging through several locales in which he will be able to destroy inanimate objects such as buildings, trees, and boats and engage in battle with animates such as military, battleships, tanks, and Mothra. In each scenario there will need to be communication between objects about their position relative to each other. Godzilla in-particular will need to be updated with the status of these objects as each of them will be able to be destroyed/killed which should be Godzilla’s queue to move on. Conversely these objects will need to be updated when they are being attacked by Godzilla so that they know to fight back, die, or run away.