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

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

交通灯管理系统

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

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

           如:

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

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

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

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

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

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

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

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

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

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

 

解题思路:

一、(1)由南向北的车辆——直行车辆; (2)由南向西的车辆——左转车辆; (3)由南向东的车辆——右转车辆

二、变灯:(路1)先直行在拐弯在另一条道(路2)先直行在拐弯,然后重复

三、初步对象有:灯的控制系统、汽车、路线;(1)汽车看到自己所在路线对应的路灯还要看前面是否有车;(2)看前面是否有车,注意:路是存储车辆的集合;

四、(1)路上就应该有增加车辆和减少车辆的需求;(2)但我们不要车移动的过程,而要捕捉车辆穿过路口过程(车辆增减的过程),车就应该设置为字符串(路上集合中的字符串),而不设置对象;所以对象就路,灯,灯控制系统。

注意:谁拥有数据,谁就有对外提供操作这些数据的方法;

五、灯一共有12个(右拐有灯——常绿共4个),因为数量是确定的——考虑枚举(12个实例对象)。

灯(枚举的对象:12个):

设计4个灯(有逻辑):自身变亮,对应相反也变亮;(反之变红也一样,同时下一个方向上边绿)

灯的变量有3个(相反方向的灯和下一个方向上的灯、还有灯自身的状态),3个成员变量

右拐的灯常亮(true)

控制灯的控制器:

         变量:当前的绿灯

                   方法:定时器——变灯用的(返回值:下一个灯)

 

解题步骤:

定义Load

(1)    定义集合V(交通工具—泛型),通过构造方法”路”获取路的名字,

(2)    (通过用java5线程库,以及线程池)ExecutorServicepool =Executors.NewSingleThreadExecutor(),获得的池来执行一个线程pool.execute(new Runnable(){})通过里面的run(),来不断的产生车辆(“路+车名”),可以使用Thread.sleep()里面定义随机值产生车,注意要抛异常;

(3)    定义定时器:(多线程的运行代码:把集合中的第一辆车移走(要判断灯)、过多少时间后接着移走

ScheduledExecutorService timer =Executors.newScheduledThreadPool(1))

//代码如下

package traffic.lamp; 

import java.util.*; 

importjava.util.concurrent.ExecutorService; 

import java.util.concurrent.Executors; 

importjava.util.concurrent.ScheduledExecutorService; 

import java.util.concurrent.TimeUnit; 

public class Road { 

   private String name; 

   final List vechiles = new ArrayList(); 

   Road( String name){ 

       this.name=name; 

       //创建一个线程池 

       ExecutorService pool = Executors.newSingleThreadExecutor(); 

       pool.execute( new Runnable() { 

           public void run() { 

                for(int i=1;i<100;i++){ 

                    try{ 

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

                    }  

                    catch (InterruptedExceptione) { 

                       e.printStackTrace(); 

                    } 

                   vechiles.add(Road.this.name+"-"+i); 

                } 

           } 

       }); 

       ScheduledExecutorService timer =Executors.newScheduledThreadPool(1); 

       timer.scheduleAtFixedRate( 

           new Runnable() { 

                public void run(){ 

                    if(vechiles.size()>0){ 

                       if(Lamp.valueOf(Road.this.name).lighted()){ 

                           System.out.println(vechiles.remove(0)+"正在通过..."); 

                        } 

                    } 

                } 

           }, 

                1,  

                1, 

                TimeUnit.SECONDS); 

       } 

 

建立灯类(枚举的方法)

(1)定义构造方法有3个参数(对应的灯、下一个灯,灯开始是否为亮的);12个灯列表

(2)判断灯是否变绿,额外还有3个方法 ”灯变绿” 或 ”灯变红” 以及 ”下一个灯” ;

package traffic.lamp; 

public enum Lamp { 

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

   N2S(false,null,null),N2E(false,null,null),W2E(false,null,null),W2N(false,null,null), 

   S2E(true,null,null),E2N(true,null,null),N2W(true,null,null),W2S(true,null,null); 

   private boolean lighted; 

   private String oppLamp; 

   private String nextLamp; 

   private Lamp(boolean lighted,String oppoLamp,String nextLamp){ 

       this.lighted=lighted; 

       this.oppLamp=oppoLamp; 

       this.nextLamp=nextLamp; 

   } 

   public boolean lighted(){ 

       return lighted; 

   } 

   public boolean isLighted(){ 

       this.lighted=true; 

       if(oppLamp!=null){ 

           Lamp.valueOf(oppLamp).isLighted(); 

       } 

        return lighted; 

   } 

   public Lamp isDarked(){ 

       this.lighted=false; 

       if(nextLamp!=null){ 

           Lamp.valueOf(nextLamp).isLighted(); 

           System.out.println("绿灯从"+name()+"切换为"+Lamp.valueOf(nextLamp)); 

       }  

       return Lamp.valueOf(nextLamp); 

   } 

建立控灯系统类

建立成员变量控灯,并将其进行构造函数初始化,通过线程池以及多线程获取run()

package traffic.lamp; 

import java.util.concurrent.Executors; 

importjava.util.concurrent.ScheduledExecutorService; 

import java.util.concurrent.TimeUnit; 

public class LampController { 

   private Lamp currentLamp; 

   public LampController() { 

       currentLamp=Lamp.S2N; 

       currentLamp.isLighted(); 

       ScheduledExecutorService timer =Executors.newScheduledThreadPool(1); 

        timer.scheduleAtFixedRate( 

           new Runnable() { 

                public void run() { 

                   currentLamp=currentLamp.isDarked(); 

                } 

           }, 

           10,  

           10, 

           TimeUnit.SECONDS); 

   } 

}

 

主函数

package traffic.lamp; 

 

public class MainTest { 

   public static void main(String[] args) { 

       String[] direction ={"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"}; 

       for(int i=0;i<direction.length;i++){                                                new Road(direction[i]); 

       } 

       new LampController(); 

   } 

}

 

额外面向对象的知识:

1、  熟悉面向对象:人在黑板画圆person blackboard circle(3个对象);——圆              关门的动作——门

列车司机停车——车            售货员统计票据金额:——票据         减少汽车的方法——路

2、  球过绳子:对象有小球(有移动的方法,在构造方法中将绳子传给小球);绳子(为球的移动提供了方法即nextPoint()——获取摸一个点的下一个坐标,还有2个点 )

3、  2块石头磨成一把石刀,石刀可以砍树,木材可以做成椅子:Stone—StoneKnife—tree—material—chair

StoneKnife = KnifePactory.creatKnife(Stone first,Stonesecond)//2块石头变成一把,该方法接受的应该是石头

Material = StoneKnife.cut(tree) //刀有一个方法,变量是tree

Chair = ChairFactory.makeChair(Material)//椅子加工有一个方法,变量是材料

 

 

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值