問題を見れば見るほど、状態/フローチャートを思い出します。

状態オブジェクトには、複数の遷移を含めることができます。
トランジションは次のもので構成されます。
- 条件)
- 行動)
- すべてのオブジェクトは、特定の順序で適用する必要がある複数のルールを持つことができます。ルール 1 が終了すると、ルール 2 の検証が開始されます。
状態図を使用すると、状態と状態遷移を介して複数のルールと特定のアクション シーケンスを取得できます
- すべての個別のルール (たとえば、1 マスしか移動できない、斜めにしか移動できないなど) は、独自のクラスに属し、再利用可能で、ルールが必要なオブジェクトに適用できる必要があります。
これは、条件チェック動作をクラスとしてカプセル化することで実現できます。
public class Condition
{
public string Name {get; set;}
public Func<Move,bool> IsMet {get;set;}
}
// Captures the behaviour of moving diagonally by 1-step
// This can now be referenced/composed by other classes to build
// a more complex condition
var moveDiagonalCondition = new Condition
{
Name="Move diagonal",
IsMet = move =>
{
var delta = (move.ToPosition - move.FromPosition);
// 1 step to the left or right
return Math.Abs(delta.X) == 1
// 1 step upwards (if player),
// or 1 step downwards (if opponent)
&& delta.Y == move.IsPlayer1Move ? -1 : 1
}
}
これは、バックエンドのマルチプレイヤー ゲームで使用されることに注意してください。
すべてのルールには、その有効性をテストするために複数のオブジェクトが必要であることに注意してください。たとえば、通常、ポーンは 1 マス移動できますが、ゲームボード上の次のマスは対戦相手のポーンによって埋められます。結果: ポーンは動けません。ポーンには、他のポーンの位置、または検証にゲームボードを含める必要があります。
move
チェスのシナリオでは、パラメーターを渡すことを提案します。
public class Move
{
public Point FromPosition {get;set;}
public Point ToPosition {get;set;}
public Piece Piece {get;set;}
}
同時に、ステートは GameBoard 全体にアクセスできる必要があります。これにより、州は次のようなことを行うことができます
// Check for empty cell
GameBoard.GetPieceAt(move.ToPosition) == null;
// Check for opponent's piece
GameBoard.GetPieceAt(move.ToPosition).IsPlayer2;
これを MMORPG シナリオにさらに拡張するには、パラメーターを介して「ソース」および/または「ターゲット」を渡します。
- つまり、コリジョン ソース/ターゲット、または直接影響を受けるオブジェクト
結論
状態の問題に非常に似ているため、状態ベースのソリューションを検討することをお勧めします。
例:状態パターン、有限状態マシン、状態遷移表、オートマトンなど。
または、デシジョン テーブルとデシジョン ツリーを調べてみることもできます(これらを自分で実際に使用したことがないため、それらについて多くを語ることはできません)。
残念ながら、正確な解決策をお勧めできるとは思いません。
しかし、うまくいけば、上記のいくつかの例/キーワードが、あなたが始めるのに役立つことを願っています.