黑马程序员_交通灯管理系统

来源:互联网 发布:棋牌软件 编辑:程序博客网 时间:2024/06/09 17:38

一、题目要求:模拟实现十字路口的交通灯管理系统逻辑,具体有以下需求:

1)异步随机生成按照各个路线行驶的车辆,举例说明如下:
(1) 由南向北行驶的车辆 ----直行车辆
(2) 由西向南行驶的车辆 ----右转车辆
(3)由东向南行驶的车辆 ----左转车辆

2) 信号灯颜色选择范围:忽略黄灯,只考虑红灯和绿灯
3)左转车辆和右转车辆的要求
(1)左转车辆受到控制信号灯的控制
(2) 但是右转车辆不受信号灯控制
注意:具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
4) 其他说明
(1) 南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
(2)每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
(3) 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
(4)不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
分析:


车在路上行驶时有12个方向,这是车必须具备的方法,必须知道是从哪往哪开的;然后,车自己有不断创建的方法;最后,车能看前面灯是否为绿灯,如果是绿灯且前面无其它车辆,就开过去。这么想来就比较复杂了,还需要管理这么多内容,不过创建车的方法应该不在车本身中,移动的方法放在集合中更加合适,remove(0)就能直接开走第一辆车,那么仅仅剩下一个方向,不如也定义在装车的集合中,就一共有12个集合,那么车这个类就完全没用了,直接用一个字符串代替即可。车行驶在路上,不如把这个集合定义成路。
灯:把车辆右拐设为一个长绿灯的话,一共有12个灯,对应12条马路。每个灯应该有自己的状态,并且有变红、变绿的方法。如果用12个灯控制逻辑变换,太过于复杂。南到北、北到男是对应的,同理东西,可以省去一半逻辑控制灯,剩下6个,减去长绿灯,还有4个,这样就比较好控制了。
控制器:定义一个当前的灯,使之变绿,过一定时间后使之变红,并得到下一个灯,再使之变绿,如此循环,便实现了对灯的控制。

实现:

定义一个Road类,需要产生车,实现车的移动方法

public class Road {List vechicles = new ArrayList<String>();private String name = null;public Road(String name){this.name = name;ExecutorService pool = Executors.newSingleThreadExecutor();pool.execute(new Runnable(){public void run(){for(int i =1 ;i<1000;i++){try {Thread.sleep((new Random().nextInt(10)+1)*1000);} catch (InterruptedException e) {e.printStackTrace();}vechicles.add(Road.this.name+"_"+i);}}});ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);timer.scheduleAtFixedRate(new Runnable(){public void run(){if(vechicles.size()>0){boolean lighted = Lamp.valueOf(Road.this.name).isLightred();if(lighted){System.out.println(vechicles.remove(0)+"is traversing");vechicles.remove(0);}}}}, 1,1, TimeUnit.SECONDS);}}

定义一个Lamp类,该类需要实现系统中12个方向上的灯,每个Lamp对象中的灯亮状态用lighted变量表示,选用S2N、S2W、E2W、E2N(上图中的1、2、3、4条路线)这四个方向上的Lamp对象依次轮询变亮,Lamp对象中还要有一个oppositeLampName变量来表示它们相反方向的灯,再用一个nextLampName变量来表示此灯变亮后的下一个变亮的灯。这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。增加让Lamp变亮和变黑的方法:light和blackOut,对于S2N、S2W、E2W、E2N这四个方向上的Lamp对象,这两个方法内部要让相反方向的灯随之变亮和变黑,blackOut方法还要让下一个灯变亮。
public enum Lamp {S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);private Lamp(String opposite,String next,boolean lighted){this.opposite = opposite;this.next= next;this.lighted = lighted;}private Lamp(){}private boolean lighted;private String opposite;private String next;public boolean isLightred(){return lighted;}public void light(){this.lighted = true;if(opposite!= null){Lamp.valueOf(opposite).light();}}public Lamp blackOut(){this.lighted = false;if(opposite!= null){Lamp.valueOf(opposite).blackOut();}Lamp  nextLamp=null; if(next!= null){nextLamp = Lamp.valueOf(next);nextLamp.light();}return nextLamp;}}
定义一个LampController类,用来实现灯的控制器:获取一个灯,使之变绿,并且在固定时间后使之变红,并得到下一个灯。
public class LampController {private Lamp currentLamp;public  LampController(){currentLamp = Lamp.S2N;currentLamp.light();ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);timer.scheduleAtFixedRate(new Runnable(){public void run(){currentLamp = currentLamp.blackOut();}},10,10,TimeUnit.SECONDS);}}
定义一个MainClass,先初始化交通灯,这时候交通灯的构造方法会启动新的线程进行10s为间隔的交通灯的切换。之后主线程应该立刻进行Road类的12条线路实例的初始化。接着再获得LampController对象并调用其start方法。
public class MainClass {public static void main(String[] args) {String[] directions = new String[]{"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};for(int i=0;i<directions.length;i++)new Road("directions[i]");new LampController();}}










0 0