Since my last post I’ve been working on a simple RPG-like game as a project for LightCastle. It’s definitely in its infancy, but I’m gonna go out on a limb here and say it has the potential to be HUGE! … Ok, that may just be me getting over-excited. But here’s the gist of the game so far: you have a character that you can equip with different weapon and armor loadouts, you can buy and sell equipment, and make your character go to the arena to fight. Eventually I’d like to have it so that you can fight other *real* people over a network, but to start off, once you enter the arena, you’ll be faced with opponents of various sorts, from simple creatures to humanoids. I’d also like to create some sort of level-up system so that you can improve your stats and your enemies get stronger as you progress, maybe even including some kind of magic system one day. All that is for down the road, though.

For now, we’ll discuss some more about classes that I’ve learned. As this is largely an extension of a previous post, it probably won’t be too long or complex. But here goes. The first class I created is the Die (as in “dice,” not as in “mortally wounded”) class. It’s a basic class that starts with an empty array (“list” in python) of values. It has a single method, the “roll” method, which takes 2 arguments: the number of dice you want to roll, and the number of sides those dice will have (i.e., 4 dice with 6 sides each). Here’s the code:

[sourcecode language=”python”]
class Die:

def __init__(self):
myclass=’this is the die roll class’
self.myrolls=[]

def __str__(self):
return ‘Dieroll’
def __repr__(self):
return ‘Dieroll’
def roll(self, dice, sides):
for x in self.myrolls:
self.myrolls.remove(x)
self.total=0
for x in range(1, dice+1):
self.myrolls.append(random.randrange(1, sides))
for x in self.myrolls:
self.total+=x
print x,
return
[/sourcecode]

The first thing the roll method does is remove anything held in the array of rolls already. This is so you can use the same instance of the Die class to roll new numbers; it’ll just clear out the old data. The next statement creates a variable called “total” and initializes its value to 0. Then the program creates a random number (it’s actually a pseudorandom number, but close enough) within range of how many sides the dice have. It does that X times, X being how many dice you specify when you call the roll method. Then the program goes through the array and adds all the numbers together to get the total value. I did that so that you could save each roll to see individual values if you need to for some reason.

Getting Jiggy With It

So Die was a pretty simple class. The most complicated one I’ve created is probably the Player class because it has the most methods. But my favorite is the Equipment class. Here’s the code for it:

[sourcecode language=”python”]

class Equipment:
def __init__(self, attack_value, defense_value, name, description, is_armor, buy_value, sell_value):
self.is_armor=is_armor
self.name=name
self.description=description
self.attack_value=attack_value
self.defense_value=defense_value
self.buy_value=buy_value
self.sell_value=sell_value

def __str__(self):
return self.name
def __repr__(self):
return self.name

def attack(self):
return str(self.attack_value)
def defend(self):
return str(self.defend_value)
[/sourcecode]

I like this class because it has a lot of arguments, which gives you a lot of flexibility in creating equipment. The first one is the obligatory “self” parameter (which is a standard, and always references the instance of the object. While it doesn’t HAVE to be named “self,” standard practice calls for that as the variable name). The other argument-variables are pretty self-explanatory, but they are handy because you can create both armor and weapons from the same class. For armors you just set the attack value to 0, and for weapons you set the defense value to 0 (unless you want some weapons to have a marginal defense value for blocking purposes, etc). The is_armor check is used by the equip() function (that is not shown here) to determine whether you already have armor on or not. After all, wearing more than one set of armor would be pretty ridiculous ….  Anyway, buy_value and sell_value are used in the buy() and sell() functions to add or subtract the proper amount of gold from your stash. The __repr__ function is a pretty handy little thing I found that allows the program to reference an instance of an object by the variable you assign it (or a description or whatever you tell it to return. I used “return self.name”, making it return the instance name). This is in contrast to some crazy talk like “instance of class Equipment at [hard drive location].” That took me a little searching on the web to find out how to do, but it’s a handy little trick everybody should know. I think the __str__ has a similar function, though to be honest, I haven’t tested extensively to see what they do. The lesson from this one? Arguments are your friend!

So to create a longsword, here’s what I did:

“longsword=Equipment(10, 0, “long sword”, “A bad-ass slayer of women and small men”, False, 50, 15)”

Now, every time you do something with the variable “longsword,” you refer back to that set of data (called attributes). So if you do “print longsword.attack()”, you’ll get the value “10” returned because that’s what that method is set to do. (I’ll probably change the attack_values to be the number of dice it uses in its attack or something, so there can be a little variation on how much each attack does. While that’s a simple change, I’ve just been busy making other aspects of the game, and haven’t gotten to it yet.)