[英]Java - Design advice for simple game
我正在实施一个简单的“正确播放你的牌”(也就是所谓的更高/更低)游戏。 如果您在规则非常简单之前没有遇到过它。 使用一套卡片(例如心形)。 一次绘制一张牌,目的是正确猜测下一张牌的面值是高于还是低于先前绘制的牌的面值。
游戏的逻辑并不是特别复杂,我并不担心。 我想出了一个设计,但我并不完全满意。 有几个方面我确信它可以改进,这就是我想要你的建议。 这是该类的接口(有关其他理解的注释,而不是真正的注释):
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);
}
正如你所看到的那样,这些都是相当自我解释和简单的。 这是我的问题:
我不希望构造函数自动绘制卡片。 这意味着最初没有“先前抽取的卡片”。 我在Prediction
枚举中有一个NO PREDICTION
值,但由于没有“先前绘制的卡片”, getNumberCardsHigher()
和getNumberCardsLower()
方法无法返回合理的值(当所有卡片都来自甲板时,它们也不能返回合理的值已被绘制)。
显然,我可以简单地抛出一个异常,但这似乎有点过分 - 特别是因为所有对方法的调用都必须包含在try / catches中。 我也不满意返回一个负值,因为如果有人忘记/无法检查它们,这很容易导致一些错误。
欢迎所有建议!
就个人而言,我认为在参数检查的情况下抛出一个未经检查的异常根本就不合适 - 这假设您的代码声明了一个无效状态(您不应该使用该状态中的对象调用这些方法,EVER)。
我通常使用IllegalArgumentException来显示已经传入的参数不符合方法调用的约定,并且使用IllegalStateException来显示该对象此时未处于处理方法调用的状态。
由于它们都是未经检查的异常,因此您不必尝试/捕获它们,只需让它们冒泡,它们就会做出异常擅长的事情 - 它们会为您提供堆栈跟踪并告诉您错误的确切位置,包括任何调用者它不正确。
顺便说一句,我通常使用某种字符串,在你的情况下它可能是:
throw new IllegalStateException("You cannot call this method until a card has been drawn");
从逻辑上讲,询问卡是否高于或低于不存在的卡是没有意义的。
现在,如果你的方法实际上是那个异常,那么你必须继续修改你的代码,这样它就不会在它绘制卡片之前调用那个方法 - 所以你必须弄清楚如何绘制你的第一张卡片。
注意:例外仅用于错误检测,避免将它们用于流控制。 这意味着您不应该尝试捕获异常并使用它来绘制卡然后再次调用! 相反,您应该以这样的方式编程,以确保在第一次调用方法之前绘制卡片。
我认为两种方法都应该返回card.count
,因为之前没有绘制过的卡片。 存在相同数量的较低和较高的卡,并且对于两者而言,卡计数更高/更低的卡比没有更多。 然后,您的算法将起作用并返回NO_PREDICTION
。
我个人建议在玩家做任何事之前先拿一张初始卡,因为让玩家在第一张牌出现之前做任何事都没有意义,但我认为“我不希望构造者自动画一张牌“意味着你不想那样做。 如果你不想这样做,我会让函数抛出异常,并让代码调用它们(预测函数)特殊情况,游戏开始时返回“无预测”而不是试图调用它们。 游戏结束不是特例; 两个函数都应返回0
,因为没有卡高于或低于卡中剩余的向上卡
此外,没有必要在接口中声明每个函数abstract
,它是自动和必需的
我不希望构造函数自动绘制卡片。 这意味着最初没有“先前抽取的卡片”。 我在预测枚举中有一个NO PREDICTION值,但由于没有“先前绘制的卡片”,getNumberCardsHigher()和getNumberCardsLower()方法无法返回合理的值(当所有卡片都来自甲板时,它们也不能返回合理的值已被绘制)。
我认为API的混乱源于你的PlayYourCardsRight
界面试图模拟两个独立的事物:游戏引擎/规则和卡片组。 我会将卡片组的状态和剩余的卡片计数方法移动到Deck
类。 我会将API更改为getNumberCards[Higher/Lower](Card)
并让游戏引擎指定您想要比较哪张牌而不是期望牌组记住最后绘制的牌,我将其视为该牌的一个元素。游戏的状态,而不是甲板的状态。
我强烈建议编写一些JUnit测试。 TDD有助于生成一个内聚的,解耦的API。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.