规则/验证设计模式

Tho*_*mas 4 c# design-patterns

可以使用哪些设计模式为象棋这样的游戏创建规则/验证系统(这只是一个简单的例子,实际游戏需要更复杂的规则集)

我在这个网站上已经阅读了几个问题,但没有找到一个确凿的答案,也没有一个答案指出我正确的方向.

该系统需要以下内容:

  • 应用了规则的每个对象都应该使用一个方法来实现一个特定的接口,该方法是验证的起点
  • 该规则应该分两步应用:首先,它需要被验证(可以pawn A移动到方格D4),如果为true则执行方法A如果为false则执行方法B
  • 每个对象都可以有多个需要按特定顺序应用的规则.当规则1完成后,规则2应该开始验证等
  • 每个单独的规则(例如:只能移动1个方格,只能对角移动等)必须在其自己的类中,并且必须可重用并适用于需要规则的对象.
  • 请注意,这将在后端的多人游戏中使用
  • 请注意,每个规则都需要多个对象来测试其有效性,例如,通常一个pawn可以移动1个方块,现在游戏板上的下一个sqaure由对手的棋子填充.结果:你的棋子无法移动.典当应包括其他典当位置,或其验证中的游戏板.

这些规则的另一个词是行为限制.

我也在gamedev.stackexchange上发布了这个问题,但由于这不是一个与游戏相关的问题而且没有人似乎有一个答案我也在这里发布.

jay*_*ars 8

我越是看问题,我就越想起状态/流程图.

在此输入图像描述

  • 应用了规则的每个对象都应该使用一个方法来实现一个特定的接口,该方法是验证的起点

  • 该规则应该分两步应用:首先,它需要被验证(可以pawn A移动到方格D4),如果为true则执行方法A如果为false则执行方法B

状态对象可以包含多个转换.

过渡包括:

  1. 条件)
  2. 行动(S)
  • 每个对象都可以有多个需要按特定顺序应用的规则.当规则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
                    }
}
Run Code Online (Sandbox Code Playgroud)
  • 请注意,这将在后端的多人游戏中使用

  • 请注意,每个规则都需要多个对象来测试其有效性,例如,通常一个pawn可以移动1个方块,现在游戏板上的下一个sqaure由对手的棋子填充.结果:你的棋子无法移动.典当应包括其他典当位置,或其验证中的游戏板.

在国际象棋场景中,我建议传递move参数:

public class Move
{
    public Point FromPosition {get;set;}
    public Point ToPosition {get;set;}
    public Piece Piece {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

与此同时,各州应该可以访问整个GameBoard.这允许国家做类似的事情

// Check for empty cell
GameBoard.GetPieceAt(move.ToPosition) == null;

// Check for opponent's piece
GameBoard.GetPieceAt(move.ToPosition).IsPlayer2;
Run Code Online (Sandbox Code Playgroud)

为了进一步将其扩展到您的MMORPG场景,我将通过参数传递任何"源"和/或"目标"

  • 即碰撞源/目标,或任何直接受影响的对象

结论

与国家问题如此相似,我认为看一下基于状态的解决方案是个好主意.

例如,状态模式,有限状态机,状态转换表,自动机等.

或者你可以尝试查找决策表和决策树(我自己没有真正使用过这些,所以我无法对它们说太多).

不幸的是,我认为我不能推荐一个确切的解决方案.

但希望上面的几个示例/关键字可以帮助您入门.