私は最近、単純なテキストベースのアドベンチャーゲームをプログラミングして楽しませており、非常に単純なデザインの問題のように見えます。
概要を説明すると、ゲームはRoom
オブジェクトに分解されます。それぞれにRoom
は、Entity
その部屋にあるオブジェクトのリストがあります。それぞれEntity
に、単純な文字列->ブールマップであるイベント状態と、文字列->関数マップであるアクションリストがあります。
ユーザー入力は次の形式を取ります[action] [entity]
。Room
適切戻るには、エンティティ名を使用Entity
して、正しい機能を見つけるために、アクション名を使用するオブジェクトを、それを実行します。
部屋の説明を生成するために、各Room
オブジェクトは独自の説明文字列を表示し、すべての説明文字列を追加しますEntity
。Entity
説明は(ETC、「ドアが開いている」、「ドアが閉じている」、「ドアがロックされている」)、その状態に基づいて変更することができます。
ここに問題があります。この方法を使用すると、実装する必要のある記述およびアクション関数の数がすぐに手に負えなくなります。私のスターティングルームだけでも、5つのエンティティの間に約20の機能があります。
すべてのアクションを1つの関数に結合し、それらをif-else / switchで結合できますが、それでもエンティティあたり2つの関数です。またEntity
、ドアやキーなどの一般的なオブジェクトや一般的なオブジェクトの特定のサブクラスを作成することもできますが、それだけではこれまでのところはできません。
編集1:要求どおり、これらのアクション関数の疑似コード例。
string outsideDungeonBushesSearch(currentRoom, thisEntity, player)
if thisEntity["is_searched"] then
return "There was nothing more in the bushes."
else
thisEntity["is_searched"] := true
currentRoom.setEntity("dungeonDoorKey")
return "You found a key in the bushes."
end if
string dungeonDoorKeyUse(currentRoom, thisEntity, player)
if getEntity("outsideDungeonDoor")["is_locked"] then
getEntity("outsideDungeonDoor")["is_locked"] := false
return "You unlocked the door."
else
return "The door is already unlocked."
end if
説明関数はほとんど同じように動作し、状態をチェックして適切な文字列を返します。
編集2:私の質問文言を改訂しました。他のオブジェクトと共通の動作(特定のアクションに対する状態ベースの応答)を共有しないゲーム内オブジェクトがかなりの数存在するとします。エンティティ固有のアクションごとにカスタム関数を作成するよりも、クリーンでメンテナンス可能な方法でこれらの固有の動作を定義できる方法はありますか?