Proof Of Concept - Breeding Game
Posted: Thu Apr 28, 2016 9:23 am
Deleted.
Supporting creators of visual novels and story-based games since 2003.
https://lemmasoft.renai.us/forums/
Code: Select all
$name = '%04d'%renpy.random.randint(0000, 9999)Code: Select all
$BoxName + BoxNumber = nameN Code: Select all
$nameN = BoxName + str(BoxNumber) Code: Select all
init python:
class TAnt(renpy.store.object):
def __init__(self,Name,Color):
self.BoxNumber=None
self.Name=Name if Name is not None else '%04d'%renpy.random.randint(0000, 9999)
self.Color=Color
def Place(self,BoxNumber=None):
if self.BoxNumber is not None:
Boxes[self.BoxNumber].remove(self)
self.BoxNumber=BoxNumber
if BoxNumber is not None:
Boxes[BoxNumber].append(self)
def ListAntsInBox(BoxNumber):
rv=[]
for Ant in Boxes[BoxNumber]:
rv.append(Ant.Name)
return ','.join(rv) if len(rv)>0 else 'noone'
label start:
$Boxes=[[]]*11
label test:
$AntNames=ListAntsInBox(2)
"In box#2 lives [AntNames]"
$Ant=TAnt('Bob','Lilac')
$Ant.Place(2)
"[Ant.Name] was put in box [Ant.BoxNumber]."
$Ant=TAnt('Alice','Yellow')
$Ant.Place(2)
"[Ant.Name] was put in box [Ant.BoxNumber]."
$AntNames=ListAntsInBox(2)
"In box#2 lives [AntNames]"
$Ant.Place(None)
"[Ant.Name] was removed from box."
$AntNames=ListAntsInBox(2)
"In box#2 lives [AntNames]"
"byebye"
return
Code: Select all
if BoxNumber == 1:
$BoxName1 = nameN
elif Boxnumber == 2:
$BoxName2 = nameN
#etc.
Code: Select all
init python:
AntBaseValue=5
ValueBonuses=[
[{'Color':'Rainbow'}, 1000],
[{'EyeColor':'Pink'}, 7],
[{'Color':'Lilac','EyeColor':'Pink'},10],
[{'Color':'White','EyeColor':'Red'}, 100],
]
class TAnt(renpy.store.object):
def __init__(self,Name,Color,EyeColor):
self.BoxNumber=None
self.Name=Name if Name is not None else '%04d'%renpy.random.randint(0000, 9999)
self.Color=Color
self.EyeColor=EyeColor
def Place(self,BoxNumber=None):
if self.BoxNumber is not None:
Boxes[self.BoxNumber].remove(self)
self.BoxNumber=BoxNumber
if BoxNumber is not None:
Boxes[BoxNumber].append(self)
@property
def Value(self):
Value=AntBaseValue
for BonusReq,Bonus in ValueBonuses:
Match=True
for Attr,Val in BonusReq.items():
if getattr(self,Attr)!=Val:
Match=False
break
if Match:
Value+=Bonus
return Value
label start:
$Alice=TAnt('Alice','White','Red')
$Bob=TAnt('Bob','White','Pink')
$Charlie=TAnt('Charlie','Rainbow','Pink')
"[Alice.Name] cost [Alice.Value], [Bob.Name] cost [Bob.Value], [Charlie.Name] cost [Charlie.Value]"
"byebye"
return
Python is very expressive language, there is some bad sides too, but overall i pretty much love it. Once you learn it you can really do things incredible easy and quick.I wonder if there's a better/shorter way to do it.
Set basic value to higher value and specific combination bonus to negative number.Would it be possible to add a value bonus to everything, BUT a certain combination?
Code: Select all
def ApplyRainbowGen(Child):
Child.Color='Rainbow'
InheritanceBonuses=[
[{'Color':'Rainbow'}, ApplyRainbowGen],
]
def ApplyInheritanceBonus(Child,Parent):
for BonusReq,Bonus in ValueBonuses:
Match=True
for Attr,Val in BonusReq.items():
if getattr(Parent,Attr)!=Val:
Match=False
break
if Match and callable(Bonus):
Bonus(Child)
def MakeBaby(Male,Female):
Child=TAnt(None,'Black','Black')
ApplyInheritance(Child,Male)
ApplyInheritance(Child,Female)
Code: Select all
ValueBonuses=[
# notice !Red
[{'Color':'White','EyeColor':'!Red'}, 100],
]
def Value(self):
Value=AntBaseValue
for BonusReq,Bonus in ValueBonuses:
Match=True
for Attr,Val in BonusReq.items():
if Val[0]=='!':
Val=Val[1:]
Test=lambda a,b: a!=b
else:
Test=lambda a,b: a==b
if not Test(getattr(self,Attr),Val):
Match=False
break
if Match:
Value+=Bonus
return Value
I would create class for Box, then maybe class AntFarm, which will contain and handle boxes.How to access the boxes?
Ants probable shouldn't be predefined at all. During ant creation you should keep it in generic variable "Ant", once you created it fully, then place ant in box, so only box will handle it, and forget about Ant. Tho you should be careful if you interconnect box and ant, if you link box by number, everything ok, but if you keep box link in ant as direct reference, then you can get memory leak. It's kinda tricky sometimes.How to add a new Ant-Fly to the Ant class?
It was half-joke, but still while i can answer simple question during teatime or when i want distraction from my main project, i can't answer all questions.Thank you for offering, but this is only an ambitious learning project.
Don't understand what exactly you want to get. It really helps if you provide not only description of problem, but also test cases. Something simple code like:Zero-matches (combinations of traits from three different archetypes) still give me trouble, though.
Code: Select all
#i have some ant
Ant=TAnt('Green','White')
#...
#...
#here i want to check if his eyes are white
WhiteEyes=...?
#...
#...
#here i use WhiteEyes
if WhiteEyes:
'[Ant.Name] is blind :('
Code: Select all
init python:
AntBaseValue=5
class TAnt(renpy.store.object):
def __init__(self,Name,Color,EyeColor):
self.BoxNumber=None
self.Name=Name if Name is not None else '%04d'%renpy.random.randint(0000, 9999)
self.Color=Color
self.EyeColor=EyeColor
self.CalculateValue()
def Place(self,BoxNumber=None):
if self.BoxNumber is not None:
Boxes[self.BoxNumber].remove(self)
self.BoxNumber=BoxNumber
if BoxNumber is not None:
Boxes[BoxNumber].append(self)
def CalculateValue(self):
self.Value=AntBaseValue
for Bonus in Bonuses:
if Bonus.DoCheck(self):
Bonus.DoApply(self)
return self.Value
Bonuses=[]
class BonusMeta(type):
def __init__(cls,name,bases,dct):
#this black magic allow Bonuses autoregistration
#no need to manually add every bonus to list
if name!='TBonusBase':
Bonuses.append(cls)
#this black magic allow to ignore boilerplate code, like @staticmethod
cls.Check=staticmethod(cls.Check.__func__)
cls.Apply=staticmethod(cls.Apply.__func__)
#it can be anything, not just bonuses, genetic inheritance fit here quite nicely
class BonusBase:
__metaclass__=BonusMeta #part of black magic, mentioned above
@classmethod
def DoCheck(cls,Ant):
for parent in cls.__mro__:
if parent is BonusBase: break
if not parent.Check(Ant): return False
return True
@classmethod
def DoApply(cls,Ant):
cls.Apply(Ant)
# if you want cascade bonuses, then uncomment next 3 lines and comment previous
# for parent in cls.__mro__:
# if parent is BonusBase: break
# parent.Apply(Ant)
def Check(Ant):
return True
def Apply(Ant):
pass
#Add value if Ant color is Rainbow
class BonusRainbowColor(BonusBase):
def Check(Ant):
return Ant.Color=='Rainbow'
def Apply(Ant):
Ant.Value+=100
#Add value if Ant color is Rainbow AND Ant eye color in Rainbow
class BonusRainbowColorAndEyeColor(BonusRainbowColor):
def Check(Ant):
return Ant.EyeColor=='Rainbow'
def Apply(Ant):
Ant.Value+=150
#if you cascade bonuses then total bonus will be +100 for color, +100+150 for color+eyes
#if you not cascade then total bonus will be +100 for color, +150 for color+eyes
#Apply cascading allow some tricky, but make things more complicated
#you probably should keep cascading of Checks, but not cascading of Apply
#Add value if Ant color wasn't unlocked before
#When player sell Ant for example, you add Ant color to UnlockedColors
#Or you can change bonuses to grant bonus only to first Ant with such color
class BonusNewColor(BonusBase):
def Check(Ant):
return Ant.Color not in UnlockedColors
def Apply(Ant):
Ant.Value+=10
label start:
$UnlockedColors=['White']
$Alice=TAnt('Alice','Red','Red') #+10 for Unlocked color, +5 default value
$Bob=TAnt('Bob','White','Pink') #+5 default value
$Charlie=TAnt('Charlie','Rainbow','Pink') #+100 for Color, +10 for Unlocked color, +5 default value
$Diana=TAnt('Diana','Rainbow','Rainbow') #+150 for Color+Eye, +100 for Color, +10 for Unlocked color, +5 default value
"[Alice.Name] cost [Alice.Value], [Bob.Name] cost [Bob.Value], [Charlie.Name] cost [Charlie.Value], [Diana.Name] cost [Diana.Value]"
"byebye"
return
So instead of "Boxes[BoxNumber][AntNumber].Name" you use "boxname[BoxNumber][AntNumber]"? Not sure i can see any benefit in this tbh, but it's your choice heh.The boxes themselves consist of several lists (boxname, boxgender, etc.), so I can make use of the list position to dynamically change and display the stats of a specific ant in a specific box.
I can't see problem just from this line, what error, what code, etc?Works just fine as dialogue in the script.rpy, but adding the same variables to a label or just plain text either makes the label/text not appear or gives me an error. I wonder why that is?
What can i say, i LOVE programming, especially tricky. Especially in python.Answer questions as long as you're having fun
NSFW link https://www.youtube.com/watch?v=7Dt5Nf7ct5cSo, what I'm trying to do is the following:I hope this is a little better.Code: Select all
...
Pretty much everything in python (and renpy, more or less) is object.This is mostly because I didn't (and probably still don't) fully understand classes (but I'm working on it!)
Code: Select all
init python:
#python and renpy ignore everything "#", it's called single-line comment
#new class TAnt(with parent class, need in RenPy, but can be omited in real python for this case)
class TAnt(renpy.store.object):
#this special method __init__ used when you tell Python to create Instance of class TAnt
#it's always must be called __init__, this how Python understand what to call
#self, Name, Color is function arguments
#self is special argument, it automatically added as first argument to every class method call
#self is variable pointing on object itself
#it can be called anyway you wish, but better keep it as "self"
#Name and Color is your arguments used to initialize Ant
def __init__(self,Name,Color):
#we set values to keys of object
self.Name=Name
self.Color=Color
#notice we didn't used CalculateValue(self), as self is auto added by python
CalculateValue()
#this is method, it calculate and set ant value
def CalculateValue(self):
#we set attribute Value of instance self
self.Value=10
#methods as function return things, we can skip this part, then function return None
return self.Value
#world of python is ended, we entered renpy world
start:
#lines in RenPy world started with $ are python code lines
#we tell python to create instance of class TAnt, with arguments Name: "Alice" and Color: "Red"
#now in variable Alice point to object, newly created instance of TAnt
$Alice=TAnt('Alice','Red')
#RenPy read from object Alice, value bound to key Name, which is string "Alice"
"[Alice.Name] is lovely."
return
Code: Select all
Box[boxnumber]_[antnumber].name
Code: Select all
varname='Box'+str(boxnumber)+'_'+str(antnumber)
ant=globals().get(varname)
ant.name='Bobb'
Code: Select all
$Boxes[boxnumber].Place(Ant)
Code: Select all
start:
$boxes=[None]*11
$boxnumber=2
$boxes[boxnumber]=TAnt('vini',...colorsetc...)
"Box [boxnumber] contain [boxes[boxnumber].name]"