交通灯管理系统

        张老师的项目思路实在是太清晰了,看完之后我就觉得这个项目很简单,看了一遍视频我也做出来了,张老师视频里说交通灯共有12盏,用枚举,这时我就在想,路线也是12条呀,怎么不用枚举呢?于是我用了,嘿,枚举还真好用,成功了!感觉真好!

这是一个模拟红绿灯的项目。

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:

·        异步随机生成按照各个路线行驶的车辆。 

·        信号灯忽略黄灯,只考虑红灯和绿灯。

·        应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

·        具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

         注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

·        每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

·        随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

·        不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

 

张老师的画图分析如下:

 交通灯线路图

我写的代码:

第一个类:红绿灯类

/**
 * 十字路口:每个路口都有直走、左拐、右拐三条路线,四个路口就有12条,每条路线上要设置一盏交通灯。
 * 右转不受灯控制,直走时相对的两条路的灯一样,左拐时相对的两条路的灯也一样,所以有4对一样灯的路,
 * 所以主要设置4盏灯即可,主灯亮以后让相对的灯跟着亮就行了,灭也跟着灭。
 * 谁拥有数据谁叫对外提供操作这些数据的方法,所以灯应该拥有以下方法:
 * 1、灯拥有判断自己灯的状态的方法
 * 2、把自己点亮的方法,当自己亮的时候相对的灯也要打亮
 * 3、把自己熄灭的方法,当自己熄灭时候相对的灯也要熄灭,并且让下一盏灯打亮
 * 
 * 车看是否是红绿灯得问路,所以灯得跟路关联,这样路才能知道灯的状态,并告知车是否能通过,所以下一步定义路的类
 *
 */
public enum Lamp {
	
	S2N("N2S","S2W"),S2W("N2E","E2W"),E2W("W2E","E2S"),E2S("W2N","S2N"),//这四盏是主灯,主要控制这四盏灯,通过构造函数保存了与它们相对的灯和它们的下一盏灯
	N2S,             N2E,             W2E,             W2N,//这四盏灯在路口与上面四盏一一相对,上面的亮,它就亮,上面的灭,它就灭
	
	S2E(true),E2N(true),N2W(true),W2S(true); //这四盏是右转灯,所以通过构造函数把它们设置为绿灯
	
	private boolean lighted;
	private String opposite;
	private  String next;
	
	private Lamp() {}
	private Lamp(boolean lighted) {this.lighted = lighted;}
	private Lamp(String opposite,String next) {
		this.opposite = opposite;
		this.next = next;
	}
	
	public boolean isLighted() {  //1、灯拥有判断自己灯的状态的方法
		return this.lighted;
	}
	
	public void light() {  //2、把自己点亮的方法,当自己亮的时候相对的灯也要打亮
		this.lighted = true;
		if(opposite != null){
			Lamp.valueOf(opposite).light();	//枚举可以通过名称获得枚举的元素	
			System.out.println("\n\n\n当前绿灯为:" + this.name() + "、" + opposite + "\n");
		}
	}
	
	public Lamp blackout() {  //3、把自己熄灭的方法,当自己熄灭时候相对的灯也要熄灭,并且让下一盏灯打亮
		this.lighted = false;
		if(opposite != null) {
			Lamp.valueOf(opposite).blackout();
			Lamp nextLamp = Lamp.valueOf(next);
			nextLamp.light();
			return nextLamp;
		}
		return null;
	}
}

第二个类:红绿灯控制系统

/**
 * 这是用来控制红绿灯的亮与灭的控制系统
 * 一开始就初始化当前灯为S2N,且为绿灯,然后每隔10秒关闭当前的绿灯,并让一下盏灯为绿灯,并让这盏绿灯变成当成灯,就这样循环执行
 */
import java.util.concurrent.*;

public class LampController {

	private Lamp currentLamp;
	
	public LampController() {
		Lamp.S2N.light();
		currentLamp = Lamp.S2N;
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//创建一个调试线程池
		
		timer.scheduleAtFixedRate(
				new Runnable() {
					public void run() {
						currentLamp = currentLamp.blackout();
					}
				},
				10, 
				10,
				TimeUnit.SECONDS);
	}
}
第三个类:路线类
/**
 * 车是属于路的数据,所以路得提供操作车的方法:
 * 1、增加车辆,这些车辆保存到路的一个集合里,车辆增加的时间是不固定的,这里用随机 1~10秒
 * 2、绿灯时让车通过,也就是减少一量增加进来的车
 * 这里通过两个线程来完成上面两个方法,让路一产生的时候就进行增加车辆和检查绿灯并让车通过
 * 
 * 每条路都得有个路名,取与灯名相同方便与灯进行关联,总共有12条路
 *
 */
import java.util.concurrent.*;
import java.util.*;
public enum Road {

	S2N,S2W,E2W,E2S,
	N2S,N2E,W2E,W2N,
	S2E,E2N,N2W,W2S;

	List<String> vehicles = new ArrayList<String>();//用于存放车辆
	
	private Road() {
		ExecutorService pool = Executors.newSingleThreadExecutor();//产生单个线程的线程池
		pool.execute(new Runnable() {
			public void run() {
				for(int i=1;i<1001;i++) {			
					try{Thread.sleep( (new Random().nextInt(10)+1)*1000);}catch(Exception e) {e.printStackTrace();}
					if(name().equals("S2E")||name().equals("E2N")||name().equals("N2W")||name().equals("W2S"))//如果是右转车则把车名加上"右转"
						vehicles.add("-->右转 " + name() + " 第" + i + "辆车");
					else
						vehicles.add(name() + " 第" + i + "辆车");
				}
			}
		});
		
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						if(Lamp.valueOf(name()).isLighted()) //如果灯绿,并且有车就删第一辆车,代表开过一辆车
							if(!vehicles.isEmpty())
								System.out.println(vehicles.remove(0) + "  已通过");
					}
				}, 
				1,
				1, 
				TimeUnit.SECONDS);
				
	}
		
}
第四个类:运行类
public class MainClass {
	
	public static void main(String[] args) {
		new LampController();//把交通灯控制系统打开,红绿灯开始运转。因为灯是枚举,所以这个系统里只要一调用到任意一个灯枚举对象,则12盏灯都有了。
		Road road = Road.S2N;//因为Road是枚举,所以只要一调用到Road这个类则里面的枚举元素就全部都有了,里面12条路的线程都启动了。		
	}
}


截一断我的运行结果,如下:

当前绿灯为:S2N、N2S

-->右转 S2E 第1辆车  已通过
-->右转 W2S 第1辆车  已通过
-->右转 E2N 第1辆车  已通过
-->右转 N2W 第1辆车  已通过
N2S 第1辆车  已通过
S2N 第1辆车  已通过
-->右转 W2S 第2辆车  已通过
-->右转 S2E 第2辆车  已通过
N2E 第1辆车  已通过
S2W 第1辆车  已通过

当前绿灯为:S2W、N2E

-->右转 E2N 第2辆车  已通过
S2W 第2辆车  已通过
-->右转 S2E 第3辆车  已通过
-->右转 N2W 第2辆车  已通过
S2W 第3辆车  已通过
N2E 第2辆车  已通过
-->右转 E2N 第3辆车  已通过
-->右转 E2N 第4辆车  已通过
-->右转 W2S 第3辆车  已通过
-->右转 N2W 第3辆车  已通过
-->右转 N2W 第4辆车  已通过


 


 

原文地址:https://www.cnblogs.com/runwind/p/4454737.html