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

 

 ---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

1.      项目需求:

模拟实现十字路口的交通灯管理系统逻辑:

a)     路线方面:

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

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

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

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

b)     信号灯方面:

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

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

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

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

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

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

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

2.       需求分析之路线方面:

设计一个Road类来表示路线,把路线的方向(name)作为Road类中的一个属性,用于表示路线的名称,在创建Road对象时对该属性赋初值。由于每个路口对应三条路线(直行,左转,右转),所以共有12条路线,如图:

                             

Road类中定义一个ArrayList集合(vehicles),用于存储该路线上的车辆。为了保证路线创建时该路线上即有车辆,所以集合元素的添加放置在构造方法中。

路线上车辆的增加:由于车辆增加的行为贯穿在整个程序运行期,所以应当为每条路线上车辆的增加分别单独开辟一个线程,且要使用循环结构(张老师视频中用了for循环,循环次数为1000,不过采用while循环似乎更合适,否则若程序执行时间足够长的话,路线上将不会有车辆增加,这与实际情况不符。本篇内采用while循环结构);又由于路线上车辆的增加是随机的,所以需要用到随机数方法,

路线上车辆通过路口:若本路线的路灯为绿,则车辆穿过路口,就把本路线ArrayList集合中的第一个元素(靠近路口的第一辆车)移除。因此Road类中还要定义一个定时器,用于经常性地检查控制本路线的灯是否为绿,检测频率设置为1秒。该定时器的创建同样要定义在构造方法中,以保证路线一旦被创建,定时器就开始执行;

具体代码示例如下:

importjava.util.*;

importjava.util.concurrent.*;

 

public classRoad {

       private List<String> vechicles =new ArrayList<String>(); //用于存储路线上的车辆;

       private String name =null;    // name为路线的名字;

       public Road(String name){

              this.name = name;

             

              //创建一个线程用于为路线随机地增加车辆;           

              ExecutorService pool =Executors.newSingleThreadExecutor();

              pool.execute(new Runnable(){

                     public void run(){

                            int vech_num=1;

                            while(true){

                                   try {

                                          Thread.sleep((newRandom().nextInt(10) + 1) * 1000);

                                   } catch(InterruptedException e) {

                                          e.printStackTrace();

                                   }

                                   vechicles.add(Road.this.name+ "_" + vech_num);

                            }                          

                     }

                    

              });

             

              //创建定时器,每隔一秒检查对应的灯是否为绿,是的话就放行一辆车;            

              ScheduledExecutorService timer=  Executors.newScheduledThreadPool(1);

              timer.scheduleAtFixedRate(

                            new Runnable(){

                                   public voidrun(){

                                          if(vechicles.size()>0){

                                                 booleanlighted = Lamp.valueOf(Road.this.name).isLighted();

                                                 if(lighted){

                                                        System.out.println(vechicles.remove(0)+ " is traversing !");

                                                 }

                                          }

                                         

                                   }

                            },

                            1,

                            1,

                            TimeUnit.SECONDS);

             

       }

}

 

3.       需求分析之交通灯方面:

创建一个Lamp类用于表示交通灯,每个交通灯控制一条路线,所以共有12个交通灯对象。这12个交通灯对象从大的方面分为两组:

第一组:共有八个,分别用于控制直行方向和左转方向,这些灯要进行变红和变绿的交替;这八个路灯分别用S2N, S2W, E2W, E2S, N2S,N2E, W2E, W2N表示。

第二组:共有四个,控制右转方向,灯常绿,不需变红;这四个路灯分别用 S2EE2NN2WW2S表示。

第一组中八个交通台并不是相互独立的,它们两两之间存在联动关系,例如:由北向南(N2S)和由南向北(S2N)的交通灯的状态始终保持一致;所以这一组又可分为两组:把其中一组交通灯的状态视为由另外一组决定。这两组交通灯分别标记为:S2N, S2W, E2W, E2S N2S, N2E, W2E, W2N

交通灯的变红和变绿是有顺序的,比如S2N变红后,S2W变绿;S2W变红后,E2W变绿;E2W变红后,E2S变绿;E2S变红后,S2N变绿。

综上分析:Lamp类共有12个实例对象,故采用枚举的方式定义Lamp。由于交通灯可变红和变绿,故Lamp中用一个boolean型的属性lighted表示红和绿的两种状态;由于第二组的八个交通灯中存在两两联动,故Lamp中用oppsite 属性表示与某一交通灯联动的交通灯;由于交通灯的变红具有顺序,故Lamp中用next属性表示一个交通灯变红后下一个要变绿的交通灯。

由于路线要检测控制它的灯的状态,故Lamp中定义一个方法isLighted()用于返回相应交通灯的状态;同时,Lamp中还需定义两个方法light() blackOut() 分别用于使交通灯变绿和变红;

代码示例如下:

public enumLamp {

       S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),

       /*下面表示与上面相反方向的灯,它们的“相反方向灯”和“下一个灯用null表示*/

       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,Stringnext,boolean lighted){

              this.opposite = opposite;

              this.next = next;

              this.lighted = lighted;

       }

       private boolean lighted; //用于表示等的红绿状态;

       private String opposite; //与当前灯同时为绿的对应方向;

       private String next;     //下一个要变绿的灯;   

       public boolean isLighted(){

              return lighted;

       }

       public void light(){           //用于使灯变绿的方法;

              this.lighted = true;

              if(opposite != null){

                     Lamp.valueOf(opposite).light();

              }

              System.out.println(name() + "lamp is green,下面总共应该有6个方向能看到汽车穿过!");

             

       }

      

       public Lamp blackOut(){        //用于使灯变红的方法;

              this.lighted = false;

              if(opposite != null){

                     Lamp.valueOf(opposite).blackOut();

              }            

             

              Lamp nextLamp= null;

              if(next != null){

                     nextLamp =Lamp.valueOf(next);

                     System.out.println("绿灯从" + name() +"-------->切换为" + next);                   

                     nextLamp.light();

              }

              return nextLamp;

       }

}

4.       需求分析之交通灯控制系统和main方法:

交通灯控制系统用于控制交通灯变化的时间间隔,使当前为绿的交通灯变红,并使下一个交通灯变绿。所以它的构造方法中需要定义一个定时器,定时器中采用每个10s使交通灯按顺序进行变化;

代码示例如下:

importjava.util.concurrent.Executors;

importjava.util.concurrent.ScheduledExecutorService;

importjava.util.concurrent.TimeUnit;

 

public classLampController {

       private Lamp currentLamp;

       public LampController(){

              //刚开始让由南向北的灯变绿;          

              currentLamp = Lamp.S2N;

              currentLamp.light();

              /*定义定时器,每隔10秒使当前绿灯变为红灯,并让下一个方向的灯变绿*/             

              ScheduledExecutorService timer=  Executors.newScheduledThreadPool(1);

              timer.scheduleAtFixedRate(

                            new Runnable(){

                                   public  void run(){

                                          currentLamp= currentLamp.blackOut();

                            }

                            },

                            10,

                            10,

                            TimeUnit.SECONDS);

       }

}

main方法非常简单,首先创建12Road示例对象,用于表示12挑路线,之后开启交通灯控制系统即可。

代码如下:

       public static void main(String[] args) {

             

              /*产生12个方向的路线*/          

              String [] directions = newString[]{

                            "S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"          

              };

              for(inti=0;i<directions.length;i++){

                     new Road(directions[i]);

              }

             

              /*开启交通灯控制系统*/            

              new LampController();

       }

 ---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

详细请查看:<a href="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值