Mercurial > traipse_dev
diff orpg/dieroller/die.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children | 449a8900f9ac |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orpg/dieroller/die.py Tue Jul 14 16:41:58 2009 -0500 @@ -0,0 +1,519 @@ +#!/usr/bin/env python +# Copyright (C) 2000-2001 The OpenRPG Project +# +# openrpg-dev@lists.sourceforge.net +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# -- +# +# File: die.py +# Author: Andrew Bennett +# Maintainer: +# Version: +# $Id: die.py,v 1.13 2007/03/13 17:53:42 digitalxero Exp $ +# +# Description: This class is used to make working with dice easier +# + +__version__ = "$Id: die.py,v 1.13 2007/03/13 17:53:42 digitalxero Exp $" + + +import random +import UserList +import copy +#import string + +class die_base(UserList.UserList): + + def __init__(self,source = []): + if isinstance(source, (int, float, basestring)): + s = [] + s.append(di(source)) + else: + s = source + UserList.UserList.__init__(self,s) + + + def sum(self): + s = 0 + for a in self.data: + s += int(a) + return s + + def __lshift__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + o = other + elif hasattr(other,"sum"): + o = other.sum() + else: + return None + + result = [] + for die in self: + if die < o: + result.append(die) + return self.__class__(result) + + def __rshift__(self,other): + + if type(other) == type(3) or type(other) == type(3.0): + o = other + elif hasattr(other,"sum"): + o = other.sum() + else: + return None + + result = [] + for die in self: + if die > o: + result.append(die) + return self.__class__(result) + + def __rlshift__(self,other): + return self.__rshift__(other) + + def __rrshift__(self,other): + return self.__lshift__(other) + + + def __str__(self): + if len(self.data) > 0: + myStr = "[" + str(self.data[0]) + for a in self.data[1:]: + myStr += "," + myStr += str(a) + myStr += "] = (" + str(self.sum()) + ")" + else: + myStr = "[] = (0)" + return myStr + + def __lt__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return (self.sum() < other) + elif hasattr(other,"sum"): + return (self.sum() < other.sum()) + else: + return UserList.UserList.__lt__(self,other) + + def __le__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return (self.sum() <= other) + elif hasattr(other,"sum"): + return (self.sum() <= other.sum()) + else: + return UserList.UserList.__le__(self,other) + + def __eq__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return (self.sum() == other) + elif hasattr(other,"sum"): + return (self.sum() == other.sum()) + else: + return UserList.UserList.__eq__(self,other) + + def __ne__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return (self.sum() != other) + elif hasattr(other,"sum"): + return (self.sum() != other.sum()) + else: + return UserList.UserList.__ne__(self,other) + + def __gt__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return (self.sum() > other) + elif hasattr(other,"sum"): + return (self.sum() > other.sum()) + else: + return UserList.UserList.__gt__(self,other) + + def __ge__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return (self.sum() >= other) + elif hasattr(other,"sum"): + return (self.sum() >= other.sum()) + else: + return UserList.UserList.__ge__(self,other) + + def __cmp__(self,other): + # this function included for backwards compatibility + # As of 2.1, lists implement the "rich comparison" + # methods overloaded above. + if type(other) == type(3) or type(other) == type(3.0): + return cmp(self.sum(), other) + elif hasattr(other,"sum"): + return cmp(self.sum(), other.sum()) + else: + return UserList.UserList.__cmp__(self,other) + + + def __rcmp__(self,other): + return self.__cmp__(other) + + def __add__(self,other): + mycopy = copy.deepcopy(self) + if type(other) == type(3) or type(other) == type(3.0): + #if other < 0: + # return self.__sub__(-other) + #other = [di(other,other)] + other = [static_di(other)] + #return self.sum() + other + + elif type(other) == type("test"): + return self + mycopy.extend(other) + #result = UserList.UserList.__add__(mycopy,other) + return mycopy + + def __iadd__(self,other): + return self.__add__(other) + + def __radd__(self,other): + mycopy = copy.deepcopy(self) + if type(other) == type(3) or type(other) == type(3.0): + new_die = di(0) + new_die.set_value(other) + other = new_die + mycopy.insert(0,other) + return mycopy + + def __int__(self): + return self.sum() + + def __sub__(self,other): + mycopy = copy.deepcopy(self) + if type(other) == type(3) or type(other) == type(3.0): + neg_die = static_di(-other) + #neg_die.set_value(-other) + other = [neg_die] + #return self.sum() - other + else: + other = -other + mycopy.extend(other) + return mycopy + + def __rsub__(self,other): + mycopy = -copy.deepcopy(self) + #print type(other) + if type(other) == type(3) or type(other) == type(3.0): + new_die = di(0) + new_die.set_value(other) + other = new_die + mycopy.insert(0,other) + return mycopy + + def __isub__(self,other): + return self.__sub__(other) + + def __mul__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.sum() * other + elif hasattr(other,"sum"): + return other.sum() * self.sum() + else: + return UserList.UserList.__mul__(self,other) + + def __rmul__(self,other): + return self.__mul__(other) + + def __div__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return float(self.sum()) / other + elif hasattr(other,"sum"): + return float(self.sum()) / other.sum() + else: + return UserList.UserList.__div__(self,other) + + def __rdiv__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return other / float(self.sum()) + elif hasattr(other,"sum"): + return other.sum() / float(self.sum()) + else: + return UserList.UserList.__rdiv__(self,other) + + def __mod__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.sum()%other + elif hasattr(other,"sum"): + return self.sum() % other.sum() + else: + return UserList.UserList.__mod__(self,other) + + def __rmod__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return other % self.sum() + elif hasattr(other,"sum"): + return other.sum() % self.sum() + else: + return UserList.UserList.__rmod__(self,other) + + def __neg__(self): + for i in range(len(self.data)): + self.data[i] = -self.data[i] + return self + + def __pos__(self): + for i in range(len(self.data)): + self.data[i] = +self.data[i] + return self + + def __abs__(self): + for i in range(len(self.data)): + self.data[i] = abs(self.data[i]) + return self + #return abs(self.sum()) + + def __pow__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.sum() ** other + elif hasattr(other,"sum"): + return self.sum() ** other.sum() + else: + return UserList.UserList.__pow__(self,other) + + + def __rpow__(self,other): + # We're overloading exponentiation of ints to create "other" number of dice + + if other >= 1: + result = self.__class__(self[0].sides) + for t in range(other-1): + result+=self.__class__(self[0].sides) + else: + result = None + + return result + +### di class to handle actual dice + +class di: + def __init__(self,sides,min=1): + self.sides = sides + self.history = None + self.value = None + self.target = None + self.roll(min) + + def __str__(self): + if len(self.history) > 1: + return str(self.history) + else: + return str(self.value) + + def __neg__(self): + self.value = -self.value + for i in range(len(self.history)): + self.history[i] = -self.history[i] + return self + + def __pos__(self): + self.value = +self.value + for i in range(len(self.history)): + self.history[i] = +self.history[i] + return self + + def __abs__(self): + self.value = abs(self.value) + for i in range(len(self.history)): + self.history[i] = abs(self.history[i]) + return self + + def __repr__(self): + if len(self.history) > 1: + return str(self.history) + else: + return str(self.value) + + def __int__(self): + return self.value + + + def __lt__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.value < other + elif hasattr(other,"value"): + return self.value < other.value + else: + return self < other + + def __le__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.value <= other + elif hasattr(other,"value"): + return self.value <= other.value + else: + return self <= other + + def __eq__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.value == other + elif hasattr(other,"value"): + return self.value == other.value + else: + return self == other + + def __ne__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.value != other + elif hasattr(other,"value"): + return self.value != other.value + else: + return self != other + + def __gt__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.value > other + elif hasattr(other,"value"): + return self.value > other.value + else: + return self > other + + def __ge__(self,other): + if type(other) == type(3) or type(other) == type(3.0): + return self.value >= other + elif hasattr(other,"value"): + return self.value >= other.value + else: + return self >= other + + def __cmp__(self,other): + # this function included for backwards compatibility +# As of 2.1, lists implement the "rich comparison" +# methods overloaded above. + if type(other) == type(3) or type(other) == type(3.0): + return cmp(self.value, other) + elif hasattr(other,"value"): + return cmp(self.value, other.value) + else: + return cmp(self,other) + + def roll(self,min=1): + if isinstance(self.sides, basestring) and self.sides.lower() == 'f': + self.value = random.randint(-1, 1) + else: + #self.value = random.randint(min, self.sides) + self.value = int(random.uniform(min, self.sides+1)) + self.history = [] + self.history.append(self.value) + + def extraroll(self): + if isinstance(self.sides, basestring) and self.sides.lower() == 'f': + result = random.randint(-1, 1) + else: + #result = random.randint(1, self.sides) + result = int(random.uniform(1,self.sides+1)) + + self.value += result + self.history.append(result) + + def lastroll(self): + return self.history[len(self.history)-1] + + def set_value(self,value): + self.value = value + self.history = [] + self.history.append(self.value) + + def modify(self,mod): + self.value += mod + self.history.append(mod) + + def gethistory(self): + return self.history[:] + +class static_di(di): + def __init__(self,value): + di.__init__(self,value,value) + self.set_value(value) + + +class std(die_base): + def __init__(self,source=[]): + die_base.__init__(self,source) + + # Examples of adding member functions through inheritance. + + def ascending(self): + result = self[:] + result.sort() + return result + + def descending(self): + result = self[:] + result.sort() + result.reverse() + return result + + def takeHighest(self,num_dice): + return self.descending()[:num_dice] + + def takeLowest(self,num_dice): + return self.ascending()[:num_dice] + + def extra(self,num): + for i in range(len(self.data)): + if self.data[i].lastroll() >= num: + self.data[i].extraroll() + return self + + def open(self,num): + if num <= 1: + self + done = 1 + for i in range(len(self.data)): + if self.data[i].lastroll() >= num: + self.data[i].extraroll() + done = 0 + if done: + return self + else: + return self.open(num) + + def minroll(self,min): + for i in range(len(self.data)): + if self.data[i].lastroll() < min: + self.data[i].roll(min) + return self + + def each(self,mod): + mod = int(mod) + for i in range(len(self.data)): + self.data[i].modify(mod) + return self + + + def vs(self, target): + for dn in self.data: + dn.target = target + return self + + + ## If we are testing against a saving throw, we check for + ## greater than or equal to against the target value and + ## we only return the number of successful saves. A negative + ## value will never be generated. + def sum(self): + retValue = 0 + for dn in self.data: + setValue = reduce( lambda x, y : int(x)+int(y), dn.history ) + if dn.target: + if setValue >= dn.target: + retValue += 1 + + else: + retValue += setValue + + return retValue