メタクラスの書き方 †pythonでは、typeを使って、サブクラスを使わずクラスを派生できる。 RPGなどで、職業などの試行錯誤をしたいときに便利だと思う。下の例は、種族(human)から職業,戦士(Fighter),盗賊(theif)を生成する。 2D6見たいな表記は、TRPGに慣れてないと分りづらいけど、6面のダイスを二回振って合計値を求めるという意味。 ハイライトは、 ChHash['Fighter']=type('Fihgter',(Human,),\ {'job':'Fighter','ita':'3D6','itl':'10D6','itq':'2D6'}) f=ChHash['Fighter']() ChHash['Thief']=type('Thief',(Human,),\ {'job':'Thief','ita':'2D6','itl':'6D6','itq':'4D6'}) t=ChHash['Thief']() X=type('クラス名',(親クラス),{属性}) f=X() で、クラスXのインスタンスが作れる。 属性は、
と言う意味。 戦士だと、ヒットポイントは、(10D6)の範囲(10-60)、盗賊だと(6D6)の範囲(6-36)の範囲になる。 そのままだと余りに戦士が有利なので、先に攻撃できるほう(素早さが高いほう)は、二回攻撃している。 Ch.sort(qnsort)#素早さを元にソートしてある Ch[0].strike(Ch[1]) Ch[0].strike(Ch[1]) Ch[1].strike(Ch[0]) 本文は、こんな感じ。好きにつかうよろし。 import random class Human(object): def __init__(self): self.attack=self.ita self.life=self.__undice(self.itl) self.hit_rate=0.8 self.quickness=self.__undice(self.itq) self.block_rate=0.2 def strike(self,obj): if self.__hit(obj): self.__attack(obj) else: return def __hit(self,obj): result=False if random.random()<(self.hit_rate-obj.block_rate): result=True return result def __undice(self,str): (freq,level)=str.split('D') return int(freq)*random.randint(1,int(level)) def __attack(self,obj): at=self.__undice(self.attack) obj.life=obj.life-at def islost(Ch): result=True for k in Ch: if k.life<0: print 'lost',k.job result=False return result Ch=[] ChHash={} ChHash['Fighter']=type('Fighter',(Human,),{'job':'Fighter','ita':'3D6','itl':'10D6','itq':'2D6'}) k=ChHash['Fighter']() Ch.append(k) ChHash['Thief']=type('Thief',(Human,),{'job':'Thief','ita':'2D6','itl':'6D6','itq':'4D6'}) k=ChHash['Thief']() Ch.append(k) def qnsort(a,b): return cmp(b.quickness,a.quickness) Ch.sort(qnsort) for c in Ch: print 'job=%s,qns=%d life=%d,attack=%s' % \ (c.job,c.quickness,c.life,c.attack) count=0 while(islost(Ch) and count<10): Ch[0].strike(Ch[1]) Ch[0].strike(Ch[1]) Ch[1].strike(Ch[0]) count+=1 print Ch[0].job,Ch[0].life,Ch[1].job,Ch[1].life |