public class VicPlus extends Vic
{
/** Tell whether any slot here or later has a CD. */
public boolean hasSomeFilledSlot()
{ String spot; // design step 1
spot = getPosition();
while (seesSlot() && ! seesCD()) // design step 2
moveOn();
boolean valueToReturn; // design step 3
valueToReturn = seesSlot();
while ( ! spot.equals (getPosition())) // design step 4
backUp();
return valueToReturn; // design step 5
} //======================
/** Move to the last CD at or after the current position. But
* if there is no such CD, stay at the current position. */
public void goToLastCD()
{ String spot; // design step 1
spot = getPosition();
while (seesSlot()) // design step 2
{ if (seesCD())
spot = getPosition();
moveOn();
}
while ( ! spot.equals (getPosition())) // design step 3
backUp();
} //======================
/** Switch the status of each slot. */
public void toggleCDs() // in a subclass of Vic
{ while (seesSlot())
{ if (seesCD())
takeCD();
else
putCD();
moveOn();
}
} //=======================
}
public class MoveToFront
{
/** Move all the CDs in the first sequence of slots up to
* the front of the sequence.
* Precondition: the stack is empty. */
public static void main (String[ ] args)
{ Vic chun; // design step 1
chun = new Vic();
String spot; // design step 2
spot = chun.getPosition();
while (chun.seesSlot()) // design step 3
{ chun.takeCD();
chun.moveOn();
}
Vic.say ("All CDs are now on the stack.");
while ( ! spot.equals (chun.getPosition()))// design step 4
chun.backUp();
while (chun.seesSlot() && Vic.stackHasCD())// design step 5
{ chun.putCD();
chun.moveOn();
}
Vic.say ("The first few slots are now filled.");
} //======================
}
/** Process a sequence of slots down to the end, usually
* without changing the current position of the executor. */
public class Looper extends Vic
{
/** Fill in the current slot and all further slots
* from the stack until the end is reached. */
public void fillSlots()
{ String spot = getPosition();
while (seesSlot())
{ putCD();
moveOn();
}
backUpTo (spot);
} //======================
/** Move all CDs in the slots into the stack. */
public void clearSlotsToStack()
{ String spot = getPosition();
while (seesSlot())
{ takeCD();
moveOn();
}
backUpTo (spot);
} //======================
/** Back up to the specified position. Precondition:
* someSpot records a slot at or before the current slot. */
private void backUpTo (String someSpot)
{ while ( ! someSpot.equals (getPosition()))
backUp();
} //======================
/** Fill in every other slot from the stack, beginning
* with the current slot, until the end. */
public void fillOddSlots()
{ String spot = this.getPosition();
while (this.seesSlot() && stackHasCD())
{ this.putCD();
this.moveOn();
if (this.seesSlot())
this.moveOn();
}
this.backUpTo (spot);
} //======================
/** Tell whether every slot here and later has a CD. */
public boolean seesAllFilled()
{ String spot = this.getPosition(); // design step 1
while (this.seesSlot() && this.seesCD()) // design step 2
this.moveOn();
boolean valueToReturn = ! this.seesSlot(); // design step 3
this.backUpTo (spot); // design step 4
return valueToReturn; // design step 5
} //======================
/** Fill in every other slot from the stack, beginning
* with the second slot, until the end. */
public void fillEvenSlots()
{ if (seesSlot())
{ moveOn();
fillOddSlots();
backUp();
}
} //======================
/** Tell whether slots 1, 3, 5, etc. all have CDs. */
public boolean seesOddsFilled()
{ String spot = getPosition();
while (seesSlot())
{ if ( ! seesCD())
{ backUpTo (spot);
return false;
}
moveOn();
if (seesSlot())
moveOn();
}
backUpTo (spot);
return true;
} //======================
/** Tell whether slots 2, 4, 6, etc. all have CDs. */
public boolean seesEvensFilled()
{ if ( ! seesSlot())
return true;
moveOn();
boolean valueToReturn = seesOddsFilled();
backUp();
return valueToReturn;
} //======================
/** Return the position for the last empty spot in
* the sequence, or the current spot if no empty spot. */
public String lastEmptySlot()
{ String spot = this.getPosition();
String lastEmpty = spot; // in case no later slot is empty
while (this.seesSlot())
{ if ( ! this.seesCD())
lastEmpty = this.getPosition();
this.moveOn();
}
this.backUpTo (spot);
return lastEmpty;
} //=======================
}
public class TwoVicUser extends Vic
{
/** Tell whether the executor has exactly the same number of
* slots as the Vic parameter. */
public boolean hasAsManySlotsAs (Vic par)
{ String thisSpot = this.getPosition(); // design step 1
while (this.seesSlot() && par.seesSlot()) // design step 2
{ this.moveOn();
par.moveOn();
}
boolean valueToReturn = ! this.seesSlot() // design step 3
&& ! par.seesSlot();
while ( ! thisSpot.equals (this.getPosition()))// d. step 4
{ this.backUp();
par.backUp();
}
return valueToReturn; // design step 5
} //=======================
}
public class Giver extends Looper
{
/** The executor gives all of its CDs to the Looper parameter,
* which distributes them to its own slots to the extent
* possible, along with any CDs originally on the stack. */
public void giveEverythingTo (Looper target)
{ this.clearSlotsToStack();
target.fillSlots();
} //======================
}
public class Interleaf
{
/** Move the first sequence's CDs to the odd-numbered slots
* of the third sequence. Move the second sequence's CDs to
* its even-numbered slots. No effect if not 3 sequences. */
public static void main (String[ ] args)
{ Vic.reset (args);
Looper one = new Looper(); // design step 1
Looper two = new Looper();
BackLooper target = new BackLooper(); // design step 2
if ( ! target.seesOddsFilled()) // design step 3
{ one.clearSlotsToStack(); // design step 3a
target.fillInReverse(); // design step 3b
}
if ( ! target.seesEvensFilled()) // design step 4
{ two.clearSlotsToStack(); // design step 4a
target.moveOn(); // design step 4b
target.fillInReverse();
}
Vic.say ("All done putting CDs in #3");
} //======================
}
public class BackLooper extends Looper
{
/** Fill slots 0,2,4,6,... ahead of the current one, reverse
* order. Precondition: The executor has at least 1 slot. */
public void fillInReverse()
{ String spot = getPosition(); // sub-design step 1
boolean movedInPairs = true; // sub-design step 2
while (seesSlot())
{ movedInPairs = ! movedInPairs;
moveOn();
}
if ( ! movedInPairs) // sub-design step 3
{ backUp();
putCD();
}
while ( ! spot.equals (getPosition())) // sub-design step 4
{ backUp();
backUp();
putCD();
}
} //======================
}
public class PairFinder extends Vic
{
/** Tell whether there are two CDs in a row at any point at
* or after this position. Leave the executor unchanged. */
public boolean hasTwoTogether()
{ String spot = getPosition(); // design step 1
boolean hasTwoTogether = seesSlot() // design step 2
&& foundPair();
while ( ! spot.equals (getPosition())) // design step 3
backUp();
return hasTwoTogether; // design step 4
} //======================
private boolean foundPair()
{ boolean previousSlotIsEmpty = ! seesCD(); // design step 1
moveOn(); // design step 2
while (seesSlot()) // design step 3
{ if ( ! seesCD()) // design step 3a
previousSlotIsEmpty = true;
else // has one in this slot // design step 3b
{ if (previousSlotIsEmpty)
previousSlotIsEmpty = false;
else // design step 3c
return true;
}
moveOn(); // design step 3d
}
return false; // design step 4
} //======================
}
|