斯坦福卡雷尔机器人作业的一些感悟

第一个是捡报纸,很简单

 

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();  
    }  
          
}  

    这个题目要考察的是考虑问题的全面性和编程的分布思想。尽管两个代码都能完成任务,但是不管是从简便性和可读性上我的代码和别人的都有很大的差距。实际上,修柱子这整个工程只有三步:修柱子并且返回,检查是否是终点,前进四部,修柱子并且返回…如此循环知道遇到终点。而我的代码复杂就复杂在我少了返回这一步,而是从柱子顶端前往下一个柱子,这样看似少了一步,其实却多了很多不必要的假设和选择:因为柱子的高度不是平齐的。地面是平齐的,第二种解法正是利用了这一点,似的程序大大简化。不过我的代码也有它的好处,如果该处的地面有塌陷,导致地面不平齐,第二个代码便会出错,而我代码可以成功运行。





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值