Development of a flexible and extensible bonus system for the implementation of the game Scrabble

Say I'm implementing my own version of Scrabble. I currently have a Board class that contains a lot of Squares . A Square , in turn, consists of a IBonus and a Piece . Bonus implementation is actually a regular bonus for Scrabble, but it is possible that I can try to add a new and twisted bonus to spice up the game - flexibility is of utmost importance here.

alt text

After thinking for a while, I came to the conclusion that in order to implement IBonus for work, they need to know the whole Board , as well as its current position (on the Board , so she knows where it is, and he can check an item that is on the same area as a bonus). This seems bad to me, because basically he needs to know a lot of information.

So, my naive implementation would be to pass the Board argument as the IBonus.calculate() , IBonus.calculate(Board board, Point position) method, which is.

In addition, a circular reference is created. Or I'm wrong? alt text

I do not particularly like this approach, so I am looking for other possible approaches. I know that I can do calculate reception of an interface instead of a specific class, i.e. calculate(IBoard board) , but I'm IMO, which is not so much better than the first case.

I am afraid to be too focused on my current implementation to be able to think of a whole variety of different projects that can fit, at least as well as solutions to this problem. Maybe I could redesign the whole game and get bonuses elsewhere to facilitate this calculation? Maybe I'm too focused on getting them on Board ? Of course, I hope that there are other approaches to this problem!

thanks

+6
java c # oop architecture software-design
source share
4 answers

I assume that Board has a visible state of the game, and there will be other objects such as Rack (one per player) and DrawPile.

“Double point if the word contains a real (not empty) Z” - it would take you to pass in Word, or Board, and in the position of the word.

“Double point if the word is the longest on the board,” the entire board is required.

“Double point if the first letter of a word matches a randomly selected letter from DrawPile,” of course, requires DrawPile.

So for me it just depends on the rules that you implement. I would be comfortable with passing the Board to the implementation of IBonus score ().

edit - more thoughts.

So, the board has 17x17 squares or something else. I would assign an IBonus implementation to each square of the board (an implementation called PlainEmptySquare, which was inert, would be implemented). You only needed to instantiate each implementation of IBonus once - it can be referenced many times. I’m likely to take care of the low road and explicitly create an instance by passing the necessary arguments. If one type needs advice, pass it on. If another needs a DrawPile, pass it on. In your implementation you will have 12 lines of ugliness. / Shrug

+4
source share

Perhaps something like the following:

CurrentGame has a Board that has a set of Squares . A Square may have IBonus, however on Square there is no Calculate() method. A Square may have a Piece , and a Piece may have a Square (i.e. a Square may or may not be empty, and a part may or may not be placed on the board).

Board also has a calculateScoreForTurn() method that would accept a Pieces collection representing the pieces that have just been placed on the board for this move. Board knows all the information about the objects and squares that have just been placed, as well as the surrounding or intersecting pieces and squares (if applicable) and, therefore, has all the information necessary to calculate the score.

+1
source share

It looks to me as bad as basically you need to know a lot of information

I think it is necessary. You simply pass the link to the board, and not really force them to move large amounts of data.

+1
source share

The council may have to keep score for this round. As each tile fits, the Council notices this. When the last tile (for reversal) was placed, the Council should receive all the squares that have the added tile (the bonus for these squares will be calculated) And all the previously placed tiles, that the current turnover is reuse. "

For example, play CAT

CAT

C falls on a double letter rating. So, the estimate for the move is C.Value * 2 + A.Value + T.Value.

The next player places S to do CATS. S falls on Triple Word. So, the evaluation for the move (C.Value + A.Value + T.Value + S.Value) * 3. When the Tile Bonus is applied, it must be “Deactivated” so that future “reuse” of this tile also does not receive the Bonus.

It is understood that some bonuses apply to the Tiles placed on the Square, while others refer to the collection of Tiles that make up the new Word AFTER Bonuses for individual letters.

Given one or more squares that were filled with tile (s) during the rotation, the Board can find the beginning of the Word (s) that were created by moving left to the edge of the board (or until an empty square) and intersect to the same conditions. The Council can find the End of the Word (s) that were created in a similar way, passing right and down. You must also go to the beginning and end of words every time a newly placed tile is adjacent to an existing tile (you could create a lot of words during a turn).

Given a set of words (each of which consists of a Square containing a possible LetterBonus and a Tile with a value), the Council (or each word itself) calculates the BaseValue (Sum of Values ​​of Tiles - applying any LetterBonuses), and then applies the WordBonus (if any ) to get maximum Word value.

+1
source share

All Articles