#freeze
[[プログラム周り]]

*メタクラスの書き方 [#d9aee725]
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のインスタンスが作れる。
属性は、
|ita|攻撃値|
|itl|ヒットポイント|
|itq|素早さ|
と言う意味。
戦士だと、ヒットポイントは、(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

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS