ホーム < ゲームつくろー! < デザインパターン習得編

Strategy
  〜ある結果を色々な方法で求めてみよう


@ 結果は過程によって異なる

 ノベルス系のゲームでは文章を整頓して描画することが大切になってきます。文章を整える方法で基本なのが「改行位置」です。改行の方法として、例えば18文字ごとに改行を入れるというのがあります。また「句点」で改行を入れる方法もあります。人によってはもっとオリジナルな改行の入れ方をするでしょう。いずれの方法も、最終的に欲しいのは「1行に入れる文字列」です。

 このようになんらかの共通する結果を出力するのに、何通りもの方法(アルゴリズム)が存在するとき、その「方法」の部分をクラス化してしまおうと考えたのがStrategyパターンです。Strategyとは「戦略」の事です。

 このパターンはStateパターンと同じ構造をしています。すなわち派生クラスで特定のアルゴリズムを持たせ、使用者がそれを使い分ける事になります。



A AI(人工知能)だってStrategy

 ゲームといえばAI(人工知能)が欠かせません。RPGなどの戦闘ではこの良し悪しがゲームの質を決定すると言っても過言ではありません。今、攻撃ターンになった時に、次の行動パターンを出力するNextStrategyクラスを作成します。

class NextStrategy
{
public:
   virtual int Next(State* state);   // 現状から次の行動パターンを出力
};


 Next関数に現状を表すStateオブジェクトを渡すと、それを解析して次の行動を決定してくれます。このクラスを派生させて、特定の行動を起こすクラスを作ります。これには非常にたくさんの方法論があると思います。例えば、ニューラルネットワークを用いた複雑な意思決定法から、状態遷移行列を用いた動的なアルゴリズムなどです。その手の話も面白いのですが、ここでは複雑な中身については考えずに、ただそういうことを実現するクラスがあると設定します。

class NextStgNeuroalNetwork : public NextStrategy
{
public:
   virtual int Next(State* state);   // ニューラルネットワークを用いた次の行動パターン決定法
};
class NextStgStateTrans : public NextStrategy
{
public:
   virtual int Next(State* state);   // 状態遷移行列を用いた次の行動パターン決定法
};


双方のクラスとも、内部の構造はかなりに複雑です。しかし、ユーザー(クライアント)は内部のことをあまり気にせずに、どちらかのアルゴリズムを選択できます。また、途中で入れ替えることも可能でしょう。

 使う側は、これらのオブジェクトを保持し、選択して使用します。

Strategyパターンのクラス図を示します。


AIのアルゴリズムに置き換えます。


難しいところはありませんね。
 「Enemy(Context)クラスにアルゴリズムを入れ込んではいけないのか?」と疑問になると思いますが、たとえばニューラルネットワークを用いる場合は、物凄い数の変数を保持しておく必要があります。これは、Enemyにとってはあまり関係のない数字の羅列ですし、他のAIにはまったく関係ありません。そういう変数がEnemyクラスから見えてしまうのは、パッケージ化を基本とするオブジェクト指向として良い設計ではないでしょう。Strategyパターンは、そういう見せては困る部分を隠蔽する働きもなしています。