PythonでコモンイベントのDSL
Pythonを使ってコモンイベントのjsonファイルを生成するためのDSL(ドメイン特化言語)を作成する方法を紹介します。DSLを使うことで、コモンイベントの定義をより簡単に、かつプログラム的に記述できるようになります。
ステップ1: 基本的なDSLの設計
まずはDSLの基本構造を設計します。DSLを使ってイベントを定義し、その定義からjsonファイルを生成する流れを考えます。
ステップ2: DSLの実装
以下に、Pythonを使った簡単なDSLの例を示します。このDSLを使って、コモンイベントのjsonファイルを生成します。
1. 基本的なイベントコマンドのクラス定義
import json
class EventCommand:
def __init__(self, code, parameters, indent=0):
self.code = code
self.parameters = parameters
self.indent = indent
def to_dict(self):
return {
"code": self.code,
"parameters": self.parameters,
"indent": self.indent
}
class ShowText(EventCommand):
def __init__(self, character_name, text, position=2):
parameters = [character_name, 0, 0, position, text]
super().__init__(101, parameters)
class ShowChoices(EventCommand):
def __init__(self, choices):
parameters = choices
super().__init__(102, parameters)
class Wait(EventCommand):
def __init__(self, frames):
parameters = [frames]
super().__init__(230, parameters)
# 他のコマンドも同様に定義します...
2. コモンイベントのクラス定義
class CommonEvent:
def __init__(self, event_id, name, trigger=0, switch_id=0):
self.id = event_id
self.name = name
self.trigger = trigger
self.switch_id = switch_id
self.list = []
def add_command(self, command):
self.list.append(command)
def to_dict(self):
return {
"id": self.id,
"name": self.name,
"trigger": self.trigger,
"switchId": self.switch_id,
"list": [cmd.to_dict() for cmd in self.list]
}
class CommonEvents:
def __init__(self):
self.events = []
def add_event(self, event):
self.events.append(event)
def to_json(self, file_path):
data = [event.to_dict() for event in self.events]
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
3. DSLを使ってコモンイベントを定義し、jsonファイルを生成する
if __name__ == "__main__":
common_events = CommonEvents()
# イベント1を作成
event1 = CommonEvent(1, "Morning Assembly")
event1.add_command(ShowText("Teacher", "Good morning, students! Today we have a special announcement."))
event1.add_command(Wait(60))
event1.add_command(ShowText("Teacher", "Let's begin the class."))
common_events.add_event(event1)
# イベント2を作成
event2 = CommonEvent(2, "Lunch Break")
event2.add_command(ShowText("Friend", "Let's go to the cafeteria together!"))
common_events.add_event(event2)
# 他のイベントを追加...
# jsonファイルを生成
common_events.to_json("common_events.json")
このDSLを使うことで、コモンイベントをプログラム的に定義し、それをjsonファイルとして出力できます。上記の例では、いくつかの基本的なコマンド(ShowText、Waitなど)を定義していますが、必要に応じて他のコマンドも同様の方法で追加できます。
ステップ3: コマンドの拡充
上記の例に基づいて、他のイベントコマンド(選択肢の表示、変数の操作など)も定義し、DSLを拡充していきましょう。これにより、より複雑なイベントも簡単に定義できるようになります。
ifコマンドの書き方
IfCommand
を追加することで、条件分岐を持つイベントを作成できるようにします。以下に、IfCommand
のクラスを追加し、DSLの機能を拡張する方法を示します。
IfCommand
クラスの定義
ステップ1: まず、条件分岐を扱うIfCommand
クラスを定義します。
class IfCommand(EventCommand):
def __init__(self, condition, true_branch=None, false_branch=None):
parameters = [condition]
super().__init__(111, parameters)
self.true_branch = true_branch if true_branch else []
self.false_branch = false_branch if false_branch else []
def add_true_command(self, command):
self.true_branch.append(command)
def add_false_command(self, command):
self.false_branch.append(command)
def to_dict(self):
true_branch_dicts = [cmd.to_dict() for cmd in self.true_branch]
false_branch_dicts = [cmd.to_dict() for cmd in self.false_branch]
return {
"code": self.code,
"parameters": self.parameters,
"indent": self.indent,
"true_branch": true_branch_dicts,
"false_branch": false_branch_dicts
}
CommonEvent
クラスの修正
ステップ2: CommonEvent
クラスでIfCommand
を処理できるように、イベントリストの展開方法を修正します。
class CommonEvent:
def __init__(self, event_id, name, trigger=0, switch_id=0):
self.id = event_id
self.name = name
self.trigger = trigger
self.switch_id = switch_id
self.list = []
def add_command(self, command):
self.list.append(command)
def to_dict(self):
event_list = []
for cmd in self.list:
event_list.append(cmd.to_dict())
if isinstance(cmd, IfCommand):
event_list.extend(cmd.true_branch)
if cmd.false_branch:
event_list.append({"code": 411, "indent": 0})
event_list.extend(cmd.false_branch)
event_list.append({"code": 412, "indent": 0})
return {
"id": self.id,
"name": self.name,
"trigger": self.trigger,
"switchId": self.switch_id,
"list": event_list
}
ステップ3: DSLを使って条件分岐を含むイベントを定義
以下の例では、条件分岐を含むイベントをDSLを使って定義します。
if __name__ == "__main__":
common_events = CommonEvents()
# イベント1を作成
event1 = CommonEvent(1, "Morning Assembly")
event1.add_command(ShowText("Teacher", "Good morning, students! Today we have a special announcement."))
event1.add_command(Wait(60))
# 条件分岐の追加
if_command = IfCommand("Variable 1 == 1")
if_command.add_true_command(ShowText("Teacher", "Let's begin the class."))
if_command.add_false_command(ShowText("Teacher", "Please take your seats."))
event1.add_command(if_command)
common_events.add_event(event1)
# イベント2を作成
event2 = CommonEvent(2, "Lunch Break")
event2.add_command(ShowText("Friend", "Let's go to the cafeteria together!"))
common_events.add_event(event2)
# 他のイベントを追加...
# jsonファイルを生成
common_events.to_json("common_events.json")
IfCommand
の条件とtrue/falseブランチの処理
ステップ4: IfCommand
の条件に基づいて、イベントリストにtrue_branch
とfalse_branch
のコマンドを展開します。これにより、条件分岐を持つイベントをjsonファイルとして出力できるようになります。
完成したコード
以下に、上記のすべてのコードをまとめます。
import json
class EventCommand:
def __init__(self, code, parameters, indent=0):
self.code = code
self.parameters = parameters
self.indent = indent
def to_dict(self):
return {
"code": self.code,
"parameters": self.parameters,
"indent": self.indent
}
class ShowText(EventCommand):
def __init__(self, character_name, text, position=2):
parameters = [character_name, 0, 0, position, text]
super().__init__(101, parameters)
class ShowChoices(EventCommand):
def __init__(self, choices):
parameters = choices
super().__init__(102, parameters)
class Wait(EventCommand):
def __init__(self, frames):
parameters = [frames]
super().__init__(230, parameters)
class IfCommand(EventCommand):
def __init__(self, condition, true_branch=None, false_branch=None):
parameters = [condition]
super().__init__(111, parameters)
self.true_branch = true_branch if true_branch else []
self.false_branch = false_branch if false_branch else []
def add_true_command(self, command):
self.true_branch.append(command)
def add_false_command(self, command):
self.false_branch.append(command)
def to_dict(self):
true_branch_dicts = [cmd.to_dict() for cmd in self.true_branch]
false_branch_dicts = [cmd.to_dict() for cmd in self.false_branch]
return {
"code": self.code,
"parameters": self.parameters,
"indent": self.indent,
"true_branch": true_branch_dicts,
"false_branch": false_branch_dicts
}
class CommonEvent:
def __init__(self, event_id, name, trigger=0, switch_id=0):
self.id = event_id
self.name = name
self.trigger = trigger
self.switch_id = switch_id
self.list = []
def add_command(self, command):
self.list.append(command)
def to_dict(self):
event_list = []
for cmd in self.list:
event_list.append(cmd.to_dict())
if isinstance(cmd, IfCommand):
event_list.extend(cmd.true_branch)
if cmd.false_branch:
event_list.append({"code": 411, "indent": 0})
event_list.extend(cmd.false_branch)
event_list.append({"code": 412, "indent": 0})
return {
"id": self.id,
"name": self.name,
"trigger": self.trigger,
"switchId": self.switch_id,
"list": event_list
}
class CommonEvents:
def __init__(self):
self.events = []
def add_event(self, event):
self.events.append(event)
def to_json(self, file_path):
data = [event.to_dict() for event in self.events]
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
if __name__ == "__main__":
common_events = CommonEvents()
# イベント1を作成
event1 = CommonEvent(1, "Morning Assembly")
event1.add_command(ShowText("Teacher", "Good morning, students! Today we have a special announcement."))
event1.add_command(Wait(60))
# 条件分岐の追加
if_command = IfCommand("Variable 1 == 1")
if_command.add_true_command(ShowText("Teacher", "Let's begin the class."))
if_command.add_false_command(ShowText("Teacher", "Please take your seats."))
event1.add_command(if_command)
common_events.add_event(event1)
# イベント2を作成
event2 = CommonEvent(2, "Lunch Break")
event2.add_command(ShowText("Friend", "Let's go to the cafeteria together!"))
common_events.add_event(event2)
# 他のイベントを追加...
# jsonファイルを生成
common_events.to_json("common_events.json")
このコードを実行することで、条件分岐を含むコモンイベントのjsonファイルを生成できます。IfCommand
クラスを使うことで、イベントの条件分岐を簡単に定義できるようになりました。
Discussion