Re: Two questions about style and some simple math

2009-01-20 Thread J Kenneth King
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

2009-01-20 Thread Rhodri James

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

2009-01-19 Thread Spoofy

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

2009-01-19 Thread Rhodri James

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

2009-01-19 Thread MRAB

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

2009-01-19 Thread Mensanator
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

2009-01-19 Thread John Machin
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