zoukankan      html  css  js  c++  java
  • 交通灯管理系统

            张老师的项目思路实在是太清晰了,看完之后我就觉得这个项目很简单,看了一遍视频我也做出来了,张老师视频里说交通灯共有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辆车  已通过


     


     

  • 相关阅读:
    135编辑器使用教程
    gitalb的搭建与使用
    关于String类型,转换BigDecimal .并且BigDecimal 的乘法计算
    关于MAP转换成驼峰命名法然后转换成实体
    java时间计算,获取某月第一天和最后一天
    Spring 自带的定时任务
    Hibernate jpa 在实体类中对于时间的注解
    noip2014总结
    sroHOBOorz来自HOBO的高精类
    2014年9月6日
  • 原文地址:https://www.cnblogs.com/runwind/p/4454737.html
Copyright © 2011-2022 走看看