複数回攻撃用のパーサ実装
複数回攻撃用のパースを実装することにした。オリジナルのソースコードでは、使用するメモリ量を節約するためなのか、関数fightでダメージ文字列をリアルタイムにパースしている。
パースしている部分だけを抜粋すると次のようになっている。
--- fight.c ---
362: for (;;)
363: {
// code
379: ndice = atoi(cp);
380: if ((cp = index(cp, 'd')) == NULL)
381: break;
382: nsides = atoi(++cp);
// code
400: proll = roll(ndice, nsides);
// code
407: if ((cp = index(cp, '/')) == NULL)
408: break;
409: cp++;
410: }
当時はこのようなやり方がよかったのかもしれないけれど、ソースコードも読みづらくなるし、簡素なパーサを実装して、ダメージ計算用の値を保持させたほうが良さそう。
class Rolls(object):
def __init__(self, damageString=""):
self.rolls = []
if damageString != "":
self.parse(damageString)
def parse(self, damageString):
self.rolls.clear()
for damage in damageString.split("/"):
dice, sides = damage.split("d")
self.rolls.append(( int(dice), int(sides) ))
さっそくテストコードを書いてみる。
rolls = Rolls("1d1/2d12")
print(rolls.rolls)
簡単なパース処理なので問題なさそうだ。ダメージ文字列の妥当性チェックはあとから追加する。
--- 実行結果 ---
[(1, 1), (2, 12)]
オリジナルのソースコードでは、永久ループをしながら処理をしていたけれど、先にパースをしてから処理できるので、次のように書き直せる。
for r in rolls:
// code
この調子でソースコードを整理していこう。