My “Strategy Pattern” Strategy

EDIT: Sorry, I can’t seem to get my code to paste into this blog while keeping the spacing and indentation that I use in PyCharm. 😦

I’m not sure if I’m generalizing too much or not, but I saw an opportunity to utilize the strategy pattern by creating a few interfaces (classes) that implement shared, but different, behaviors for almost all of my animate classes. For instance, I currently have the following animate classes: Monster (subclasses: Godzilla, Mothra), People (subclasses: Civilian, Military), and Vehicles (subclasses: Battleship, Tank). Each class implements all of the following interfaces (with the exception being that Civilians don’t attack at all): MoveBehavior (different ways of moving around), AttackBehavior (different ways of attacking), and DeclareBehavior (different ways of talking or declaring themselves). Within each of those interfaces is different methods for achieving the actions of moving, attacking, and declaring (in an audible manner) themselves.

One thing I don’t really understand is how to implement my inanimates and locations. Being that we’re using OO programming my first instinct is to create a class for each so I ended up with the following classes:

Inanimates: Boat, Building, Tree

Locations: Ocean, City

Being that I don’t really know what else to do with these, I simply created a Display method in each class which prints a line of text saying what they are. The locations are meant to simply be backgrounds, as are the three inanimates, with the exception that I want the three inanimates (Boat, Building, Tree) to be destroyable by Godzilla either breathing fire or punching them.

This leads me to one issue with my AttackBehavior interface, I wanted to have two subclasses AttackFireBreath and AttackPunch that could both be utilized by Godzilla. I’m not sure if it’s possible to have Godzilla choose the appropriate behavior based on context if I’m using a simple interface. For instance in the Godzilla class (subclass of Monster) I currently just have self.attackBehavior = AttackFireBreath() but if I also implemented self.attackBehavior = AttackPunch() then how do I get him to choose between the two? Say I want him to breath fire at trees, boats, people but punch Mothra, battleships, buildings, and tanks. Can I do that with how I currently have the interface set up? Is it something that can be implemented by using the Observer pattern?

Here’s a copy of my current code:

__author__ = ‘jasonjkeller’

 
#interface for move behaviors
class MoveBehavior(object):
def move(self):
pass

class MoveWalk(MoveBehavior):
def move(self):
print “I’m walking around!”

class MoveRunAway(MoveBehavior):
def move(self):
print “I’m running away!”

class MoveFly(MoveBehavior):
def move(self):
print “I’m flying around!”

class MoveFloat(MoveBehavior):
def move(self):
print “I’m floating around!”

class MoveDrive(MoveBehavior):
def move(self):
print “I’m driving around!”

 
#interface for attack behaviors
class AttackBehavior(object):
def attack(self):
pass

class AttackFireBreath(AttackBehavior):
def attack(self):
print “I’m breathing fire at you!”

class AttackLaserBeam(AttackBehavior):
def attack(self):
print “I’m shooting a laser beam at you!”

class AttackPunch(AttackBehavior):
def attack(self):
print “I’m punching you!”

class AttackShootGun(AttackBehavior):
def attack(self):
print “I’m shooting my gun at you!”

 

 

#interface for declare behaviors
class DeclareBehavior(object):
def declare(self):
pass

class DeclareGodzilla(DeclareBehavior):
def declare(self):
print “Godzilla declares: ROOOAAAAAR!!!”

class DeclareMothra(DeclareBehavior):
def declare(self):
print “Mothra declares: BZZZzzz!!!”

class DeclareCivilian(DeclareBehavior):
def declare(self):
print “Civilian declares: Run for your life!!!”

class DeclareMilitary(DeclareBehavior):
def declare(self):
print “Military declares: Fire your weapons!!!”

class DeclareBattleship(DeclareBehavior):
def declare(self):
print “Battleship declares: Fire your battleship weapons!!!”

class DeclareTank(DeclareBehavior):
def declare(self):
print “Tank declares: Fire your tank cannon!!!”

 

# Monster superclass
class Monster(object):
moveBehavior = MoveBehavior()
attackBehavior = AttackBehavior()
declareBehavior = DeclareBehavior()
def setMoveBehavior(self, cb):
self.moveBehavior = cb

def setAttackBehavior(self, ab):
self.attackBehavior = ab

def setDeclareBehavior(self, yb):
self.declareBehavior = yb

def display(self):
pass

def performMove(self):
self.moveBehavior.move()

def performAttacks(self):
self.attackBehavior.attack()

def performDeclare(self):
self.declareBehavior.declare()

def isDead(self):
pass

class Godzilla(Monster):
“””a subclass of Monster”””
def __init__(self):

self.attackBehavior = AttackFireBreath()
self.moveBehavior = MoveWalk()
self.declareBehavior = DeclareGodzilla()

def display(self):
print “I’m Godzilla!!!”

class Mothra(Monster):
“””a subclass of Monster”””
def __init__(self):

self.attackBehavior = AttackLaserBeam()
self.moveBehavior = MoveFly()
self.declareBehavior = DeclareMothra()

def display(self):
print “I’m Mothra!!!”

 

 

# People superclass
class People(object):
moveBehavior = MoveBehavior()
attackBehavior = AttackBehavior()
declareBehavior = DeclareBehavior()
def setMoveBehavior(self, cb):
self.moveBehavior = cb

def setAttackBehavior(self, ab):
self.attackBehavior = ab

def setDeclareBehavior(self, yb):
self.declareBehavior = yb

def display(self):
pass

def performMove(self):
self.moveBehavior.move()

def performAttacks(self):
self.attackBehavior.attack()

def performDeclare(self):
self.declareBehavior.declare()

def isDead(self):
pass

class Civilian(People):
“””a subclass of People”””
def __init__(self):

self.moveBehavior = MoveRunAway()
self.declareBehavior = DeclareCivilian()

def display(self):
print “We’re just civilians!!!”

class Military(People):
“””a subclass of People”””
def __init__(self):

self.moveBehavior = MoveWalk()
self.attackBehavior = AttackShootGun()
self.declareBehavior = DeclareMilitary()

def display(self):
print “We’re the military!!!”

 
# Vehicle superclass
class Vehicle(object):
moveBehavior = MoveBehavior()
attackBehavior = AttackBehavior()
declareBehavior = DeclareBehavior()
def setMoveBehavior(self, cb):
self.moveBehavior = cb

def setAttackBehavior(self, ab):
self.attackBehavior = ab

def setDeclareBehavior(self, yb):
self.declareBehavior = yb

def display(self):
pass

def performMove(self):
self.moveBehavior.move()

def performAttacks(self):
self.attackBehavior.attack()

def performDeclare(self):
self.declareBehavior.declare()

def isDead(self):
pass

class Battleship(Vehicle):
“””a subclass of Vehicle”””
def __init__(self):

self.moveBehavior = MoveFloat()
self.attackBehavior = AttackShootGun()
self.declareBehavior = DeclareBattleship()

def display(self):
print “I’m a battleship!!!”

class Tank(Vehicle):
“””a subclass of Vehicle”””
def __init__(self):

self.moveBehavior = MoveDrive()
self.attackBehavior = AttackShootGun()
self.declareBehavior = DeclareTank()

def display(self):
print “I’m a tank!!!”

 
# inanimate classes
class Boat(object):
def Display(self):
print “I am an inanimate boat.”

class Building(object):
def Display(self):
print “I am an inanimate building.”

class Tree(object):
def Display(self):
print “I am an inanimate tree.”

class OceanBG(object):
def Display(self):
print “I am an Ocean location.”

class CityBG(object):
def Display(self):
print “I am a City location.”

Advertisements

One comment

  1. Pingback: Strategy Pattern TestDriver « jasonjkeller

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