/** * An instance of this class (UmpireClicker2) represents a device commonly * used by baseball/softball umpires to keep track of the inning, outs, * balls, and strikes. The physical device is hand-held. * * This class improves UmpireClicker1 by its use of the private method * wrapAroundIncrement(). * * @author P.M.J. (modified by R.W.M.) * @version 2009-09-10 */ public class UmpireClicker2 { // Symbolic Constants //======================================================================== private static final int MAX_INNING = 9; private static final int MAX_OUT = 3; private static final int MAX_BALL = 4; private static final int MAX_STRIKE = 3; // Instance Variables //======================================================================== private int inning; // wraparound counter over the range 0..MAX_INNING private int out; // wraparound counter over the range 0..MAX_OUT private int ball; // wraparound counter over the range 0..MAX_BALL private int strike; // wraparound counter over the range 0..MAX_STRIKE // Constructor(s) //======================================================================== /** Initializes attributes so that the counts for inning, outs, balls, and ** and strikes are all zero. ** (Note: Numeric instance variables are automatically initialized ** to zero, so the body of this constructor can be omitted.) */ public UmpireClicker2() { inning = 0; out = 0; ball = 0; strike = 0; } // Observer Method(s) //======================================================================== /** Returns the inning count. * @return The inning count */ public int getInning() { return inning; } /** Returns the out count. * @return The out count */ public int getOut() { return out; } /** Returns the ball count. * @return The ball count. */ public int getBall() { return ball; } /** Returns the strike count. * @return The strike count. */ public int getStrike() { return strike; } // Mutator Method(s) //======================================================================== /** Advances the inning count. */ public void advanceInning() { inning = wrapAroundIncrement(inning, MAX_INNING); } /** Advances the out count. */ public void advanceOut() { out = wrapAroundIncrement(out, MAX_OUT); } /** Advances the ball count. */ public void advanceBall() { ball = wrapAroundIncrement(ball, MAX_BALL); } /** Advances the strike count. */ public void advanceStrike() { strike = wrapAroundIncrement(strike, MAX_STRIKE); } // Standard Method(s) //======================================================================== /** Returns the current count values as a printable string. */ public String toString() { return "Inning " + getInning() + ", Out " + getOut() + ", Ball " + getBall() + ", Strike " + getStrike(); } // Private Method(s) //======================================================================== /** Returns the value that results from "incrementing" the first ** parameter, 'cntrVal', under the assumption that it is a "wraparound" ** counter with range 0..'upperBound' (the second parameter). ** ** (A wraparound counter has the property that incrementing it corresponds ** to adding one, except if its value is the maximum of its range, in ** which case incrementing it sets it to the minimum of its range.) ** ** Remark: The local variable 'result' is unnecessary, as each of ** its three uses can be replaced by cntrVal. ** ** @param cntrVal The value of the counter to be incremented ** @param upperBound The maximum value in the range of the counter ** to be incremented */ private int wrapAroundIncrement(int cntrVal, int upperBound) { int result; if (cntrVal == upperBound) { result = 0; } else { result = cntrVal + 1; } return result; /* Note: Assuming that cntrVal is in the range 0..upperBound (which is, * indeed, the intent here), an equivalent method body is * * return (cntrVal + 1) % (upperBound + 1) */ } }