一直想学这门课,网易公开课的版本确实不错,但是代码看不清,非常难受,所以自己搬运了youtube上2016年的课程,非常清晰,字幕是youtube自动翻译的,可能有些不准,但内容和网易公开课版本基本一致,这里给下链接。
视频地址:
https://pan.baidu.com/s/12oEpv022SiKlJGwZiQNO0g
密码:62nu
参考书籍:
https://pan.baidu.com/s/1PYRjvvq6fkV_NdTR7FOa2g
密码:h092

课程主页:
https://www.baidu.com/link?url=Ti8c7qJ4ibyIfgMgucbK5qTnnzGf3xWVsRdzORr1_fF-vGRVoHQ7Q7RlITXwHgPE&wd=&eqid=a77bcc030001438d000000045aba5907
最新版的课程其实和网易公开课上的资料基本一致,选择哪个都可以,个人感觉把这些部分都完成应该会有不错的效果。

再来简述一下这门课程,这门是编程的入门课,0基础都可以学,介绍java的,老师讲课很有意思,难度不大,感觉这门课的精华是作业,所以在这里记录下作业的思路。

来看下作业1,主要是Karel的操作。

  • problem1:

这题很简单,就是移动过去拿住物块,并返回,基本题。

import stanford.karel.*;

public class CollectNewspaperKarel extends SuperKarel {
	
	// You fill in this part
	public void run() {
		
		move2new();
		pickBeeper();
		return2start();
	}
	private void move2new() {
		move();
		turnRight();
		move();
		turnLeft();
		move();
		move();
	}
	private void return2start() {
		turnAround();
		move();
		move();
		move();
		turnRight();
		move();
		turnRight();
	}
	
}
  • problem 2:

这题的意思上设计代码帮助Karel在固定间隔处放物块,注意每次的高度不一定一致,一共放置的列数也不是常数,但是列和列的间隔固定。

这里定义了put方法和move4。put方法将其所在列的空缺处放上物块并返回原处,注意这里开始和结束的方向均为面朝右。move4方法为运动固定距离,这里为4。

import stanford.karel.*;

public class StoneMasonKarel extends SuperKarel {

	// You fill in this part
	public void run() {
		put();
		while (frontIsClear()) {
			move4();
			put();
		}
	}
	
	private void move4() {
		for (int i=0;i<4;i++) {
			move();
		}
	}
	
	private void put() {
		turnLeft();
		while (frontIsClear()) {
			put1();
			move();		
		}
		put1();
		turnAround();
		while(frontIsClear()) {
			move();
		}
		turnLeft();
	}
	
	private void put1() {
		if (noBeepersPresent()) {
			putBeeper();
		}
	}
}
  • problem 3:

这题的意思是让Karel在中点处放物块,如果墙的间隔为2k,则在k或者k+1的位置放均可,如果墙的间隔和2k+1,则在k+1的位置放。乍一看是个弱智题,但是这里Karel是没有办法计数的,所以还是有一定难度的。

这里的思路是定义一个状态量flag:如果前方为墙或者有物块,则状态为1,否则为0。利用这个状态量先放置左右两侧靠边的物块,然后递归在剩余未放置的地方重复此操作,最后会在每个地方放置一个物块。然后我在停滞的地方多放置两个物块,最后利用remove方法清理物块,正向反向各一次,最后留下的物块在中点处。

import stanford.karel.*;

public class MidpointFindingKarel extends SuperKarel {

	// You fill in this part
	public void run() {
		put();
		//在停滞的点放两块物块
		putBeeper();
		putBeeper();
		//移除物块
		remove();
		turnAround();
		//反向移除物块
		remove();
		turnAround();
		while (noBeepersPresent()) {
			move();
		}
	}
	
	//递归定义放置函数,先放左右两边的物块,再在剩余空余位置重复此操作
	public void put() {
		if (noBeepersPresent()) {
			putBeeper();
	}
		while (flag()==1) {
			if (frontIsClear()) {
			move();
			}
	}
		if (noBeepersPresent()) {
			putBeeper();
	}
		turnAround();
		if (flag()==1) {
			put();
		}

	}
	
	//如果前面有物品或者墙,返回0,否则返回1
	private int flag() {
		if (frontIsBlocked()) {
			return 0;
		}else{
			move();
			if (beepersPresent()) {
				turnAround();
				move();
				turnAround();
				return 0;
			}else {
				return 1;
			}

		}
	}
	
	//如果有物块,则清理
	private void remove() {
		while (frontIsClear()) {
			if (beepersPresent()) {
			pickBeeper();
			}
			move();
		}
		if (beepersPresent()) {
			pickBeeper();
		}
	}
}
  • problem 4



    这一题是将空盘填为棋盘的样子,要注意奇数偶数两种不同情形。这里的思路是定义put1和put2,put1处理奇数排的情形,put2处理偶数排的情形。每行处理完之后返回最左侧,如果此处有物块,则下一行为偶数排,否则为奇数排。

import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {

	// You fill in this part
	public void run() {
		put1();
		//判断是否到达最高层,右手边为墙
		while(rightIsClear()) {
			//如果此处有物块,下一排采用put2(),否则采用put1()
			if (beepersPresent()) {
				turnRight();
				move();
				turnRight();
				put2();
				
			}else {
				turnRight();
				move();
				turnRight();
				put1();
			}			
		}
	}
	
	//在奇数排中每间隔一个距离放物块,结束后返回最左侧,面朝墙
	private void put1() {
		putBeeper();
		while(frontIsClear()) {
			move();
			if (frontIsClear()) {
			move();
			putBeeper();
			}
		}
		turnAround();
		while (frontIsClear()) {
			move();
		}
	}
	
	//在偶数排中每间隔一个距离放物块,结束后返回最左侧,面朝墙
	private void put2() {
		if (frontIsClear()) {
			move();
		}
		putBeeper();
		while(frontIsClear()) {
			move();
			if (frontIsClear()) {
			move();
			putBeeper();
			}
		}
		turnAround();
		while (frontIsClear()) {
			move();
		}
	}
}