2013-01-16 68 views
3

什么样的设计模式可以用来创建类似国际象棋的游戏规则/验证系统(这只是一个简单的例子,实际的游戏需要更加困难的规则集)规则/验证设计模式

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

该系统需要以下内容:已应用到它应该实现特定 接口是用于验证

  • 规则应适用的出发点的方法规则

    • 每个对象分两步:首先需要验证 (可以棋子移动到D4方格),如果是true,则执行方法 A如果为false,则执行方法B
    • 每个对象都可以有多个规则需要应用一个 特定序列。当规则1结束后,第2条应该然后开始 验证等
    • 每一个单独的规则(例如:只能移动1格,只能 移动斜等)必须在其自己的类,并且必须是可重复使用的 和适用于需要规则的对象。
    • 注意这会在多人游戏中使用的后端
    • 注意,每一个规则需要多个对象,以测试它的有效性,为 例如,正常的棋子可以移动1格,现在 下一sqaure该游戏板充满了你的对手的典当。结果:你的棋子 不能移动。棋子应该包括其他棋子的位置,或者在其验证中包含的棋子。

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

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

  • 回答

    1

    我在想你的问题的Specification Pattern方法。

    +0

    谢谢,我一定会仔细看看它。我已经看到这种模式在其他答案中被命名,但我不完全确定如何实现这一点。 – Thomas

    1

    这是我将如何设计它。 (可能会或可能不会对应某种设计模式)。

    abstract class Rule<T> 
    { 
        protected abstract bool implementRule(T on, GameWorld gw); 
    
        protected abstract void doIfTrue(); 
    
        protected abstract void doIfFalse(); 
    
        public void runRule(T on, GameWorld gw) 
        { 
         if (implementRule(on, gw)) 
         { 
          doIfTrue(); 
         } 
         else 
         { 
          doIfFalse(); 
         } 
        } 
    
    } 
    

    然后,假设你有一些类/接口称为棋子,具有的getX()方法,你可以这样做

    class RuleImpl : Rule<Pawn> // note T is now Pawn 
    { 
    
        protected override bool implementRule(Pawn on, GameWorld gw) { 
         if(on.getX()<gw.getX()){ 
          return true; 
         } 
    
         return false; 
        } 
    
    
        protected override void doIfTrue() 
        { 
         Console.WriteLine("true"); 
    
        } 
    
    
        protected override void doIfFalse() { 
         Console.WriteLine("false"); 
    
        } 
    } 
    

    编辑:自然典当可以而且应该改变为界面如。但为了代码清晰度,我将它保留原样

    2

    我在想,Strategy Pattern可能是您要找的,它比HuorSwords建议的规范模式更轻,如果您正在寻找更容易入门的应用程序用。

    您希望使用的规则可以被抽象为策略,然后根据需要插入每一块。

    每个规则都可以保存在它自己的类中。

    每个策略都可以按照您要求的顺序建立一系列规则。

    +0

    你能否更新答案中的链接?它目前404s。 –

    7

    我越看问题,我就会想到更多的状态/流程图。

    enter image description here

    • 具有施加到其上规则应实现与作为用于验证

    • 规则应在2所施加的起点的方法的特定的接口中的每个对象步骤:首先,它需要被验证(可以棋子移动到D4方格),如果是则执行方法A如果为false,则执行方法B

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

    甲转变包括:

    1. 条件(一个或多个)
    2. 动作(一个或多个)
    • 每个对象可以有多个规则需要在要被施加特定序列。当规则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;} 
    } 
    

    与此同时,各州应该能够访问整个游戏键盘。 这使得该州做的事情一样

    // Check for empty cell 
    GameBoard.GetPieceAt(move.ToPosition) == null; 
    
    // Check for opponent's piece 
    GameBoard.GetPieceAt(move.ToPosition).IsPlayer2; 
    

    为了进一步通过参数这扩展到您的MMORPG的情况下,我会通过任何“源”和/或“目标”

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

    结论

    与状态问题非常相似,我认为查看基于状态的解决方案是一个不错的主意。

    例如,State Pattern,有限状态机,状态转变表,自动机等

    或者你可以尝试寻找了决策表和决策树(还没有真正使用这些我自己,所以我无法对他们说很多)

    不幸的是,我不认为我可以推荐一个确切的解决方案。

    但希望上面的几个例子/关键字将帮助您开始。