[Edu-sig] Simple game framework

kirby urner kirby.urner at gmail.com
Sat May 10 17:05:44 CEST 2008


"""

Tiny game framework, using a maze of rooms
randomly populated with mentors.  There might
be treasure in one of them.

K. Urner
4D Solutions
May 10, 2008

Basic idea....

class Mentor:

    '''
    Gatekeeper, gets in the way with
    a dumb question
    '''
    pass

class Hero:

    '''
    a star is born
    '''
    def __init__(self, name):
        self.name = name

class Maze:
    pass

class Room:
    pass

class Game:

    def __init__(self):
        '''
        get a maze of interconnected
        rooms, maybe with treasure,
        welcome hero to the game
        '''

    def run(self):
        '''
        loop through turns until treasure
        found or hero runs out of time
        '''

    def turn(self):
        '''
        some turn mechanism, advancing us
        from start to finish
        '''

To start:

>>> from sgf import Game

>>> thegame = Game()
>>> thegame.run()

"""

from random import choice

class Mentor:

    '''
    Gatekeeper, gets in the way with
    a dumb question.  Of course you might
    want a lot more variety, consider
    subclassing options
    '''

    def __init__(self, myquestion, myanswer,
                 reward = 1, punishment = -1):

        self.q = myquestion
        self.a = myanswer
        self.r = reward
        self.p = punishment

    def check(self, usersays):
        if usersays == self.a:
            print "Rewarding with " + str(self.r)
            return self.r
        else:
            print "Punishing with " + str(self.p)
            return self.p

class Hero:

    '''
    a star is born
    '''

    def __init__(self, name):
        # we're keeping it simple, but remember this
        # is just a framework to give you ideas
        self.name = name
        self.vitality = 10
        self.lifeclock = 15

    def stats(self):
        print "%s's stats: Vitality: %s  Lifeclock: %s" % (self.name,
                                        self.vitality, self.lifeclock)

class Room:

    def __init__(self, name):
        self.name = name
        self.has_treasure = False
        self.has_mentor = False

    def __repr__(self):
        return self.name

# ============= GLOBALS ========================
"""
You can build a maze using generic names like
Lobby, but then give a different flavor to the
game when defining what the Room tells the
user -- what we accomplish in the specialrooms
dictionary
"""

specialrooms = {"Lobby":Room("Gang Plank"),
                "Kitchen":Room("Galley"),
                "Den":Room("Captain's Quarters"),
                "Bathroom":Room("Head"),
                "Safe":Room("Treasure Chest")}

# Getting more creative with the questions would
# make for a funner game

thementors = [Mentor("2+2? ","4",
                     reward = 2,
                     punishment = 7),
              Mentor("Capital of Oregon ","Salem",
                     punishment = -5),
              Mentor("5*5? ","25"),
              Mentor("Python fits your brain? ","Yes sir!",
                     punishment = 5), # trick question
              Mentor("Are we having fun yet? ","Yes",
                     reward = 10),  # wow, lots of vitality
              Mentor("Is fast food good for you?",
                     "Not usually", # who would guess this?
                     reward = 3,
                     punishment = 5)]

# =========== END GLOBALS ========================

class Maze:

    """
    Interconnects rooms and keeps track of which is
    occupied.  No access to hero from this class.

    depends on specialrooms global (above)
    defines a layout (hardwired here, but randomizable
    with some work)

    Note there may be no treasure anywhere in the
    Maze, so you can't win no matter what, just wait
    out your life clock and die a loser, oh well.
    Very pre-destined in flavor, feel free to change.
    """

    def __init__(self):

        # got treasure?
        specialrooms['Safe'].has_treasure = choice([True, False])

        # map names like Kitchen give us a generic view, with
        # specialrooms used to customize (provide a theme, skin)
        self.layout = {"Lobby":["Kitchen","Bathroom"],
                       "Kitchen":["Lobby","Den"],
                       "Den":["Kitchen","Bathroom"],
                       "Bathroom":["Safe","Den"],
                       "Safe":["Bathroom","Bathroom"]}

        # populate with random mentors
        for i in range(len(self.layout)//2):
            somementor = choice(thementors)
            someroom = choice(specialrooms.keys())
            specialrooms[someroom].has_mentor = True
            specialrooms[someroom].mentor = somementor

        self.mapkey = "Lobby"
        self.thisroom = specialrooms[self.mapkey]
        print self.thisroom

    def getroom(self):
        '''
        take us to a next room -- what?  Doesn't the user
        get to choose?  This would be a good place to
        get some raw_input don't you think?
        '''
        self.mapkey = choice(self.layout[self.mapkey])
        self.thisroom = specialrooms[self.mapkey]

class Game:

    def __init__(self):
        '''
        get a maze of interconnected
        rooms, maybe with treasure,
        welcome hero to the game
        '''
        self.themaze = Maze()
        print "Welcome to the game."

    def run(self):
        '''
        loop through turns until treasure
        found or hero runs out of time
        '''
        myname = raw_input("What is the name of your Hero? ")
        self.hero = Hero(myname)

        while self._turn():
            self.themaze.getroom()

    def _turn(self):
        '''
        some turn mechanism, advancing us
        from start to finish
        '''
        print

        print "Location: " + str(self.themaze.thisroom)

        print

        self.hero.stats()

        if self.themaze.thisroom.has_mentor:
            print "Oh oh, a mentor!"
            thementor = self.themaze.thisroom.mentor
            ans = raw_input(thementor.q)
            self.hero.vitality += thementor.check(ans)
        else:
            print "No mentor here, whew."

        self.hero.lifeclock -= 1

        self.hero.stats()

        if self.hero.vitality <= 0:
            print "No more vitality.\nG A M E  O V E R"
            return False

        if self.hero.lifeclock <= 0:
            print "Time limit reached.\nG A M E  O V E R"
            return False

        if self.themaze.thisroom.has_treasure:
            print "Treasure found!\nY O U  W I N ! !"
            return False

        else:

            print "Onward!"
            return True

if __name__ == '__main__':
    thegame = Game()
    thegame.run()


More information about the Edu-sig mailing list