Java - совет Дизайна для простой игры

Я реализую простую "Игру Ваше право карт" (иначе известный как выше/ниже) игра. В случае, если Вы не столкнулись с ним, прежде чем правила будут действительно просты. Используется единственный иск карт (например, основы). Одна карта оттянута за один раз, и цель состоит в том, чтобы правильно предположить, будет ли номинальная стоимость следующей карты выше или ниже, чем номинальная стоимость ранее оттянутой карты.

Логика для игры не особенно сложна, я не волнуюсь по поводу этого. Я придумал дизайн, но я не совсем доволен им. Существует несколько областей, где я уверен, что это могло быть улучшено, и это - то, относительно чего я хотел бы Ваш совет. Вот интерфейс для класса (комментарии для дополнительного понимания, не реальные комментарии):

public interface PlayYourCardsRight {

/**
 * Get the number of cards remaining with higher face values than the previously
 * drawn card
 * @return
 */

public abstract int getNumberCardsHigher();

/**
 * Get the number of cards remaining with lower face values than the previously
 * drawn card
 * @return
 */

public abstract int getNumberCardsLower();

/**
 * Get all cards that have already been drawn in the order they were drawn in
 * 
 */

public abstract List<Card> getPlayedCards();

/**
 * Simple prediction algorithm  - if there are more cards left in the deck with
 * lower face values than the previous card, then predict 'Lower', if there 
 * are more cards left in the deck with higher face values then predict
 * 'Higher', if there are equal numbers of higher/lower cards pick 'higher' or     'lower'
 * at random
 *
 * Prediction is an Enum (Higher/Lower/None)
 *
 */

public abstract Prediction getPrediction();

/*
 * Draw the next card at random
 */

public abstract void nextRound();

/**
 * Specifiy what the next card should be
 * 
 * @param card
 */

public abstract void nextRound(Card card);

}

Поскольку Вы видите, что это - все справедливо сам объяснительный и простой. Вот мои проблемы:

Я не хочу, чтобы конструктор автоматически потянул карту. Это означает, что первоначально нет никакой "ранее оттянутой карты". У меня есть a NO PREDICTION значение в Prediction перечисление, но, как нет никакой "ранее оттянутой карты" getNumberCardsHigher() и getNumberCardsLower() методы не могут возвратить нормальные значения (они не могут также возвратить нормальные значения, когда все карты из деки были оттянуты).

Очевидно, я мог просто выдать исключение, но это походит на излишество - тем более, что затем все вызовы к методам затем должны быть перенесены в попытку/выгоды. Я также недоволен возвращением отрицательного значения, так как это могло легко привести к некоторым ошибкам, если кто-то забывает/может быть побеспокоенным для проверки на них.

Все приветствующиеся предложения!

5
задан BalusC 23 October 2011 в 15:24
поделиться

4 ответа

Лично я не думаю, что бросать непроверенное исключение в случае проверки аргументов - это вообще излишество - это при условии, что ваш код утверждает недопустимое состояние (Вы не должны вызывать эти методы с объектом в этом состоянии, НИКОГДА).

Обычно я использую IllegalArgumentException, чтобы показать, что был передан аргумент, который не соответствует контракту вызова метода, и IllegalStateException, чтобы показать, что объект не в том состоянии, чтобы обработать вызов метода в данный момент.

Поскольку они оба являются непроверенными исключениями, вам не нужно пытаться/ловить их, просто позвольте им всплыть, они делают то, что исключения делают отлично - они дают вам трассировку стека и говорят вам, где именно находится ваша ошибка, включая того, кто вызвал ее неправильно.

Кстати, я обычно использую какую-то строку, в вашем случае это может быть:

throw new IllegalStateException("You cannot call this method until a card has been drawn");

Логически не имеет смысла спрашивать, выше или ниже карта, чем карта, которой не существует.

Теперь, если ваш метод действительно ПРОВЕРЯЕТ это исключение, то вы должны пойти дальше и исправить свой код так, чтобы он не вызывал этот метод до тех пор, пока не вытянет карту - так что вам придется придумать, как вытянуть первую карту независимо от этого.

Примечание: Исключения предназначены только для обнаружения ошибок, избегайте их использования для управления потоком. Это означает, что вы не должны пытаться поймать исключение и использовать его для розыгрыша карты, а затем вызвать снова! Вместо этого вы должны составить программу таким образом, чтобы гарантировать, что карта будет нарисована до первого вызова методов.

3
ответ дан 15 December 2019 в 06:14
поделиться

Я бы сказал, что оба метода должны возвращать card.count , когда не было вытянутой предыдущей карты. Осталось одинаковое количество младших и более высоких карт, и для обоих есть количество карт больше / меньше карт, чем ничего. Тогда ваш алгоритм будет работать и вернет NO_PREDICTION .

0
ответ дан 15 December 2019 в 06:14
поделиться

Я бы лично рекомендовал иметь начальную карту до того, как игрок что-либо сделает, поскольку не имеет смысла, чтобы игрок делал что-либо до того, как первая карта будет поднята, но я думаю, что "Я не хочу, чтобы конструктор автоматически рисовал карту" означает, что вы не хотите этого делать. Если вы не хотите этого делать, я бы сделал так, чтобы функции бросали исключения, а код, который их вызывает (функция предсказания), в специальном случае в начале игры возвращал "нет предсказания" вместо того, чтобы даже пытаться их вызвать. Конец игры не является особым случаем; обе функции должны возвращать 0, так как в колоде не осталось карт выше или ниже карты "вверх"

Также нет необходимости объявлять каждую функцию abstract в интерфейсе, это автоматически и обязательно

.
0
ответ дан 15 December 2019 в 06:14
поделиться

Я не хочу, чтобы конструктор автоматически вытягивал карту. Это означает, что изначально нет «ранее взятой карты». У меня есть значение NO PREDICTION в перечислении Prediction, но, поскольку нет «ранее нарисованной карты», методы getNumberCardsHigher () и getNumberCardsLower () не могут возвращать разумные значения (они также не могут возвращать разумные значения, когда все карты из колоды нарисованы).

Я думаю, что путаница с API возникает из-за того, что ваш интерфейс PlayYourCardsRight пытается моделировать две отдельные вещи: игровой движок / правила и колоду карт. Я бы переместил состояние колоды карт и методы подсчета оставшихся карт в класс Deck . Я бы изменил API на getNumberCards [Higher / Lower] (Card) и позволил игровому движку указывать, с какой картой вы хотите сравнивать, вместо того, чтобы ожидать, что колода запомнит, какая карта была взята последней, что я бы сделал видеть как элемент состояния игры, а не колоды.

И я настоятельно рекомендую написать несколько тестов JUnit. TDD помогает создавать целостный, несвязанный API.

0
ответ дан 15 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: