Counter
class that we saw in lecture has a method, tick,
which increments the counter and wraps the counter's value back to 0
if incrementing causes the counter to hit its upper limit.
Your job is to add to the Counter class a method,
advance that takes one parameter, an int. A
call to advance adds the value of the parameter into the
value of the counter. For example, if c references a
Counter object, then the following would be equivalent:
int n whose value was nonnegative
(i.e., 0 or positive), the following would be equivalent:
You might think that you could just write the body of the
advance method as a for-loop that calls tick
the right number of times. This approach suffers from two problems.
First is that it is quite inefficient if the parameter given in a call
of advance is large: you'd end up calling
tick that many times.
The second reason is more serious: the parameter to
advance is allowed to be negative. In this case, the
counter should run backward. What would happen if you ran the
following for-loop when n is negative?
c references a counter with a limit of 5 (so that it
could take on the values 0, 1, 2, 3, or 4) and a current value of 2.
Suppose further that we call c.advance(-3). Then after
the call, the counter should have the value 4. Why 4? Think of it
this way: if the counter had the value 4 and we called
c.advance(3), it would end up with the value 2.
Now that we've ruled out using a for-loop, think about using the
modulus operator (%). Using our example of a counter
with limit 5 and value 4, observe that (4 + 3) % 5 gives
2: the same value as advancing by 3.
So it seems that the modulus operator is great here, and it is. Except that there's one other problem. If you mod a negative number, you might get a negative number:
0 % 5 gives 5
-1 % 5 gives -1
-2 % 5 gives -2
-3 % 5 gives -3
-4 % 5 gives -4
-5 % 5 gives 0
-6 % 5 gives -1
-7 % 5 gives -2
-8 % 5 gives -3
-9 % 5 gives -4
-10 % 5 gives 0
Counter should never have a negative value, so
if you get a negative value after modding, you need to correct it to
make it positive. Using our example counter with a limit of 5,
observe that if you get the value -1 after modding, you really want
your counter to have the value 4; if you get -2, you really want 3; if
you get -3, you really want 2; and if you get -4, you really want 1.
There's a very simple pattern here that you can easily
exploit in your program with simple arithmetic.
So, to recap, your advance method needs to first update
the counter's value by performing a mod operation that uses the
current counter value, the amount to advance by, and the counter's
limit. Then, if the new value is negative, the method needs to adjust
it to make it the appropriate positive value. You should be able to
write the body of advance in three lines of Java, plus
comments.
Modify the Counter class to add the advance
method, and modify the CounterDriver
class to show some calls of advance. Make sure that
your calls demonstrate that advance does the right thing
when
advance is positive but the
counter does not wrap around,
advance is positive and the
counter does wrap around,
advance is negative but the
counter does not wrap around,
advance is negative and the
counter does wrap around.
Hand in printouts of your Counter and
CounterDriver classes, along with the output of running
the program.