Разработка гибкой и расширяемой системы бонусов для игровой реализации Scrabble - PullRequest
6 голосов
/ 26 октября 2010

Допустим, я внедряю свою собственную версию Scrabble.В настоящее время у меня есть класс Board, который содержит много Squares.A Square в свою очередь состоит из IBonus и Piece.Реализация бонусов на самом деле является обычным бонусом для Scrabble, но возможно, что я попытаюсь добавить какой-то новый и извращенный бонус, чтобы привнести в игру особую гибкость - гибкость здесь имеет первостепенное значение!

alt text

Подумав некоторое время, я пришел к выводу, что для реализации IBonus им потребуется знать весь Board, а также его текущую позицию (на Board, поэтому он знает, где он находитсяи он может проверить на кусок, который находится в той же площади, что и бонус).Это поражает меня так же плохо, как и в основном нужно знать много информации.

Итак, моей наивной реализацией было бы передать Board в качестве аргумента методу IBonus.calculate(), IBonus.calculate(Board board, Point position), то есть.

Кроме того, похоже, создается циклическая ссылка.Или я не прав?alt text

Мне не нравится этот подход, поэтому я ищу другие возможные подходы.Я знаю, что могу calculate принять интерфейс вместо конкретного класса, т. Е. calculate(IBoard board), но я думаю, что не все так хорошо, как в первом случае.

Боюсь, что я слишком сосредоточен на своемтекущая реализация, чтобы иметь возможность думать о совершенно разных проектах, которые могли бы соответствовать как минимум, а также решения этой проблемы.Может быть, я мог бы перестроить всю игру и получить бонусы в другом месте, чтобы это облегчило этот расчет?Может быть, я слишком сосредоточен на том, чтобы иметь их на Board?Я, конечно, надеюсь, что есть другие подходы к этой проблеме!

Спасибо

Ответы [ 4 ]

4 голосов
/ 26 октября 2010

Я предполагаю, что доска имеет видимое состояние игры, и будут другие объекты, такие как Стойка (по одному на игрока) и DrawPile.

"Двойной счет, если слово содержит реальный (непусто) Z "- потребует, чтобы вы передали слово или доску и позицию слова.

" Двойной счет, если слово является самым длинным на доске ", требует всей доски.

«Двойной счет, если первая буква слова соответствует случайно выбранной букве из DrawPile», конечно, требует DrawPile.

Так что для меня это зависит только от правил, которые вы применяете.Мне было бы удобно передать Board в реализацию IBonus Score ().

edit - больше мыслей.

Таким образом, доска имеет 17x17 квадратов или что-то еще.Я бы назначил реализацию IBonus для каждого квадрата платы (была бы реализация под названием PlainEmptySquare, которая была бы инертной.) Вам нужно было бы только создать экземпляр каждой реализации IBonus один раз - на нее можно было бы ссылаться много раз.Я бы, вероятно, выбрал низкую дорогу и подробно описал каждый из них, передав необходимые аргументы.Если одному типу нужна доска, передайте его. Если другому нужен DrawPile, передайте его. В вашей реализации у вас может быть 12 линий уродства./ Пожав плечами

1 голос
/ 26 октября 2010

Правлению, вероятно, придется вести подсчет очков за данный раунд.Когда каждая плитка размещена, Правление отмечает это.Когда последний Тайл (за ход) был размещен, Правление должно получить все Квадраты, у которых есть недавно добавленный тайл (Бонус за эти Квадраты будет подсчитан) И И все ранее размещенные Тайлсы, которыми является текущий ход.многократное использование ".

Например, игра CAT

CAT

C падает на счет двойной буквы.Таким образом, на терне получается C.Value * 2 + A.Value + T.Value.

Следующий игрок ставит S, чтобы сделать CATS.S падает на счет тройного слова.Таким образом, счет за ход (C.Value + A.Value + T.Value + S.Value) * 3.Когда бонус плитки применен, он должен быть «деактивирован», чтобы будущие «повторные использования» этой плитки также не получали бонус.

Подразумевается, что некоторые бонусы применяют плитку, размещенную на площади, в то время какдругие относятся к коллекции плиток, составляющих новое слово ПОСЛЕ того, как были рассчитаны бонусы для отдельных букв.

Учитывая один или несколько квадратов, которые были заполнены плиткой в ​​течение хода, доскаможно найти начало слова (слов), которые были созданы путем перемещения влево до края доски (или до пустого квадрата) и перемещения до тех же условий.Доска может найти Конец Слова (й), которые были созданы аналогичным движением вправо и вниз.Вы также должны переходить к началу и концу слов каждый раз, когда вновь размещенная плитка соседствует с существующей плиткой (вы можете создать много слов за ход).

Учитывая набор слов (каждый состоит изКвадрат, содержащий возможный LetterBonus и Плитку со значением), Board (или каждое само слово) вычисляет BaseValue (Сумма значений Tiles - применяя любые LetterBonuses), а затем применяет WordBonus (если есть), чтобы получить окончательное значениеСлова.

1 голос
/ 26 октября 2010

Мне кажется, что это так плохо нужно знать много информация

Я думаю, что это необходимо. Вы просто передаете ссылку на доску, а не перемещаете большие объемы данных.

1 голос
/ 26 октября 2010

Может работать что-то вроде следующего:

CurrentGame имеет Board, который имеет коллекцию SquaresSquare может быть IBonus, однако на Square нет метода Calculate().Square может иметь Piece, а Piece может иметь Square (т. Е. Квадрат может быть или не быть пустым, а часть может быть или не быть размещена на доске).

Board также имеет метод calculateScoreForTurn(), который принимает коллекцию Pieces, представляющую фигуры, которые были только что размещены на доске для этого хода.Board знает всю информацию о фигурах и квадратах, которые только что были размещены, а также окружающие или пересекающиеся фигуры и квадраты (если применимо) и, таким образом, обладает всей информацией, необходимой для вычисления результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...