Re: Two questions about style and some simple math
Spoofy spoo...@gmx.net writes: .. snip .. 2. For maintaining the character attributes I creates a seperate class. I wonder weather this is an overuse of OO (instead of just making the attributes plain variables of the Char class) and if the way I wrote this is OK (somehow this looks cool to me but maybe too showy?) class Attributes(object): ATTRIBUTES = {attack: 0, defence: 0, ability: 0, courage: 0, condition: 0} def __init__(self, **kwargs): self.__dict__.update(self.ATTRIBUTES) for arg in kwargs: if arg not in self.ATTRIBUTES: raise ValueError(Unkown character attribute '%s' % arg) self.__dict__[arg] = kwargs[arg] Again, I appreciate any tips. I you need more code (for the bigger picture or such), just ask. Thanks in advance I think the first part has been covered well. If you want an opinion, this class isn't showy at all, rather it is ugly and unnecessary. Firstly it's bad because: 1. ATTRIBUTES is still modifiable after insantiation. This breaks the restriction you're expressing in __init__ 2. You want to avoid modifying __dict__ directly if you can. It bypasses the whole point of using named attributes. What you'd really want in a case where a class has a restricted set of attributes is __slots__. Classes defined with it have no __dict__ and thus attributes cannot be dynamically added to them after instanciation (a __slots__ defined class will raise an exception in this case). However, even in this case, it doesn't make sense to encapsulate the attributes of your game's Character objects in this way. Your Hero class should have its attributes directly associated to it: Hero.health, Hero.defence, and so forth. If you want to encapsulate a common set of attributes available to a class of objects, you'd create a Character class with those general attributes, sub-class your NPC's and Hero from it, and specialize those sub-classes as needed. HTH, j_king -- http://mail.python.org/mailman/listinfo/python-list
Re: Two questions about style and some simple math
On Tue, 20 Jan 2009 02:11:24 -, Mensanator mensana...@aol.com wrote: On Jan 19, 7:44 pm, Rhodri James rho...@wildebst.demon.co.uk wrote: Surely in any case you don't want an expression based on the difference, since that would give you the same chance of having the first attack no matter what the levels of courage actually were, which can't be right. Why? Isn't it possible some attributes are relative rather than absolute? You're right, of course. I blame lack of sleep. What I should have said was that you shouldn't have the random factor scaled to the difference. That way (as with the original code) your attributes aren't even relative, they're pretty much irrelevant. -- Rhodri James *-* Wildebeeste Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Two questions about style and some simple math
Hello everybody! Though I'm a hobby programmer for years now (mainly small hackery things) I still have big problems getting real things to work. I'm currently trying to write a simple RPG and have problems with the following: 1. Characters have a courage attribute that basically determins who has the first attack in a fight. After some trying, I came up with this (sorry, not really working code, but what I made from interactive experimentation): def first_attack(player1, player2): diff = player1.attributes.courage - player2.attributes.courage players = (player, player2) return players[diff + random.randint(-diff, diff) 0] To make it more realistic, I randomized it a little bit and this seems to work for low courage values. But when the courage values are high (100 and such) it fails (the chance to have the first attack drops the higher the values are). My math is really bad and I have problems to understand what's happenning here. I suspect the greater range for randint() is the problem, but I don't really get why. Any tips would be greatly appreciated. 2. For maintaining the character attributes I creates a seperate class. I wonder weather this is an overuse of OO (instead of just making the attributes plain variables of the Char class) and if the way I wrote this is OK (somehow this looks cool to me but maybe too showy?) class Attributes(object): ATTRIBUTES = {attack: 0, defence: 0, ability: 0, courage: 0, condition: 0} def __init__(self, **kwargs): self.__dict__.update(self.ATTRIBUTES) for arg in kwargs: if arg not in self.ATTRIBUTES: raise ValueError(Unkown character attribute '%s' % arg) self.__dict__[arg] = kwargs[arg] Again, I appreciate any tips. I you need more code (for the bigger picture or such), just ask. Thanks in advance -- http://mail.python.org/mailman/listinfo/python-list
Re: Two questions about style and some simple math
On Tue, 20 Jan 2009 01:15:47 -, Spoofy spoo...@gmx.net wrote: Hello everybody! Though I'm a hobby programmer for years now (mainly small hackery things) I still have big problems getting real things to work. I'm currently trying to write a simple RPG and have problems with the following: 1. Characters have a courage attribute that basically determins who has the first attack in a fight. After some trying, I came up with this (sorry, not really working code, but what I made from interactive experimentation): def first_attack(player1, player2): diff = player1.attributes.courage - player2.attributes.courage players = (player, player2) return players[diff + random.randint(-diff, diff) 0] To make it more realistic, I randomized it a little bit and this seems to work for low courage values. But when the courage values are high (100 and such) it fails (the chance to have the first attack drops the higher the values are). My math is really bad and I have problems to understand what's happenning here. I suspect the greater range for randint() is the problem, but I don't really get why. Any tips would be greatly appreciated. This is always going to select player1 (assuming you fix the typo of player for player1!). The most negative number that the call to randint can produce is -diff, so diff + randint() is at least diff + -diff, which is zero and hence never less than zero. Surely in any case you don't want an expression based on the difference, since that would give you the same chance of having the first attack no matter what the levels of courage actually were, which can't be right. 2. For maintaining the character attributes I creates a seperate class. I wonder weather this is an overuse of OO (instead of just making the attributes plain variables of the Char class) and if the way I wrote this is OK (somehow this looks cool to me but maybe too showy?) class Attributes(object): ATTRIBUTES = {attack: 0, defence: 0, ability: 0, courage: 0, condition: 0} def __init__(self, **kwargs): self.__dict__.update(self.ATTRIBUTES) for arg in kwargs: if arg not in self.ATTRIBUTES: raise ValueError(Unkown character attribute '%s' % arg) self.__dict__[arg] = kwargs[arg] It's not necessarily a bad idea to have your character attributes in a separate class, but do you really need to prevent use of other class attribute names (sorry, the terminology crossover is inherently confusing) so much? Unless you think there's a serious danger of trying to add new character attributes on the fly, I think it's overkill. -- Rhodri James *-* Wildebeeste Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: Two questions about style and some simple math
Spoofy wrote: Hello everybody! Though I'm a hobby programmer for years now (mainly small hackery things) I still have big problems getting real things to work. I'm currently trying to write a simple RPG and have problems with the following: 1. Characters have a courage attribute that basically determins who has the first attack in a fight. After some trying, I came up with this (sorry, not really working code, but what I made from interactive experimentation): def first_attack(player1, player2): diff = player1.attributes.courage - player2.attributes.courage players = (player, player2) return players[diff + random.randint(-diff, diff) 0] To make it more realistic, I randomized it a little bit and this seems to work for low courage values. But when the courage values are high (100 and such) it fails (the chance to have the first attack drops the higher the values are). My math is really bad and I have problems to understand what's happenning here. I suspect the greater range for randint() is the problem, but I don't really get why. Any tips would be greatly appreciated. [snip] Try: def first_attack(player1, player2): total_courage = player1.attributes.courage + player2.attributes.courage players = (player, player2) return players[random.randrange(0, total_courage) player1.attributes.courage] -- http://mail.python.org/mailman/listinfo/python-list
Re: Two questions about style and some simple math
On Jan 19, 7:44 pm, Rhodri James rho...@wildebst.demon.co.uk wrote: On Tue, 20 Jan 2009 01:15:47 -, Spoofy spoo...@gmx.net wrote: Hello everybody! Though I'm a hobby programmer for years now (mainly small hackery things) I still have big problems getting real things to work. I'm currently trying to write a simple RPG and have problems with the following: 1. Characters have a courage attribute that basically determins who has the first attack in a fight. After some trying, I came up with this (sorry, not really working code, but what I made from interactive experimentation): def first_attack(player1, player2): diff = player1.attributes.courage - player2.attributes.courage players = (player, player2) return players[diff + random.randint(-diff, diff) 0] To make it more realistic, I randomized it a little bit and this seems to work for low courage values. But when the courage values are high (100 and such) it fails (the chance to have the first attack drops the higher the values are). My math is really bad and I have problems to understand what's happenning here. I suspect the greater range for randint() is the problem, but I don't really get why. Any tips would be greatly appreciated. This is always going to select player1 (assuming you fix the typo of player for player1!). The most negative number that the call to randint can produce is -diff, so diff + randint() is at least diff + -diff, which is zero and hence never less than zero. Surely in any case you don't want an expression based on the difference, since that would give you the same chance of having the first attack no matter what the levels of courage actually were, which can't be right. Why? Isn't it possible some attributes are relative rather than absolute? 2. For maintaining the character attributes I creates a seperate class. I wonder weather this is an overuse of OO (instead of just making the attributes plain variables of the Char class) and if the way I wrote this is OK (somehow this looks cool to me but maybe too showy?) class Attributes(object): ATTRIBUTES = {attack: 0, defence: 0, ability: 0, courage: 0, condition: 0} def __init__(self, **kwargs): self.__dict__.update(self.ATTRIBUTES) for arg in kwargs: if arg not in self.ATTRIBUTES: raise ValueError(Unkown character attribute '%s' % arg) self.__dict__[arg] = kwargs[arg] It's not necessarily a bad idea to have your character attributes in a separate class, but do you really need to prevent use of other class attribute names (sorry, the terminology crossover is inherently confusing) so much? Unless you think there's a serious danger of trying to add new character attributes on the fly, I think it's overkill. -- Rhodri James *-* Wildebeeste Herder to the Masses- Hide quoted text - - Show quoted text -- Hide quoted text - - Show quoted text - -- http://mail.python.org/mailman/listinfo/python-list
Re: Two questions about style and some simple math
On Jan 20, 12:15 pm, Spoofy spoo...@gmx.net wrote: Hello everybody! Though I'm a hobby programmer for years now (mainly small hackery things) I still have big problems getting real things to work. I'm currently trying to write a simple RPG and have problems with the following: 1. Characters have a courage attribute that basically determins who has the first attack in a fight. After some trying, I came up with this (sorry, not really working code, but what I made from interactive experimentation): def first_attack(player1, player2): diff = player1.attributes.courage - player2.attributes.courage players = (player, player2) return players[diff + random.randint(-diff, diff) 0] To make it more realistic, I randomized it a little bit and this seems to work for low courage values. But when the courage values are high (100 and such) it fails (the chance to have the first attack drops the higher the values are). My math is really bad and I have problems to understand what's happenning here. I suspect the greater range for randint() is the problem, but I don't really get why. Are you 100% sure that the above code is what you have been running? For a start, the result of that code depends only on diff which is the difference between the two courages -- it should not be influenced by whether the courages are (say) about 10 or about 100. If player1 is more aggro than player2, then diff will be positive. Let's say it's 20. The lowest possible value returned by random.randint (-20, 20) will be -20. Then 20 + (-20) is zero. so 0 0 is False, and player 1 will always be chosen. This happens for any positive value of diff, even 1. If the diff is zero, then again you get 0 0, and player1 will always be chosen. If the diff is negative, the world blows up; for diff == -10, you get this: ValueError: empty range for randrange() (10,-9, -19) I think that you need to take the range of the courage values into account. You need to scale the randomisation so that you get believable outcomes. If the players have equal courage, there should be a 50% chance that player2 hits first. If one has maximal courage and the other has zero, then the maximal one should have 100% chance of hitting first. For example: def choosep2(diff, maxc): ...assert abs(diff) = maxc ...return random.randint(-maxc, maxc-1) = diff ... def simulate(diff, maxc): ...return sum(choosep2(diff, maxc) for _ in range(100)) ... simulate(0, 50) 50 simulate(0, 50) 47 simulate(0, 50) 43 simulate(49, 50) 1 simulate(-49, 50) 100 You may want to choose a probability distribution that's a bit more bell-shaped than roadkill-shaped, but whatever you do you should check that it's behaving plausibly. HTH, John -- http://mail.python.org/mailman/listinfo/python-list