/*
* 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.
*
* author:zhendongYi
* time:2016/06/27
* 我采用的方法是首先鋪滿一層beeper硬毕,然后從兩端各自清除一個(gè)beeper呻引,循環(huán)清除
* 直到最后beeper數(shù)量小于等于2結(jié)束
* **********************************
* 由于看錯(cuò)了題目要求,以為偶數(shù)的行需要中間兩個(gè)格子都放上beeper吐咳,結(jié)果只需要
* 隨便放一個(gè)beeper即可逻悠,懶得改了,再加一個(gè)判斷就可
*/
import stanford.karel.*;
public class MidpointFindingKarel extends SuperKarel {
public void run(){
putLineBlocks(); //將一行填滿方塊,并轉(zhuǎn)向
removeBlocksStepByStep(); //循環(huán)從左邊和右邊各移動(dòng)一個(gè)方塊
}
//填滿一行方塊,并轉(zhuǎn)向
private void putLineBlocks() {
while(frontIsClear()){
putBeeper();
move();
}
putBeeper();
turnAround();
}
// 如果beeper數(shù)量大于2挪丢,則循環(huán)清除左右兩邊的方塊蹂风,否則什么也不做
private void removeBlocksStepByStep() {
while(blockNumber()>2){
moveToBlockEnd();
removeBlock();
moveToBlockEnd();
removeBlock();
}
}
//移除最邊上的beeper,并前進(jìn)一小格,走到beeper的地方
private void removeBlock() {
pickBeeper();
move();
}
/*
* 條件:karel位于有block的一端
* 結(jié)果:karel跑到有block的另一端乾蓬,i為block數(shù)量惠啄,并轉(zhuǎn)向兩次以避免奇數(shù)次對(duì)循環(huán)造成影響
*/
private int blockNumber() {
// 計(jì)算所有的block的數(shù)量
int i=0;
while(beepersPresent()){
i++;
if(frontIsClear()){
move();
}else{
break;
}
}
turnAround();
//再轉(zhuǎn)回來(lái)
while(beepersPresent()){
if(frontIsClear()){
move();
}else{
break;
}
}
turnAround();
return i;
}
/*
* 將karel移到存在beeper所有的位置的最邊上的一點(diǎn)
*/
private void moveToBlockEnd() {
while(frontIsClear()&&beepersPresent()){
move();
}
if(noBeepersPresent()){
turnAround();
move();
}else{
turnAround();
}
}
}