黑马程序员_交通灯管理



---------------------- android培训java培训、期待与您交流! ----------------------

   交通灯管理系统的需求分析:

异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
……
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

   谁拥有数据,谁就对外提供操作这些数据的方法。

   面向对象的设计需求,先要分析对象

   初步分析 会有四个对象

   1.路线

    Road 表示路线,一共有12条路线,每一条的路线名字是不同的,所以要创建Road的12个实例对象.

    路线要具备的方法:

     增加车辆

     减少车辆

   2.红绿灯

    Lamp类来表示交通灯,因为有12条路线,所以一共就有12交通灯来表示路线,因为右拐弯不受灯的限制,但是为了让系统有统一的管理方式,假如四个右拐弯有交通灯,四个交通的状态是常亮的。

    除了右拐弯的灯以后,还有八个交通灯,因为交通灯的是两两相对的,所以可以分成四组,从这四组中各取出一个灯来控制,与这个灯对应的灯,的状态随着控制灯的变换而变换。

     假如:由南道北的灯是亮的

     对应的灯: 由北到南的灯也是亮的

     下一个灯: 由南到西的灯是不亮的

     对应的灯: 由北到东的灯是不亮的

   3.红绿灯控制器

     lampController类 来表示交通控制器,因为控制器是单一的,最好是用单例模式来设计,也可以用枚举来实现。

   4.汽车

     因为只需要捕捉汽车瞬间移过路口,所以汽车的设计可以用字符串表示。

    

 //路线
public class Road {
   private List<String>vehicle=new ArrayList<String>();
   String roadName;
   public Road(String roadName){
    this.roadName=roadName;
    //用 Executors newSingleThreadExecutor()创建多线程 用 execute()启动run()方法里面的代码
  ExecutorService execSer= Executors.newSingleThreadExecutor();
  execSer.execute(new Runnable(){
   public void run(){
     try {
    Thread.sleep(new Random().nextInt(10)+1*1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
     for(int i=0;i<1000;i++){
     vehicle.add(Road.this.roadName+"方向的车"+i);
   
      }
   }
  });
 //用  Executors 创建定时器 newScheduledThreadPool
    ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);
      
     timer.scheduleAtFixedRate(
       new Runnable(){
        public void run(){
         if(vehicle.size()>0){
          boolean  lighted=Lamp.valueOf(Road.this.roadName).isLighted();
          if(lighted){
           System.out.println(vehicle.remove(0)+"车开走 !");
          }
         }
        }
       },
       1,
      1,
      TimeUnit.SECONDS );
   }
}

   路线图片:

 

//灯
public enum Lamp {
  南(S) 北(N) 东(E)西(W)
  需要控制的等,可以分成四组,单独控制每组灯里的一个。
  南到北  南到西  东到西  东到南
  北到南  北到东  西到东  西到北
  右拐灯:不需要控制,常亮
  南到东  东到北  北到西  西到南
  *
   S2N,S2W,E2W,E2S,
      N2S,N2E,W2E,W2N,
      W2S,S2E,E2N,N2W;
 
   //要控制的四个灯
   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),
      //右拐弯常亮的四个灯
      W2S(null,null,true),S2E(null,null,true),
      E2N(null,null,true),N2W(null,null,true);
      private Lamp(){};
      //因为枚举要先定义后才能使用,所以这就构造函数不直接接收灯的对象,而是接收灯的名字。
      private Lamp(String opposite,String lignext,boolean lighted){
       this.opposite=opposite;
       this.lignext=lignext;
       this.lighted=lighted;
      }
      //接收对应灯的名字
      private String  opposite;
      //接收下一个灯的名字
      private String lignext;
      //灯的状态
      private boolean lighted;
       //返回灯的状态
      public boolean isLighted(){
       return lighted;
      }
      //灯变亮方法
      public void light(){
      
       this.lighted=true;
       //让对应的灯变亮
       if(opposite!=null)
        Lamp.valueOf(opposite).light();
      
       System.out.println("下面可以看到六个方向的灯------------>");
      
      }
      //灯变暗方法
      public Lamp backlight(){
       this.lighted=false;
       //让对应的灯变暗
       if(opposite!=null)
        Lamp.valueOf(opposite).backlight();
       //让下一个灯变亮
      
       if(lignext!=null){
        Lamp temp=Lamp.valueOf(lignext);
      temp.light();
      System.out.println("灯切换了---由 "+this.toString()+"----------"+"到"+lignext+"--->");
      return temp;
       }
       return null;
      }
}

 

 

//灯控制器
public class LampController {
       
 //当前灯
 private Lamp  currentLamp;
 
 public LampController(){
  this.currentLamp=Lamp.S2N;
  //调用灯变亮方法
  currentLamp.light();
 ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);
 timer.scheduleAtFixedRate(
   new Runnable(){
    public void run(){
    currentLamp=currentLamp.backlight();
    }
   },
   3,
   3,
    TimeUnit.SECONDS);
 }
}

 

//测试类
public class LampMainTest {

  public static void main(String[]arge){
     String[] road={ "S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","W2S","S2E","E2N","N2W"};
      for(int i =0;i<road.length;i++){
       new Road(road[i]);
      }
      new LampController();
  }
}

---------------------- android培训java培训、期待与您交流! ----------------------

《Tecplot与MIKE结合教程》是一份详细介绍如何将Tecplot与MIKE软件进行协同工作的学习资料。这份教程旨在帮助用户理解并掌握这两款强大的科学计算与数据可视化工具的整合应用,从而提高在流体动力学、环境工程、海洋科学等领域的模拟分析效率。 Tecplot是一款广泛应用于科研和工程领域的数据可视化和分析软件,它能够处理大量数据,快速生成高质量的2D和3D图形,便于用户理解和解释复杂的数值模拟结果。其强大的后处理能力,如等值线绘制、颜色梯度图、矢量场显示等功能,使得数据的呈现更加直观。 MIKE(原名DHI软件)是由丹麦水力研究所开发的一系列专业仿真软件,主要用于水资源管理、环境流动、海岸工程等领域。MIKE软件家族包括MIKE 11(河流模拟)、MIKE 21(海洋模型)、MIKE 3(三维流体动力学模型)等,可以解决从河流、湖泊到海洋的各类水动力问题。 当Tecplot与MIKE结合使用时,Tecplot作为后处理器,可以接收MIKE软件产生的计算结果,进行更深入的数据解析和可视化。通过这种方式,用户不仅可以查看MIKE模拟出的流场、浓度分布等数据,还能进行多变量分析、动画制作,以及生成专业报告所需的图表,极大地提高了数据分析的效率和质量。 教程中可能会涵盖以下内容: 1. **数据导入**:讲解如何从MIKE软件导出适合Tecplot处理的文件格式,如ASCII或二进制文件。 2. **Tecplot界面操作**:介绍Tecplot的基本操作,如数据加载、变量选择、区域定义等。 3. **数据可视化**:教学如何使用Tecplot创建等值线图、颜色梯度图、矢量图等,以及调整色彩映射、透明度等参数,以清晰地展示MIKE的模拟结果。 4. **动画制作**:说明如何通过Tecplot制作时间序列动画,动态展示流动过程。 5. **高级分析**:可能涉及统计分析、插值运算、剖面图绘制等高级功能,帮助用户深入理解模拟数据。 6. **定制化和脚本编程**:介绍如何利用Tecplot的内置脚本语言(如TecScript或Python)自动化处理MIKE数据,进行批量分析或自定义功能的实现。 7. **案例研究**:提供实际案例,演示Tecplot与MIKE结合的具体应用,如河流污染扩散分析、海岸线变化模拟等。 通过学习这份教程,用户将能够熟练地将Tecplot与MIKE结合使用,提升在复杂水动力问题上的建模和分析能力,为科学研究和工程决策提供有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值