2009-12-16 87 views
3

我正在开发简单棋盘游戏等通用游戏引擎。我定义了需要每个游戏实现的接口,我有IGame,IGameState,IBoardEvaluator和IMove等类。如何分组泛型类?

我有像IGame.PerformMove(IMove移动),我想限制的方法。如果我玩井字游戏,我想强制我只能使用具体的类TTTGame,TTTState,TTTMove等......

我可以想到几种方法来做到这一点,但没有一个听起来有趣。也许所有的类都可以有一个通用参数,我可以确保它匹配。

so IGame<T> has method PerformMove(IMove<T> move) 

如果这样做,我不知道用什么类T也许没关系。

我的另一个想法是在IGame上放上一堆泛型参数并给它所需的所有类。所以我会创建class TTTGame<TTTMove,TTTState,TTTMove....>

这也不是很好。是否有共同的模式来做到这一点?

+3

也许你正试图想太多前期。你应该尝试从一个简单的游戏实现开始,然后重构你的代码使其更加通用。 – Costo 2009-12-16 05:54:49

回答

2

我没有看到从指定您的TTTGame类只能使用TTTMoves得到的优势。

我想你可能会在这里工程。

通过这样做,您唯一能够保护自己的就是一些流氓MonopolyMove类变得自我意识并将自己置于您的代码中。

我说坚持接口定义,避免泛型,除非你有一个真正有效的案例。我没有看到一个基于你提到的。

+0

那么这个想法是,如果我有一个TTTGame,我想能够用TTTMove执行MoveMove(),并假设它是一个TTTMove,而不是一个垄断移动。我宁愿不必投射和检查每种方法。 – captncraig 2009-12-16 06:00:17

+0

您不必检查它是否是TTTMove。理想情况下,TTTMove从IMove继承。如何移动的代码我期望被声明为IMove :: Move(),并在TTTMove :: Move()中定义(使用重写的方法)。 我不会尝试编写代码,以防有人用MonopolyMove调用PerformMove(),因为为什么任何代码在TicTacToe游戏中使用MonopolyMove? – santosc 2009-12-16 06:06:21

+0

也许你是对的。我试图尽可能地强化它。我将不得不将它转换为TTTMove,如果失败了,我会得到一个NullReference。让我在那里投掷垄断。 – captncraig 2009-12-16 06:13:12

1

接口的要点是不关心类的具体实现。因此,我认为没有必要直接强制执行某个类,在这种情况下,可以通过类本身来进行论证。

TTTGame : IGame 
{ 
    PerformMove(TTTMove move); 
} 

也许这是你在说什么。现在

public interface IGame<T> where T:IMove 
    { 
     void PerformMove(T move); 
    } 

public class TTTGame : IGame<TTTMove> 
    { 

     public void PerformMove(TTTMove move) 
     { 
      //perform move 
     } 

    } 

您的iGame被迫采取IMOVE,但像你一样said..with多个类(IState..etc),这将导致混乱快捷。

+0

那么重点是如果IGame接口指定了PerformMove需要一个IMove,那么我可以给它任何类型的移动。您的版本不是IGame的有效实施。 – captncraig 2009-12-16 05:57:41

+0

更新了我的答案。 – 2009-12-16 06:14:27

1

我想说,你感觉需要限制你的接口到某些类的实现是一个接口不够具体的指示。

IGame真的是个好主意吗?这个名字表明它可能对tic-tac-toe和Quake同样有效。当然,在不同的棋盘游戏之间有一些相似之处(比如表演动作),但是你真的能从在这个高水平创建抽象中受益吗?

+0

那么这个想法是,我可以创建游戏不可知论者,演示者和AI代理,可以玩任何符合界面的游戏。目标是检查多人回合制游戏中的某些AI策略。 – captncraig 2009-12-17 17:12:34