黑马程序员——交通灯系统

来源:互联网 发布:冒险岛双刀v矩阵 编辑:程序博客网 时间:2024/05/21 14:50

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

12.1. 需求

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

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

例如:

      由南向而来去往北向的车辆----直行车辆

      由西向而来去往南向的车辆---- 右转车辆

      由东向而来去往南向的车辆---- 左转车辆

      ….

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

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

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

5、注意:

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

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

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

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

6、说明:

这里要实现的是模拟十字路口的交通灯管理系统逻辑,是对交通灯的控制,而不是模拟汽车的移动过程。所以不用将车作为主体对象,再单独产生一个类。只需要将车和路绑定在一起即可。

二、需求分析:

一、图解分析:

 

12.2. 基本思想

因为有十二条路线,就有十二个灯,灯是固定的。所以会想到用枚举的方法。

枚举里面的元素就是枚举的实例对象,不可以单独创建元素。

只用设计四个灯,只有四个灯有逻辑。对应相反方向的灯,我变绿把相反方向灯变红。下一个灯,对应方向的灯,记录自己状态,灯里面有三个变量。true,右转的时候。当前绿的灯是哪一个?弄一个定时器。我变红,同时会让下一个灯变绿,我的返回值就是下一个灯,就是当前变绿的灯。要记住下一个绿灯,就要得到下一个绿灯。

对于车辆的变化。可以将道路理解为一个集合,而车辆就是该集合中的元素,路上的车辆变化,可以理解为向集合中添加元素和取出元素的操作。可以通过随机生成线程的方式模拟路上车辆的变化。

对于Lamp类的编写:

分析:

1、总共有12条路线,有12个方向,就需要定义12灯,用枚举类创建灯对象

2、12个灯分别如代码中所示

3、12个灯中,有四个右转的等可设为常亮状态,即S2E,E2N,N2W,W2S

4、对于剩下的灯,可分为4组,每组的两个灯是对应的,这里设置当前灯和对应灯,

5、对应的两个灯是同时亮的,而与其垂直方向的灯则不能亮。如南北方向灯亮,东西方向则不亮

6、当前灯亮时,就要设置对应灯为亮,并设置垂直方向灯为不亮

 

Road类

public class Road{

List vechicies=new ArrayList();

public Road(String)

}

具体代码:

Road类

import java.util.List;  import java.util.ArrayList;  import java.util.Random;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.ScheduledExecutorService;  import java.util.concurrent.TimeUnit;  public class Road {      //定义一个集合,用于存储车辆和移除车辆      private List vechicles = new ArrayList();      //依据路名产生车名      private String name = null;      public Road(String name){          this.name = name;                    //模拟车辆不断随机上路的过程          //使用线程池,通过产生单个线程的方法,创建一个线程池          ExecutorService pool = Executors.newSingleThreadScheduledExecutor();          //调用execute方法,可向线程池提交一个任务,让池中的线程执行任务          pool.execute(new Runnable(){              //执行的任务,随机产生车,并加入集合              public void run() {                  for(int i=1;i<1000;i++){                      try {                          //每个10秒随机产生一辆车                          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){                              //每隔1秒让车通行,通行前要先判断灯是否亮,亮了才能通行,即从集合中移除                              boolean lighted = Lamp.valueOf(Road.this.name).isLighted();                              if(lighted)                                  System.out.println(vechicles.remove(0) + " is traversing !");                          }                      }                  },                                  TimeUnit.SECONDS                  );      }  


Lamp类的编写:

 

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 String oppsiteLampName;      //定义当前灯的下一个灯,当前灯亮,下个灯不亮      private String nextLampName;      //标记当前灯是否为绿灯(亮)      private boolean lighted;      //灯的判断是否亮的方法      public boolean isLighted(){          return lighted;      }            //构造方法,初始化对象      private Lamp(String oppsiteLampName,String nextLampName,boolean lighted){          this.oppsiteLampName = oppsiteLampName;          this.nextLampName = nextLampName;          this.lighted = lighted;      }            public void light(){          this.lighted = true;          //当前灯变绿了,让对应的灯也变绿          if(oppsiteLampName!=null)              Lamp.valueOf(oppsiteLampName).light();              System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");      }            //当前灯变红了,对应灯也要变红,并启动下个灯变绿      public Lamp blackOut(){          this.lighted = false;          if(oppsiteLampName!=null)              Lamp.valueOf(oppsiteLampName).blackOut();          Lamp nextLamp = null;          if(nextLampName!=null){              nextLamp = Lamp.valueOf(nextLampName);                    System.out.println("绿灯从" + name() +"切换为" + nextLampName);              nextLamp.light();          }          return nextLamp;                }  }  

LampContriller类的编写:

import java.util.concurrent.ScheduledExecutorService;  import java.util.concurrent.TimeUnit;    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() {                          //让当前灯变红,并返回下一个灯                          System.out.println("coming...");                          currentLamp = currentLamp.blackOut();                      }                  },                  10,                  10,                  TimeUnit.SECONDS);       }  }    


---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
0 0