第一个是捡报纸,很简单
code:
import stanford.karel.*;
public class CollectNewspaperKarel extends SuperKarel {
public void run() {
turnRight();
move();
turnLeft();
move();
move();
move();
pickBeeper();
}
}
第二题:
第二个是修柱子,有以下规则:
卡雷尔被雇去修复1989 年大地震对斯坦福大方院造成的损坏。补全支撑拱门石头(当然还
是用菱形方块表示),如下图所示:
你编写的程序应当能解决如上情况,但凡是满足本题基本规则的情况都应该能解决,规则见
题末。本题文件夹中有各种不同情况的界面,你的程序应当能在这些界面中正确运行。
卡雷尔完工后,所有空缺应当被菱形填满,效果图如下:
卡雷尔需遵循如下规则:
每隔三列有一个支撑柱,分别位于第一、五、九和十三列,依此类推;
最后一个支撑柱右侧紧贴一堵墙,本题中,墙壁紧贴第十三列右侧,但无论有多少组支
撑柱,你的程序都应该能正确运行;
每组支撑柱顶端为墙体,但卡雷尔不知道每个支撑住是否只有5 块石头,也不知道是
否所有的支撑柱都等高。
有些支撑柱中的石头并未完全缺损,你的程序不能在已有石头的位置再次置放。
my code:
/*
* File: StoneMasonKarel.java
* --------------------------
* The StoneMasonKarel subclass as it appears here does nothing.
* When you finish writing it, it should solve the "repair the quad"
* problem from Assignment 1. In addition to editing the program,
* you should be sure to edit this comment so that it no longer
* indicates that the program does nothing.
*/
import stanford.karel.*;
public class StoneMasonKarel extends SuperKarel {
public void run() {
while(true)
{
if(frontIsClear()||leftIsClear())
downToUp();
else break;
if(frontIsClear()||rightIsClear())
upToDown();
else break;
}
}
private void upToDown(){
turnRight();
if(noBeepersPresent())
putBeeper();
while(frontIsClear())
{
move();
if(noBeepersPresent())
putBeeper();
}
turnLeft();
int n=0;
while(n<4&&(frontIsClear()||leftIsClear()))
{
if(frontIsClear())
{
move();
n++;
}
else if(leftIsClear())
{
turnLeft();
move();
turnRight();
}
if(n==4){
while(rightIsClear())
{
turnRight();
move();
turnLeft();
}
}
}
}
private void downToUp(){
turnLeft();
if(noBeepersPresent())
putBeeper();
while(frontIsClear())
{
move();
if(noBeepersPresent())
putBeeper();
}
turnRight();
int n=0;
while(n<4&&(frontIsClear()||rightIsClear()))
{
if(frontIsClear())
{
move();
n++;
}
else if(rightIsClear())
{
turnRight();
move();
turnLeft();
}
}
if(n==4){
while(leftIsClear())
{
turnLeft();
move();
turnRight();
}
}
}
}
博客上某老鸟的代码:
import stanford.karel.*;
public class StoneMasonKarel extends SuperKarel {
public void run(){
fixAndBack();
while(rightIsBlocked()){
if(frontIsClear()){
moveFourSteps();
fixAndBack();
}
}
}
/* 修复一整根柱子并返回
* 前置条件:处于一根柱子底部,面向东
* 后置条件:同上
*/
public void fixAndBack(){
turnLeft();
fixLine();
moveBack();
turnLeft();
}
/* 修复一根柱子面向北
* 前置条件:柱子底部,面向北
* 后置条件:柱子顶部,面向北
*/
public void fixLine(){
while(frontIsClear()){
if(noBeepersPresent()){
putBeeper();
}
move();
}
if(noBeepersPresent()){
putBeeper();
}
}
/* 回到柱子底部
* 前置条件:位于柱子顶端面向北
* 后置条件:位于柱子低端面向南
*/
public void moveBack(){
turnAround();
while(frontIsClear()){
move();
}
}
// 移动四步
public void moveFourSteps(){
move();
move();
move();
move();
}
}
这个题目要考察的是考虑问题的全面性和编程的分布思想。尽管两个代码都能完成任务,但是不管是从简便性和可读性上我的代码和别人的都有很大的差距。实际上,修柱子这整个工程只有三步:修柱子并且返回,检查是否是终点,前进四部,修柱子并且返回…如此循环知道遇到终点。而我的代码复杂就复杂在我少了返回这一步,而是从柱子顶端前往下一个柱子,这样看似少了一步,其实却多了很多不必要的假设和选择:因为柱子的高度不是平齐的。地面是平齐的,第二种解法正是利用了这一点,似的程序大大简化。不过我的代码也有它的好处,如果该处的地面有塌陷,导致地面不平齐,第二个代码便会出错,而我代码可以成功运行。