プログラム周り

メタクラスの書き方

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
Last-modified: 2015-02-01 (日) 14:38:23 (1021d)