/*
* File: MidpointFindingKarel.java
* -------------------------------
* When you finish writing it, the MidpointFindingKarel class should
* leave a beeper on the corner closest to the center of 1st Street
* (or either of the two central corners if 1st Street has an even
* number of corners). Karel can put down additional beepers as it
* looks for the midpoint, but must pick them up again before it
* stops. The world may be of any size, but you are allowed to
* assume that it is at least as tall as it is wide.
*/
import stanford.karel.*;
public class MidpointFindingKarel extends SuperKarel {
public void run () {
makeDiagonalRight () ;
putBeeper () ;
setUpForNextDiagonal () ;
makeDiagonalLeft () ;
putBeeper () ;
turnLeft () ;
checkForLoneBeeper () ;
cleanUpBeepers () ;
}
private void makeDiagonalRight () {
while (frontIsClear()) {
putBeeper () ;
move () ;
turnLeft () ;
move () ;
turnRight () ;
}
}
private void setUpForNextDiagonal () {
turnAround () ;
while (frontIsClear()) {
move () ;
}
turnAround () ;
}
private void makeDiagonalLeft () {
while (frontIsClear()) {
if (noBeepersPresent()) {
putBeeper () ;
}
move () ;
turnRight () ;
move () ;
turnLeft () ;
}
}
private void checkForLoneBeeper () {
while (leftIsClear()) {
while (noBeepersPresent() && frontIsClear()) {
move () ;
}
if (beepersPresent()) {
move () ;
}
while (noBeepersPresent() && frontIsClear ()) {
move () ;
}
checkForSecondBeeper () ;
if (frontIsBlocked()) {
placeMidpointBeeper () ;
}
}
}
private void checkForSecondBeeper () {
if (beepersPresent() && facingNorth ()) {
if (frontIsBlocked()) {
turnLeft () ;
move () ;
turnLeft () ;
move () ;
}
while (frontIsClear() && facingNorth ()) {
move () ;
if (beepersPresent()) {
turnLeft () ;
move () ;
if (beepersPresent()) {
turnAround () ;
move () ;
turnLeft () ;
placeMidpointBeeper () ;
}
if (noBeepersPresent()) {
turnAround () ;
move () ;
turnLeft () ;
}
if (frontIsBlocked()) {
turnLeft () ;
move () ;
turnLeft () ;
move () ;
}
}
}
}
if (beepersPresent() && facingSouth ()) {
if (frontIsBlocked()) {
turnRight () ;
move () ;
turnRight () ;
move () ;
}
while (frontIsClear() && facingSouth ()) {
move () ;
if (beepersPresent()) {
turnRight () ;
move () ;
if (beepersPresent()) {
turnAround () ;
move () ;
turnRight () ;
placeMidpointBeeper () ;
}
if (noBeepersPresent()) {
turnAround () ;
move () ;
turnRight () ;
}
if (frontIsBlocked()) {
turnRight () ;
move () ;
turnRight () ;
move () ;
}
}
}
}
}
private void placeMidpointBeeper () {
turnAround () ;
while (noBeepersPresent()) {
move () ;
}
if (beepersPresent()) {
pickBeeper () ;
}
if (facingNorth()) {
turnAround () ;
}
while (frontIsClear()) {
move () ;
}
if (frontIsBlocked()) {
putBeeper () ;
turnRight () ;
move () ;
}
}
private void cleanUpBeepers () {
cleanRow () ;
while (rightIsClear()) {
repositionForRowToEast () ;
cleanRow () ;
if (leftIsClear()) {
repositionForRowToWest () ;
cleanRow () ;
} else {
turnAround () ;
}
}
turnAround () ;
cleanRow () ;
turnRight () ;
cleanRow () ;
repositionToBeginning () ;
}
private void cleanRow () {
while (frontIsClear()) {
move () ;
if (beepersPresent()) {
pickBeeper () ;
}
}
}
private void repositionForRowToWest () {
turnLeft () ;
move () ;
turnLeft () ;
}
private void repositionForRowToEast () {
turnRight () ;
move () ;
turnRight () ;
}
private void repositionToBeginning () {
turnRight () ;
while (frontIsClear()) {
move () ;
}
turnAround () ;
}
}