「P は Python の P <実戦編>」
〜やるぞ作るぞRPG!〜
NP-4 閉店・新装開店の時
え〜新連載4回にして、もう挫折か?という話しでは、一応ありません(笑)
これまで3回にわたって、試作品に手を入れてまいりましたが、これらは全
体の動作の様子と、本作品に必要なツールをそろえるためのものです。
今回、コマンド関連をつかさどるcommand.pyを完成させて、ひとまずこの試
作品の改良は終了いたします。
ゲーム内容はほとんど変わっていませんが、コマンドは数値だけでなく、文
字もうけつけるように改良されています(大文字、小文字を問いません)
なお、ゲーム終了コマンドはひきつづき隠しコマンドとされていて、"quitgame"
ですので、ゲームに途中で飽きたらご利用ください。
--^ ebv4.py
#---ENDLESS BATTLE ver.4---
# 新しいコマンドクラスの動作確認のための
# テストモジュール
from dice import *
from command import *
from display import *
from unit import *
# 初期化作業
hero = Hero()
# コマンド作成
def hero_attack():
dragon.hp - hero.attack()
# コマンド登録
hero_battle = CommandList({
"attack" : hero_attack ,
"heal" : hero.heal
})
# お宝を装備するか捨てるかの選択コマンド
hero_weaponChange = CommandList({
"change" : hero.changeWeapon,
"drop" : hero.dropTrophy
})
# ゲーム本体
next()
print 'WELCOME TO THE "ENDLESS BATTLE" FIELD!!'
next()
# メインループ
try:
numberOfSlay = 0
while numberOfSlay < 10 :
print "Encounter!!"
next()
dragon = Dragon()
while 1 :
print "HERO'S WEAPON : ",hero.weapon.name
print "HERO'S HP : ",hero.hp
print "HERO'S MP : ",hero.mp
print "DRAGON'S HP : ",dragon.hp
print "NO.OF SLAY : ",numberOfSlay
# 勇者の行動
hero_battle()
# ドラゴンの反撃
print ""
hero.hp -= dragon.attack()
next()
if hero.hp <= 0 : raise "HeroHPZero"
elif dragon.hp <= 0 : break
print "YOU WIN!"
numberOfSlay += 1
print "LEVEL UP!!"
hero.levelUp()
# ここから、お宝に関する処理
print "YOU FIND A NEW WEAPON\nCHANGE?"
hero.getTrophy(dragon.treasure())
hero_weaponChange()
next()
except "HeroHPZero":
print "--HERO IS DEAD!--"
print "--THE GAME OVER--"
next()
else:
print "--HERO SLAY 10 DRAGONS--"
print "----CONGRATULATION!!----"
print "--------GAME END--------"
next()
--$ ebv4.py
ebv4.pyは、FormalCommandに変わる、汎用のCommandListへのオブジェクトの
受け渡し方法が変更されたので、それに合わせてある以外、変更はありません。
unit.py,item.py,display.py,dice.pyの4モジュールについては、全く変更
がありませんので、前回のものがそのまま使用できます。
--^ command.py
# command.pyモジュール[改定版]
# 定型、非定型に両対応
from sys import exit as sys_exit
class CommandList:
def __init__(self,dict):
self.dict = {"quitgame":sys_exit}
self += dict
def __add__(self,dict): # + は連結用
for x in dict:
self.dict[x.lower()] = dict[x]
return self
def __iadd__(self,dict): # +=は非連結用
for x in dict:
self.dict[x.lower()] = dict[x]
def __sub__(self,key): # - は連結用
del self.dict[key.lower()]
return self
def __isub__(self,key): # -= は非連結用
del self.dict[key.lower()]
def __delitem__(self,key):
del self.dict[key.lower()]
def __getitem__(self,key):
return self.dict[key.lower()]
def __setitem__(self,key,value):
self.dict[key.lower()] = value
def __call__(self,direct=0):#call(1)で、表示省略ダイレクト入力
print "\n---COMMAND---\n"
if direct:
print "INPUT COMMAND AND HIT ENTER KEY!"
while 1:
c = raw_input("COMMAND >>> ").lower()
if self.dict.has_key(c):
self.dict[c]()
break
else :
print "BAD COMMAND!\nPLEASE INPUT ONCE MORE"
else :
print "---SELECT NUMBER---"
keyList = self.dict.keys()
# quitgameを隠しコマンドにするため、リストから外す
keyList = [x for x in keyList if x <> "quitgame"]
keyList.sort()
for x in range(len(keyList)):
print x," : " , keyList[x].upper()
print "INPUT COMMAND OR NUMBER\nAND HIT ENTER KEY!"
while 1:
c = raw_input("NUM/COM >>> ").lower()
if c.isdigit(): # 番号入力の場合
c = int(c)
if 0 <= c < len(keyList):
self.dict[keyList[c]]()
break
else:
print "OUT OF RANGE!\nPLEASE INPUT ONCE MORE"
else : # コマンド入力の場合
if self.dict.has_key(c):
self.dict[c]()
break
else :
print "BAD COMMAND!\nPLEASE INPUT ONCE MORE"
--$ command.py
今回の目玉であり、結果的には試作品の最大の結果となりました、コマンド
入力モジュールです。
定型/非定型に分けるとメッセージの変更などが面倒になると考え、両対応
のクラスを作りました。
ちなみに、ebv4.pyの一部を以下のように書き換えると、コマンドなどが表示
されず、ダイレクトにコマンドを入力しなければならなくなります。
hero_battle() -> hero_battle(1)
hero_weaponChange() -> hero_weaponChange(1)
魔法の入力や罠の解除なんかは、コレのほうが、Wizっぽくていいんじゃない
かな?と思うのは私だけでしょうか?(笑)
さて、コマンドがしっかりできたところで、次回からは少しプログラミング
から外れて、ゲームデザインの話などを少しづつ進めていきたいと思います。
最終的にどんなゲームにするかを決め、ゲームの骨格だけのものを作ります。
それが終わったら、いよいよ各種データのフォーマットを考えるために、詳
細な戦闘ルールのデザインに入ります。
戦闘ルールのデザインが終わったら、各種データ、そしてシナリオを書いて
完成。
さて、完成までこぎつけるでしょうか?(笑)
機械伯爵