On Oct 18, 8:28 am, dex <josipmisko...@gmail.com> wrote: > I'm building a turn based RPG game as a hobby. The design is becoming > increasingly complicated and confusing, and I think I may have > tendency to over-engineer simple things. Can anybody please check my > problems-solutions and point me to more elegant solution? > > Every item/character/room is a separate object. Items/characters need > to have references to room they are in, and room needs to have a list > of references to items/characters that are contained within. I decided > to use weak references. That way I can destroy object by deleting it, > I don't have to destroy all references as well. In each object's > __init__() that object is added to game_object list, and in each > __del__() they are removed from game_object list. This mechanism keeps > them safe from garbage collector. How pythonic is this design? > > In turn-based games, the order of action execution in battle can give > unfair advantage to players. For example, if player's arm is crippled > before his action is executed, he would do less damage. To offset > this, I first execute all players' actions and calculate effects in > first pass, then apply the effects in second pass. The effect can be > health decrease by 15HP, item pick-up, 30p experience gain, etc. This > means the player deals the same amount of damage no matter what > happens to him in that turn. The difficult part is keeping track of > various effects. I had to make separate class for various types of > effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each > class stores weak reference to target object and has apply() method > that applies the effect to object. I'm not satisfied with this as it's > limiting, error-prone and uses metaprogramming. Is there a design > pattern that would remember changes to an object, and apply them > later? > > Sorry for the wall of text.
One common way to store delayed actions is as a lambda (an anonymous function.) A lambda defines a new function: , and you can call this function later. The created function has no name, (but you can assign it to a variable to give it a name if you like) and can be called later: So in the game, you could have a collection 'effects', each one will be a lambda: effects = [] At the start of the round, as each entity makes its moves, they add lambdas to this collection. effects.append( lambda: decrease_hp(monster_a, 4) ) effects.append( lambda: lose_item(monster_a, item_b) ) Instead of appending it directly like this, I imagine the lambdas could be returned by the monster's 'act' or 'update' method: class Monster(): def act(self): # blah and finally return lambda: decrease_hp(monster_a, 4) Then for the start of a round, first you ask each monster what action it is going to perform: for monster in room.monsters: effects.append( monster.act() ) Then for the end of the round, call all the lambdas for effect in effects: effect() -- http://mail.python.org/mailman/listinfo/python-list