黑马程序员--【学习日记十】——交通灯管理系统

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

交通灯管理系统

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

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

例如:

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

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

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

。。。

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

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

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

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

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

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

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

--------------------------------------------------------------------------------------------------------------------------------------------------------

以上是题,以下是解。

--------------------------------------------------------------------------------------------------------------------------------------------------------

分析:

一共4个路口,每个路口分别可以向左、右、前三个方向行车,这样就有12条行车路线。而右转不受信号灯控制,所以减去4条线路,还剩8条,也就是每个路口向前和向左。假设从南往北(S-N)通车,那么对应的从北往南(N-S)也可以行车,南北向的灯变红后,下一个通车线路应该是从南往西(S-W)以及从北往东(N-E),接着是(E-W)(W-E),接着是(E-S)(E-N),接着(N-S)(S-N)就算循环一次了。

这8条线路又分成4组线路,每个组中的两条线路是对应关系(灯的状态相同,只考虑其中一个),组与组之是先后关系,

当前灯的下一个灯:(S-N)――>(S-W)――>(E-W)――>(E-S)――>(N-S)(相当于回到(S-N))。

对应关系是(S―N)<――>(N―S);(S-W)<――>(N-E);(E-W)<――>(W-E);(E-S)<――>(W-N);

这样路线就固定了,可以用集合增加删除元素来演示车辆过马路。定义一个类来描述路。

  1: public class Road {
  2:    private List<String> vechicles = new ArrayList<String>();
  3:    private String name =null;
  4:    public Road(String name){
  5:       this.name = name;
  6:       ExecutorService pool = Executors.newSingleThreadExecutor();
  7:       pool.execute(new Runnable(){
  8:          public void run(){
  9:             for(int i=1;i<1000;i++){
 10:                try {
 11:                   Thread.sleep((new Random().nextInt(10) + 1) * 1000);
 12:                } catch (InterruptedException e) {
 13:                   e.printStackTrace();
 14:                }
 15:                vechicles.add(Road.this.name + "_" + i);
 16:             }            
 17:          }
 18:          
 19:       });
 20:       
 21:       //定时器每隔一秒检查对应的灯是否为绿,如果为绿就放行一辆车      
 22:       ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
 23:       timer.scheduleAtFixedRate(
 24:             new Runnable(){
 25:                public void run(){
 26:                   if(vechicles.size()>0){
 27:                      boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
 28:                      if(lighted){
 29:                         System.out.println(vechicles.remove(0) + " is traversing !");
 30:                      }
 31:                   }
 32:                   
 33:                }
 34:             },
 35:             1,
 36:             1,
 37:             TimeUnit.SECONDS);
 38:       
 39:    }
 40: }

有且只有12条线路,因此可以使用枚举来描述灯,public enum Lamp{SN…..等等};

并且只有4条线路需要被控制,也就是说这四条线路有对应的灯以及下一个等,这样就可以循环切换灯的颜色。剩下的线路没有下一个灯颜色与这4个线路的灯对应相反,右转方向灯常亮。

  1: public enum Lamp {
  2:    //每个枚举元素分别表示一个对应方向的灯   
  3:    S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
  4:    //对应的灯没有下一个灯,颜色受上面对应的灯控制
  5:    N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
  6:    //右转弯的灯常绿
  7:    S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
  9:    private Lamp(String opposite,String next,boolean lighted){
 10:       this.opposite = opposite;
 11:       this.next = next;
 12:       this.lighted = lighted;
 13:    }
 16:    //判断当前灯是否为绿   
 17:    private boolean lighted;
 18:    //对应的灯与当前灯颜色一致   
 19:    private String opposite;
 20:    //控制下一个灯改变颜色
 21:    private String next;
 22:    public boolean isLighted(){
 23:       return lighted;
 24:    }
 25:    //当前灯绿,对应的灯也变绿   
 26:    public void light(){
 27:       this.lighted = true;
 28:       if(opposite != null){
 29:          Lamp.valueOf(opposite).light();
 30:       }
 31:       System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");
 32:    }
 34:    //某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿   
 35:    public Lamp blackOut(){
 36:       this.lighted = false;
 37:       if(opposite != null){
 38:          Lamp.valueOf(opposite).blackOut();
 39:       }      
 41:       Lamp nextLamp= null;
 42:       if(next != null){
 43:          nextLamp = Lamp.valueOf(next);
 44:          System.out.println("绿灯从" + name() + "-------->切换为" + next);         
 45:          nextLamp.light();
 46:       }
 47:       return nextLamp;
 48:    }
 49: }

假设初始化时从南往北的灯是绿的,并且设置为当前灯,这样定义一个类来描述控制器,只要控制当前灯。

 1: public class LampController {
  2:    private Lamp currentLamp;
  4:    public LampController(){
  5:       //初始化时设定从南往北的灯为绿灯      
  6:       currentLamp = Lamp.S2N;
  7:       currentLamp.light();
  9:       //定时器每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿   
 10:       ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
 11:       timer.scheduleAtFixedRate(
 12:             new Runnable(){
 13:                public  void run(){
 14:                   System.out.println("来啊");
 15:                   currentLamp = currentLamp.blackOut();
 16:             }
 17:             },
 18:             10,
 19:             10,
 20:             TimeUnit.SECONDS);
 21:    }
 22: }

最后定义主函数的类,运行控制器,循环打印输出有车辆通过的线路,模拟车辆过马路,如果打印结果符合预期

结果,就说明程序合理。

  1: 
  2: public class MainClass {
  3:    public static void main(String[] args) {
  4:       
  5:       //初始化12条线路      
  6:       String [] directions = new String[]{

7: "S2N","S2W","E2W","E2S","N2S","N2E",

"W2E","W2N","S2E","E2N","N2W","W2S"

  8:       };
  9:       for(int i=0;i<directions.length;i++){
 10:          new Road(directions[i]);
 11:       }
 12:       //运行交通灯控制器      
 13:       new LampController();
 14:    }
 16: }

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值