Friday, April 18, 2008

Programming Mana Cost 2

No picture, some random internal error. Computer programming is all about breaking a big problem into smaller, easier ones. "Divide and Conquer" Skip the first paragraph if you already know about mono-hybrid mana.

Previously I have talked about programming normal mana costs (2WW), but Shadowmoor features new, unusual costs like (2/B), you may pay 2 of any mana or B. Shadowmoor also brings back hybrid costs like GB, you may pay G or B. The reason I mention all of this, is because these new costs mean more programming (which isn’t necessarily a bad thing).

I have done some additional programming and the good news is that I can process all mana costs that Wizards has ever printed, except for the weird snow mana that Coldsnap introduced. I wanted to talk about the logic that my code uses.

Everything came together when I started thinking about dividing the mana cost into smaller parts. So “2WW” would have the parts: 2, W, W. Each individual part would know what kind of mana it needed. So the object ManaPart would have a only a few methods as shown below. The method needsMana() returns true if that mana is needed. The object ManaPart greatly simplifies the task of programming X and hybrid costs.

needsMana(String) : boolean
isPaid() : boolean
toString() : String

But wait!! I haven’t shown you the magic yet. Each ManaPart object also has a method named correctManaPart(String part) that returns either true or false. This method answers the question “Does this object handle this kind of mana?” So the ManaPart that handles X costs always handles the X regardless of the rest of the cost. So I could easily handle snow mana, because it would involve just adding a new ManaPart.

I’m going to try to describe the pseudocode below, because I stink at writing it. TotalManaCost is given a cost like 2WW creates the correct ManaPart for each part. In this example, the parts are “2”, “W”, and “W” so three ManaPart objects are created.

setCost(String cost):

Split cost into mana parts
for p in parts:
for m in ManaParts:
If m.correctCost(p)
totalCost.add(create ManaPart)

addMana(String mana):
loop through totalCost to see which ManaPart needs mana

Download Python Code – I’ll explain it in more detail in my next post.

No comments: