見出し画像

フラグを整理する

部屋中を動き回れるようになったきたので、少しソースコードのリファクタリングすることにした。まずはフラグから始める。

フラグを分類する

オリジナルのソースコードでは、すべてのフラグ値は分類されてなくて、単に列挙されている。まずはこれを分類する。

--- rogue.h ---
126: /*
127: * Various flag bits
128: */
129: #define ISDARK  0000001
130: #define ISCURSED 000001
131: #define ISBLIND 0000001
132: #define ISGONE  0000002
133: #define ISKNOW  0000002
134: #define ISRUN   0000004
135: #define ISFOUND 0000010
136: #define ISINVIS 0000020
137: #define ISMEAN  0000040
138: #define ISGREED 0000100
139: #define ISBLOCK 0000200
140: #define ISHELD  0000400
141: #define ISHUH   0001000
142: #define ISREGEN 0002000
143: #define CANHUH  0004000
144: #define CANSEE  0010000
145: #define ISMISL  0020000
146: #define ISCANC  0020000
147: #define ISMANY  0040000
148: #define ISSLOW  0040000
149: #define ISHASTE 0100000

フラグを分類していくと、5つのカテゴリに収まり、2つの系統(is系とcan系)を持つことがわかる。

分類したフラグ

分類したフラグを必要な箇所にまとめることで、ソースコードは格段に見やすくなる。

フラグの判定

オリジナルのソースコードでは、フラグの判定を行うためだけに専用のマクロが用意されている。pythonにはマクロがないので、これを関数に落とし込むのはやや抵抗がある。

--- rogue.h ---
51: #define on(thing, flag) (((thing).t_flags & flag) != 0)
52: #define off(thing, flag) (((thing).t_flags & flag) == 0)

Cにはクラスメソッドがないので、こういったマクロが必要になるのはよくわかる。可読性も悪くないし、Cでならいいのかもしれない。

しかし、折角Pythonに移植するのだから、次のようにPythonらしい書き方をしたい。

if room.isDark:
    # ダークルームなら

このような書き方を許す一番簡単な方法はクラス変数としてフラグを持たせる方法だけど、一括でフラグをクリアしたい場合に対応することができない。そこで、今回はフラグを管理するためのクラスを作成することにした。

setatter組み込み関数

Pythonのことはよくわからないので調べてみると、デコレータを使って定義済みのクラスに対して後からメンバを追加するsetattr組み込み関数という便利なものがあるらしい。

setatter組み込み関数は、次のように使う。メンバがなければ追加し、メンバがあれば値を上書きしてくれる。

setattr(className, memberName, initalizeValue)

追加したフラグ名のリストをフラグを管理するクラスの初期化時に渡し、初期値をクリアするようにすればよさそう。

実装すると次のようになる。

class Flags(object):
   def __init__(self, flagList):
       self.flagList = flagList
       self.clearAll()

   def clearAll(self):
       for flag in self.flagList:
           setattr(self, flag, False)

さっそくテストコードを書いてみる。

if __name__ == '__main__':
   flags = Flags([ "isGone", "isDark" ])
   print(flags.isGone)
   flags.isGone = True
   print(flags.isGone)

問題なさそうだ。

--- 実行結果 ---
False
True

フラグ周りをリファクタリングすることでPythonの新しい書き方を憶えることができ、冗長な書き方をせずに済むようになった。

この記事が気に入ったらサポートをしてみませんか?