`
tsdl2009
  • 浏览: 5564 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论
阅读更多

交通灯管理系统

   

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



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

例如:



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



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



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



       。。。



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

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

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

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



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

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

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

         对于这道题,我想,首先这是一个不是状态模式的一个状态机。根据,张孝祥老师提供的思路,我知道了

每一个交通灯都有它各自的状态,又由于它的状态仅需模拟红、绿两个状态,不像状态模拟一样,需要针对每个状态设计类,那么仅需要一个枚举就可以了,当然,我们还需要一个枚举来设定控制的方向,或者说是路口的方向。

   解题步骤:(1)我首先设置两个枚举类型,即是交通灯颜色和控制的方向。源代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TrafficDemo
{
    /// <summary>
    /// 交通灯颜色
    /// </summary>
    public enum LightState
    {
        Green=0,
        Red=1
    }

    /// <summary>
    /// 控制的方向
    /// </summary>
    public enum ControlDirection
    {
        /// <summary>
        /// 南北
        /// </summary>
        SN,
        /// <summary>
        /// 北南
        /// </summary>
        NS,
        /// <summary>
        /// 东西
        /// </summary>
        EW,
        /// <summary>
        /// 西东
        /// </summary>
        WE,
        /// <summary>
        /// 南西
        /// </summary>
        SW,
        /// <summary>
        /// 南东,右转
        /// </summary>
        SE,
        /// <summary>
        /// 北东
        /// </summary>
        NE,
        /// <summary>
        /// 北西,右转
        /// </summary>
        NW,
        /// <summary>
        /// 西南,右转
        /// </summary>
        WS,
        /// <summary>
        /// 西北
        /// </summary>
        WN,
        /// <summary>
        /// 东北,右转
        /// </summary>
        EN,
        /// <summary>
        /// 东南
        /// </summary>
        ES
    }

    /// <summary>
    /// 一个交通灯
    /// </summary>
    public class Light
    {
        protected LightState state;
        /// <summary>
        /// 交通灯当前的颜色状态
        /// </summary>
        public virtual LightState State
        {
            get { return state; }
            set { state = value; }
        }

        public virtual void ChangeState()
        {
            //忽略黄灯
            State = (LightState)Math.Abs((int)State-1);
        }

        /// <summary>
        /// 该交通灯控制的方向
        /// </summary>
        public ControlDirection Direction
        {
            get;
            set;
        }

        LightControl control;

        /// <summary>
        /// 该交通灯属于哪组控制器
        /// </summary>
        public LightControl Control
        {
            get { return control; }
            set { control = value; }
        }
    }
}
其布局的图如下:

(2)接着,我们考虑交通灯,这里需求中需要考虑的是常亮的灯,比如,大部分路口的右转灯;对于所有的灯,都要有一个状态,控制的方向,以及一个改变状态的方法。其源代码如下:
/// <summary>  
  /// 一个交通灯  
  /// </summary>  
  public class Light  
  {  
      protected LightState state;  
      /// <summary>  
      /// 交通灯当前的颜色状态  
      /// </summary>  
      public virtual LightState State  
      {  
          get { return state; }  
          set { state = value; }  
      }  
 
      public virtual void ChangeState()  
      {  
          //忽略黄灯  
          State = (LightState)Math.Abs((int)State-1);  
      }  
 
      /// <summary>  
      /// 该交通灯控制的方向  
      /// </summary>  
      public ControlDirection Direction  
      {  
          get;  
          set;  
      }  
 
 
/// <summary>  
  /// 固定常亮的信号灯  
  /// </summary>  
  public class FixLight:Light  
  {  
      public override LightState State  
      {  
          get 
          {  
              return base.State;  
          }  
          set 
          {  
              state = LightState.Green;  
          }  
      }  
      public override void ChangeState()  
      {  
          //什么都不做  
      }  
  } 
这里FixLight继承了Light类。
   (3)然后,就是最关键的东西了,考虑交通灯肯定不止一个,在一个路口,需要对一些交通灯的状态进行轮换,而且,各个路口的轮换模式还不一样,有的是南北对开,然后左转、有的是直行和左转同时亮,然后是另外一个方向的直行和左转。归根结底,其实就是把交通灯划分为几组,同组的交通灯状态时相同的,状态变换只需要切换当前的组别就可以了。因此,引入组控制器,每个组控制器之间是一个互斥的状态。
/// <summary>  
/// 一组控制器  
/// </summary>  
public class LightControl  
{  
    Dictionary<ControlDirection, Light> lights;  
    /// <summary>  
    /// 该控制器控制的所有交通灯,这些交通灯有同样的状态  
    /// </summary>  
    public Dictionary<ControlDirection, Light> Lights  
    {  
        get 
        {  
            return lights;  
        }  
        set 
        {  
            lights=value;  
            foreach (Light light in lights.Values)  
            {  
                light.Control = this;  
            }  
        }  
    }  
 
    LightState state;  
 
    /// <summary>  
    /// 本组内的状态  
    /// </summary>  
    public LightState State  
    {  
        get 
        {  
            return state;  
        }  
        set 
        {  
            state = value;  
            ChangeState(state);  
        }  
    }  
 
    public LightControl()  
    {  
        Lights = new Dictionary<ControlDirection, Light>();  
    }  
 
    public void ChangeState()  
    {  
        foreach (Light light in Lights.Values)  
        {  
            light.ChangeState();  
        }  
    }  

(4) 另外,在日常生活中,我们还注意到在路口等红灯的时候,如果一个路口的交通灯不会自动变化的话,往往在路口边都会有个大箱子,一个交通协管站在边上,时间差不多了的时候,就伸手在箱子里拨一下,灯就变了,当然,有的时候是交警在路口拿个遥控器按一下,效果是一样的。站在用户接口的角度上,不可能让他们去一组组改变状态,因此,就会有个路口控制器,针对每一组进行轮换控制。因此,这里设置一个路口控制器。
/// <summary>  
/// 路口控制器  
/// </summary>  
public class CrossRoadControl  
{  
 
     /// <summary>  
     /// 该路口的交通灯集合,这个集合其实仅在动态改变本路口交通灯分组的时候需要用到  
     /// </summary>  
     public Dictionary<ControlDirection, Light> Lights  
     {  
         get;  
         set;  
     }  
 
     List<LightControl> controls;  
     /// <summary>  
     /// 该路口的控制器集合  
     /// </summary>  
     public List<LightControl> Controls  
     {  
         get 
         {  
             return controls;  
         }  
         set 
         {  
             controls = value;  
             if (value.Count > 0)  
             {  
                 activeIndex = 0;  
             }  
         }  
     }  
 
     int  activeIndex;  
 
     /// <summary>  
     /// 当前激活的控制器序号  
     /// </summary>  
     public int ActiveIndex  
     {  
         get 
         {  
             return activeIndex;   
         }  
         set   
         {  
             activeIndex = value;  
             if (value >=0 && value<controls.Count)  
             {  
                   
                 foreach (LightControl control in controls)  
                 {  
                     if (controls.IndexOf(control)==activeIndex)  
                     {  
                         control.ChangeState( LightState.Green);  
                     }  
                     else 
                     {  
                         control.ChangeState( LightState.Red);  
                     }  
                      
                 }  
             }  
         }  
     }  
 
 
     public CrossRoadControl()  
     {  
         Controls = new List<LightControl>();  
         Lights=new Dictionary<ControlDirection,Light>();  
     }  
 
     /// <summary>  
     /// 改变所有交通灯到下一组状态  
     /// </summary>  
     public void ChangeState()  
     {  
         //当前这一组变化信号  
         controls[activeIndex].ChangeState();  
         activeIndex++;  
         if (activeIndex >= controls.Count)  
             activeIndex = 0;  
         //下一组变化信号  
         controls[activeIndex].ChangeState();  
     }  
 

这里,Light、LightControl和C rossRoadControl三者之间关系如图所示。
    
(5)最后,就是调用,由于路口控制器中使用集合存储组控制器,因此每个路口是三岔还是十字都是可变的,组控制器控制的交通灯也是集合,因此组控制策略就是可变的,当然别设置成东西向和南北向同组了,这样会碰车的。
这里使用最简单的四个灯的十字路口如下:
//只有四个方向的灯  
       Dictionary<ControlDirection, Light> lights = new Dictionary<ControlDirection, Light>  
       {  
          {ControlDirection.NS,new Light{ Direction=ControlDirection.NS} },  
          {ControlDirection.SN,new Light{ Direction=ControlDirection.SN} },  
          {ControlDirection.WE,new Light{ Direction=ControlDirection.WE} },  
          {ControlDirection.EW,new Light{ Direction=ControlDirection.EW} }  
       }; 
       #region 分为两组  
       LightControl control1 = new LightControl();  
       control1.Lights = new Dictionary<ControlDirection, Light>  
       {  
           {ControlDirection.NS,lights[ControlDirection.NS]},  
           {ControlDirection.SN,lights[ControlDirection.SN]},  
       };//南北,北南是一组  
 
       LightControl control2 = new LightControl();  
       control2.Lights = new Dictionary<ControlDirection, Light>  
       {  
           {ControlDirection.EW,lights[ControlDirection.EW]},  
           {ControlDirection.WE,lights[ControlDirection.WE]},  
       };//东西,西东是一组  
 
 
       List<LightControl> controls = new List<LightControl>();  
       controls.Add(control1);  
       controls.Add(control2);  
       #endregion  
 
       //该路口控制器只需要控制两组灯即可  
       CrossRoadControl road = new CrossRoadControl  
       {  
           Controls = controls,  
           Lights = lights  
       };  
       road.ActiveIndex = 0;  
       InitDisplay(road);  
       RefreshButton();  
 
       StopThread();  
       thd = new Thread(new ParameterizedThreadStart(Begin));  
       thd.Start(road); 
    其实,上面还可以组合成八方向,有左转,八方向,右转灯常亮,三岔路口等,代码类似,这里就不做介绍了。到这里, 基本上交通管理系统完成了,其结构如下:
路口控制器--->组控制器---->交通灯
如果考虑路口车辆的通过,这个就不属于交通灯控制的范畴了,有兴趣的可以自己开一个线程生成汽车,然后判断当前方向的灯是否亮(人工智能模拟?)
分享到:
评论

相关推荐

    VUE面试题二.zipVUE面试题二.zip

    VUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE面试题二.zipVUE...

    JAVA面试题2.rar

    JAVA面试题2JAVA面JAVA面试题2JAVA面试题2JAVA面试题2JAVA面试题2JAVA面试题2JAVA面试题2试题2JAVA面试题2JAVA面试题2JAVA面试题2JAVA面试题2

    .net面试题2.net面试题2

    .net面试题2.net面试题2.net面试题2.net面试题2.net面试题2.net面试题2.net面试题2.net面试题2

    SQL面试题2

    SQL面试题SQL面试题SQL面试题SQL面试题SQL面试题SQL面试题SQL面试题SQL面试题

    华为面试题华为面试题华为面试题华为面试题华为面试题

    JAVA面试题JAVA面试题JAVA面试题JAVA面试题JAVA面试题JAVA面试题

    asp.net初级面试题2

    asp.net初级面试题2,接着第一初级面试题

    java面试题 2

    没有想到华为的面试题就是非同一般,很多题不是一眼就能够看得出来,至少对我这种鸟来说是这样。对我个人来说,看看这样的题,可能比看《Think In Java》都还要好,因为这里面有很多的东西,都是我们平时没有太在意...

    java面试题,J2EE面试题 笔试题

    2、各个公司面试题 3、J2EE初学者面试题 4、J2EE面试题(打码查错题) 5、java_华为笔试题 6、java常见面试题 7、java程序员面试宝典 8、java面试题及答案 9、java面试题编程篇 10、Oracle面试题 11、Oracle企业面试...

    .NET面试题(精华版)

    面试题2 介绍ASP.NET和ASP的区别 面试题3 说明ASP.NET的Application特性 面试题4 简述ASP.NET的页面运行机制 面试题5 简述ASP.NET一个页面的生命周期 面试题6 C#中的托管代码是什么 通常将在CLR的控制下运行的代码...

    C++经典面试题2C++经典面试题2

    C++经典面试题2 C++经典面试题2 C++经典面试题2 C++经典面试题2 C++经典面试题2

    Java 后端面试题2附答案

    Java 后端面试题2附答案

    面试题面试题面试题2

    百度 面试题

    .net 面试题系列(网上收集)很全

    2008/06/17 18:42 2,699 .net 面试题系列文章二(附答案).txt 2008/06/17 18:41 2,395 .net 面试题系列文章五(附答案).txt 2008/06/17 18:40 1,847 .net 面试题系列文章八.txt 2008/06/17 18:41 5,352 .net 面试...

    ASP.NET面试题2

    ASP.NET面试题2ASP.NET面试题2ASP.NET面试题2ASP.NET面试题2ASP.NET面试题2ASP.NET面试题2

    2019互联网面试题第2季,互联网面试题及答案,Java

    2019互联网面试题第2季

    hibernate面试题2

    hibernate 面试题,让你了解面试!

    .net基础面试题二

    我将我收集的所有.net程序员在面试的时候会遇到的面试题都贡献出来啦。

    2021最新大厂AI面试题q2版121题.21.7.19

    本资源为2021年最新大厂AI面试题的第二版,共121题,涵盖了机器学习、深度学习、计算机视觉、自然语言处理等多领域的知识点。以下是该资源中的一些重要知识点: 1. 数据结构和算法:包括二叉查找树、快速排序、链表...

    人事面试题及答案

    8. 人事面试题(二) 9. 人事面试题(三) 10. 人事面试题(四) 11. 人事面试题(五) 12. 人事面试题(六) 13. 人事面试题答案 14. 人事面试问题回答思路 15. 上海面试题补充 16. 上海人事面试题

    sql面试题2

    sql面试题2

Global site tag (gtag.js) - Google Analytics