OO and game design questions

2010-10-18 Thread dex
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.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-18 Thread dex
> You're aware Python can collect reference cycles, correct?  You don't
> have to delete references; Python will get them eventually.  

I'm not sure I understand this part? If I don't delete all strong
references, the object will not be deleted.
It will persist and occupy memory as long as there's at least one
reference to it (it could be part of inventory, or target of some
action).


> Instead, I'd recommend managing the lifetime of all objects (creating
> and destroying) through game_object methods.  To create an object,
> don't call its constructor, call obj =
> game_object.create(,args) and game_object.destroy(obj).
> (If you really want to be strict about it, you can override __init__
> to raise an exception (thus disabling the normal way to create an
> object), and create the objects in you create method by calling the
> class's __new__ method directly.)

This makes sense, I will make these modifications.

> Your objects should have two sets of attributes (beginning of round,
> end of round) and a method to copy the end-of-round attributes to the
> beginning-of-round area at the end of the round.

Perhaps I could utilize properties. Make getters return start-of-round
attributes
and setters set end-of-round attributes. Things would get a bit messy
if two or more players modify the same attribute or chest content.
I need to think about this some more.

Thanks for your thoughts.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread dex
> I'm not sure if it's a good idea to let an item disappear from your
> inventory by a weak reference disappearing.  It seems a little shaky
> to not know where your objects are being referenced, but that's yout
> decision.

OK, imagine a MUD, where players can "dig out" new rooms. Room A has a
door that holds reference to newly created room B. By "using" a door,
player is transported to room B. At later time someone destroys room
B.

Using strong references, I have to remove room B from list of rooms,
and also remove door to room B, as it holds reference to room B. To do
that, I have to keep list of doors that lead to room B.

Using weak references, I don't have to worry about removing all doors
to room B. They all now have a dead reference, which better models
actual situation. If part of mine collapses, or if a module on space
station is destroyed, the passage to that location does not magically
vanish - it's just obstructed.

Can you please tell me if there's something wrong with my reasoning?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread dex
On Oct 19, 8:08 pm, Carl Banks  wrote:
> On Oct 19, 1:19 am, dex  wrote:
>
>
>
>
>
> > > I'm not sure if it's a good idea to let an item disappear from your
> > > inventory by a weak reference disappearing.  It seems a little shaky
> > > to not know where your objects are being referenced, but that's yout
> > > decision.
>
> > OK, imagine a MUD, where players can "dig out" new rooms. Room A has a
> > door that holds reference to newly created room B. By "using" a door,
> > player is transported to room B. At later time someone destroys room
> > B.
>
> > Using strong references, I have to remove room B from list of rooms,
> > and also remove door to room B, as it holds reference to room B. To do
> > that, I have to keep list of doors that lead to room B.
>
> > Using weak references, I don't have to worry about removing all doors
> > to room B. They all now have a dead reference, which better models
> > actual situation. If part of mine collapses, or if a module on space
> > station is destroyed, the passage to that location does not magically
> > vanish - it's just obstructed.
>
> > Can you please tell me if there's something wrong with my reasoning?
>
> Well, you're talking about particulars here whereas I am speaking in
> general.  If something is "questionable" or even "bad" in general it
> doesn't mean there are no particular cases for it.
>
> Generally speaking: in a game there's presumably some conservation of
> objects.  If you drop an item, does it disappear, or does it become an
> object of the room?  Weak referencing won't help you in the latter
> case because you have to take care of references at both ends anyway.
> That's what I mean by shaky: it lets you forget about half of the
> transaction, which might not be the best thing.  YMMV
>
> Carl Banks

I see your point. I'll think this through and try to build more robust
system.
Thanks for your insight.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread dex
On Oct 19, 6:54 pm, Dennis Lee Bieber  wrote:
> On Tue, 19 Oct 2010 01:19:48 -0700 (PDT), dex 
> declaimed the following in gmane.comp.python.general:
>
>
>
> > OK, imagine a MUD, where players can "dig out" new rooms. Room A has a
> > door that holds reference to newly created room B. By "using" a door,
> > player is transported to room B. At later time someone destroys room
> > B.
>
>         Out of curiosity, have you looked at any of the older Python
> efforts?
>
> http://py-universe.sourceforge.net/http://www.strout.net/info/coding/python/poo/index.html(some
>  dead
> links)
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfr...@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

I will check out your links. I did some research on several MUD
projects (evennia, PyMUD) and gained very little from them. I used MUD
only as example, my game idea is combination of Rogue and Elite, with
Darklands GUI. It's definitely overambitious, but I'm taking it slowly
and learning things on the way.

Thanks for input.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread dex
On Oct 20, 12:25 pm, Jonathan Hartley  wrote:
> On Oct 18, 8:28 am, dex  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()

Mr. Roy Smith already proposed using closures. I already did a similar
thing in my code, but instead of decrease_hp() I have AttributeEffect
class which is able to modify any attribute (in old RPGs some monsters
could drain your intelligence, in my game laser gun hit will decrease
HP as well as armor integrity). The first version looks like this
(missing few checks):

class AttributeEffect(object):
'''Effect changes object's attribute by delta'''
def __init__(self, obj, attrib, delta):
self.obj = obj   # reference to object the effect
applies to
self.attrib = attrib # name of attribute that effect
applies to
self.delta = delta   # change of value for
object.attribute
def apply(self):
value = getattr(self.obj, self.attrib) # todo: try, except
value += self.delta
setattr(self.obj(), self.attrib, value)

Yesterday I learned that Python 3.0 introduces nonlocal keyword which
would simplify defining effect functions and passing them along. Nice
improvement.
-- 
http://mail.python.org/mailman/listinfo/python-list


MySQLdb extracting to a list

2007-12-13 Thread dave . dex
Hi all,

I've been searching the docs like mad and I'm a little new to python
so apologies if this is a basic question.

I would like to extract the results of the following query into a list
- SELECT columnname FROM tablename. I use the following code.

# Create a connection object and create a cursor
db = MySQLdb.Connect(http://mail.python.org/mailman/listinfo/python-list


Re: MySQLdb extracting to a list

2007-12-13 Thread dave . dex
On Dec 13, 10:40 am, John Machin <[EMAIL PROTECTED]> wrote:
> On Dec 13, 9:03 pm, [EMAIL PROTECTED] wrote:
>
>
>
> > Hi all,
>
> > I've been searching the docs like mad and I'm a little new to python
> > so apologies if this is a basic question.
>
> > I would like to extract the results of the following query into a list
> > - SELECT columnname FROM tablename. I use the following code.
>
> > # Create a connection object and create a cursor
> > db = MySQLdb.Connect( > cursor = db.cursor()
> > # Make SQL string and execute it
> > sql = "SELECT columnname FROM tablename"
> > cursor.execute(sql)
> > # Fetch all results from the cursor into a sequence and close the
> > connection
> > results = cursor.fetchall()
> > db.close()
> > print results
>
> > The output from the above gives the following:
>
> > (('string1',), ('string2',), ('string3',))
>
> > When I'm expecting
> > ('string1', 'string2', 'string3')
>
> > I could pass this through some string manipulation but I'd guess I'm
> > doing something wrong. Please could someone point me in the right
> > direction.
>
> Your SQL query has returned 3 rows. Each row contains only 1 column.
>
> Each row is returned as a tuple of 1 element. The whole result is a
> tuple of 3 rows. You don't need string manipulation, you need tuple
> manipulation.
>
> Better example:
> select name, hat_size from friends;
> results in:
> (('Tom', 6), ('Dick', 7), ('Harry', 8))
>
> so:>>> result = (('Tom', 6), ('Dick', 7), ('Harry', 8))
> >>> [row[0] for row in result]
>
> ['Tom', 'Dick', 'Harry']>>> for n, h in result:
>
> ...print 'Name: %s; hat size: %d' % (n, h)
> ...
> Name: Tom; hat size: 6
> Name: Dick; hat size: 7
> Name: Harry; hat size: 8
>
> >>> result[2][1]
> 8
>
> HTH,
> John

Many thanks John,

Really well explained and I understand what to do now. It's much
appreciated.

Thanks again.
-- 
http://mail.python.org/mailman/listinfo/python-list