为Scrabble的游戏实施设计灵活且可扩展的奖励系统

时间:2010-10-25 21:57:51

标签: c# java oop software-design architecture

假设我正在实施我自己的Scrabble版本。 我目前有一个包含大量Board的{​​{1}}类。 Squares依次由SquareIBonus组成。奖金实施实际上是拼字游戏的常用奖励,但有可能我会尝试添加一些新的和扭曲的奖金以增加游戏的灵活性 - 这里的灵活性至关重要!

alt text

经过一段时间的思考,我得出的结论是,Piece实施工作,他们需要知道整个IBonus及其当前位置(Board ,所以它知道它在哪里,它可以检查与奖金在同一方格中的那块。)这让我感觉很糟糕,基本上它需要知道很多信息。

所以,我的天真实现是将Board作为参数传递给Board方法IBonus.calculate(),即。{/ p>

此外,它似乎创建了一个循环引用。还是我错了? alt text

我不喜欢这种方法,所以我正在寻找其他可能的方法。我知道我可以让IBonus.calculate(Board board, Point position)接受一个接口而不是一个具体的类,即calculate,但我的IMO并不比第一种情况好。

我担心过于专注于我目前的实施,能够想到至少能够解决这个问题的完整不同的设计。 也许我可以重新设计整个游戏并在其他地方获得奖金,这样可以促进这种计算吗?也许我过于专注于将它们放在calculate(IBoard board)上?我当然希望有其他方法可以解决这个问题!

由于

4 个答案:

答案 0 :(得分:4)

我认为Board具有游戏的可见状态,并且会有其他对象,例如Rack(每个玩家一个)和DrawPile。

“如果单词包含真实(非空白)Z,则双重得分” - 需要您传入Word,或者单词以及单词的位置。

“如果这个词在董事会中最长,那么双重得分”需要整个董事会。

“如果单词的第一个字母与DrawPile中随机选择的字母匹配,则为双重分数”当然需要DrawPile。

所以对我而言,这取决于你实施的规则。我很乐意将董事会传递给IBonus得分()实施。

编辑 - 更多想法。

所以一块板子有17x17个正方形,或者其他什么。我将一个IBonus实现分配给每个方块(有一个名为PlainEmptySquare的实现是惰性的。)你只需要实例化IBonus的每个实现一次 - 它可以被多次引用。我可能会走低路并明确地实例化每一个,传递所需的参数。如果一种类型需要Board,则将其传入。如果另一种类型需要DrawPile,则将其传入。在您的实现中,您可能有12行丑陋。 /耸肩

答案 1 :(得分:1)

以下内容可能有效:

CurrentGame有一个Board,其集合为SquaresSquare可能有IBonus,但Calculate()上没有Square方法。 Square可能有Piece,而Piece可能有Square(即正方形可能是或可能不是空的,一块可能有也可能没有放在董事会上。)

Board还有一个calculateScoreForTurn()方法可以接受Pieces的集合,代表刚刚放置在棋盘上的那些棋子。 Board知道有关刚放置的棋子和方块的所有信息,以及周围或相交的棋子和方块(如果适用),因此具有计算得分所需的所有信息。

答案 2 :(得分:1)

  

这让我感觉很糟糕   需要了解很多   信息

我认为这是必要的。您只是将引用传递给电路板,而不是实际上导致大量数据移动。

答案 3 :(得分:1)

董事会本身可能必须推动一轮特定的得分。随着每个瓷砖的放置,董事会会记录下来。当放置最后一个Tile(转弯)时,Board必须获得所有具有新添加的tile的Square(将计算这些Square的奖励)以及当前转向的所有先前放置的Tiles复用”。

例如,播放CAT

C A T

C属于双字母得分。所以,转牌的得分是C.Value * 2 + A.Value + T.Value。

下一位玩家放置一个S来制作CATS。 S属于三位一词。所以,转牌的得分是(C.Value + A.Value + T.Value + S.Value)* 3。当应用Tile's Bonus时,它必须是“Deactivated”,以便将来“重新使用”该Tile也不会获得奖励。

这意味着一些奖金适用于放置在广场上的瓷砖,而其他奖金适用于组成新单词的瓷砖集合,这些单词是在计算单个字母的奖金之后。

如果一个或多个Square在转弯时已经填充了Tile,则棋盘可以找到通过向左移动直到棋盘边缘创建的Word的开头(或直到空方块)并遍历到相同的条件。委员会可以找到通过类似地向右和向下遍历创建的单词的结尾。每次新放置的Tile与现有Tile相邻时,您还必须遍历单词的开头和结尾(您可以在转弯时创建多个单词)。

给定一个单词集合(每个单词由一个包含可能的LetterBonus的Square和一个带有Value的Tile组成),Board(或每个Word本身)计算BaseValue(Tiles的值的总和 - 应用任何LetterBonuses)然后应用WordBonus(如果有的话)来获得Word的最终价值。