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辆车  已通过


     


     

  • 相关阅读:
    Binary Tree Maximum Path Sum
    ZigZag Conversion
    Longest Common Prefix
    Reverse Linked List II
    Populating Next Right Pointers in Each Node
    Populating Next Right Pointers in Each Node II
    Rotate List
    Path Sum II
    [Leetcode]-- Gray Code
    Subsets II
  • 原文地址:https://www.cnblogs.com/runwind/p/4454737.html
Copyright © 2011-2022 走看看