C++实现路口交通灯模拟系统

yizhihongxing

C++实现路口交通灯模拟系统完整攻略

介绍

本系统利用C++语言实现,模拟了路口交通灯的控制,包括车辆的停止和通行,交通信号的改变等。系统结构清晰,代码简单易懂,适合初学者学习C++语言的基础和面向对象编程的实现。

设计思路

本系统的设计思路涉及到面向对象编程的基本思想。首先将路口、红绿灯、车辆等实体抽象为类,通过类的成员函数实现对对象的控制。同时,本系统利用时钟实现交通信号的周期变化和车辆通行的延迟等功能。

功能设计

  • 系统启动
  • 输入交通信号灯的周期
  • 车辆按照随机时间在四个方向出发
  • 如果红绿灯是绿色,则车辆可以通过,否则必须停止等待
  • 每次绿灯持续时间结束后,交通信号灯会自动变成红色,另一个方向的红绿灯变为绿色,如此往复。

代码实现

红绿灯类

首先定义红绿灯类,由于红灯和绿灯的状态只能存在一个,因此用枚举类型定义状态。

class TrafficLight
{
public:
    enum LightState {Green, Red};
    LightState State;
    void Change() { State = (State == Green ? Red : Green); }
    TrafficLight(): State(Red) {}
};

车辆类

车辆类包含了车辆的出发时间和方向,可以定义一个时间戳表示出发时间,并设置一个随机数生成函数。在模拟时钟滴答的时候,我们需要获取当前时间并让所有车辆检查自己是否可以通过路口,如果不能则停止。

class Car
{
public:
    int TimeStamp;
    Direction Dir;
    int GetRand(int min, int max) { return min + rand() % (max - min + 1); }
    Car():TimeStamp(0), Dir(North) {}
    bool CanPass(const TrafficLight& tl, int currtime)
    {
        if (tl.State == TrafficLight::Red)
        {
            return false;
        }
        if (currtime - TimeStamp < 10)
        {
            return false;
        }
        return true;
    }
};

路口类

路口类包含四个方向的车辆列表和两个红绿灯。

class RoadIntersection
{
public:
    vector<Car> Cars[4];
    TrafficLight Light[2];
    void Tick(int currtime);
    void Print();
};

在路口类中定义了模拟时钟滴答的函数Tick(),每滴答一次,会让红绿灯变化,并检查车辆是否可以通过路口。

void RoadIntersection::Tick(int currtime)
{
    // 红绿灯变换
    if (currtime % Light[0].Cycle == 0)
    {
        Light[0].Change();
        Light[1].Change();
    }
    // 车辆检测
    for (int i = 0; i < 4; i++)
    {
        for (auto& car : Cars[i])
        {
            if (car.CanPass(Light[i/2], currtime))
            {
                car.TimeStamp = currtime;
                Cars[i].erase(std::find(Cars[i].begin(), Cars[i].end(), car));
                Cars[Next(i)].push_back(car);
            }
        }
    }
}

在Tick()中,我们用STL库中的std::find查找车辆是否在当前方向,如果车辆不能通过,则从当前方向删除;如果车辆可以通过,则产生一个新的时间戳,然后将车辆从当前方向删除,并将车辆添加到下一个方向。

接着是交通信号灯的控制:

class TrafficLight
{
public:
    void Change() { State = (State == Green ? Red : Green); }
    TrafficLight(): State(Red), Cycle(20) {}
    LightState State;
    int Cycle;
};

定义了两个信号灯,灯的周期是20个单位时间。在滴答中,由第一个信号灯控制车辆行驶的方向,由第二个信号灯控制其它方向的车辆通行。如果是绿色状态,可以直接行驶,否则,要等待红绿灯变为绿色。

class RoadIntersection
{
public:
    void Tick(int currtime);
};

可以定义Tick()函数,实现模拟时钟的滴答:

void RoadIntersection::Tick(int currtime)
{
    // 红绿灯变换
    if (currtime % Light[0].Cycle == 0)
    {
        Light[0].Change();
        Light[1].Change();
    }
    // 车辆检测
    for (int i = 0; i < 4; i++)
    {
        for (auto& car : Cars[i])
        {
            if (car.CanPass(Light[i/2], currtime))
            {
                car.TimeStamp = currtime;
                Cars[i].erase(std::find(Cars[i].begin(), Cars[i].end(), car));
                Cars[Next(i)].push_back(car);
            }
        }
    }
}

主程序

主程序实现了输入交通灯的周期,和一些车辆的初始化。

int main()
{
    srand(time(nullptr));
    int Cycle = 20;
    RoadIntersection intersection;
    int cnt = 0;
    while (cnt < 20)
    {
        intersection.Tick(cnt++);
        if (cnt % Cycle == 0)
        {
            for (int i = 0; i < 4; i++)
            {
                int ncars = intersection.Lights[i/2].State == TrafficLight::Green ? 
                            intersection.GetRand(1, 10) : 0;
                for (int j = 0; j < ncars; j++)
                {
                    intersection.Cars[i].push_back(Car());
                }
            }
        }
        intersection.Print();
        std::this_thread::sleep_for(chrono::milliseconds(200));
    }
    return 0;
}

示例说明:

假如我们要模拟一个周期为20的红绿灯定时器,主程序每经过20个单位时间,交通信号灯的第一个信号灯会变色,并且每个方向上的车辆会出发,通过或停止。因此,main()函数里循环计时器定时器,驱动系统滴答。每个周期后,需要获取红绿灯的状态,如果是绿色,随机关数以生成车辆,并将其加入到当前方向的列表中。最后输出所有车辆的状态,用std::this_thread::sleep_for防止程序运行过快。

示例2:

我们可以设置目标物理系统有不同时间点的行为要求。例如:某时刻,南北方向需要有10辆车通过路口,而东西方向只需1辆车通过路口。可以在主程序中按行进方向,决定车辆的行进数量。

int main()
{
    srand(time(nullptr));
    int Cycle = 20;
    RoadIntersection intersection;
    int cnt = 0;
    while (cnt < 20)
    {
        intersection.Tick(cnt++);
        if (cnt % Cycle == 0)
        {
            for (int i = 0; i < 4; i++)
            {
                int ncars = 0;
                if (i == North || i == South)
                {
                    ncars = intersection.Lights[0].State == TrafficLight::Green ? 
                             intersection.GetRand(1, 10) : 0;
                }
                else
                {
                    ncars = intersection.Lights[1].State == TrafficLight::Green ?
                            intersection.GetRand(1, 2) : 0;
                }
                for (int j = 0; j < ncars; j++)
                {
                    intersection.Cars[i].push_back(Car());
                }
            }
        }
        intersection.Print();
        std::this_thread::sleep_for(chrono::milliseconds(200));
    }
    return 0;
}

总结

本文介绍了如何使用C++实现一个简单的路口交通灯模拟系统。通过理解本系统的代码,能够学习到C++语言的基本语法和面向对象编程的基本思想。同时,对于系统设计的优化,也会有一定的了解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现路口交通灯模拟系统 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言与C++中内存管理详解

    C语言与C++中内存管理详解 内存管理是C语言和C++中非常重要的一部分,正确的内存管理可以避免内存泄漏和内存溢出等问题,从而提高程序的稳定性和性能。本文将详细介绍C语言和C++中的内存管理技巧和注意事项。 内存分配和释放 在C语言和C++中,内存分配和释放是通过动态内存管理函数来实现的。C语言中的动态内存管理函数包括malloc()、calloc()和re…

    C 2023年5月22日
    00
  • MathWorks Matlab R2021b(V9.11)密钥安装+许可激活图文教程

    首先,需要注意的是,安装和激活Matlab软件需要使用合法的许可证密钥。本攻略提供的密钥仅供学习和测试目的。 下载Matlab安装包 首先,需要前往MathWorks官网下载Matlab R2021b安装包。如果已经拥有安装包,则跳过此步。 前往官网: https://www.mathworks.com/downloads/ 选择“Download”按钮,进…

    C 2023年5月22日
    00
  • C++11中std::thread线程实现暂停(挂起)功能

    要实现线程的暂停或挂起功能,可以利用C++11中提供的条件变量condition_variable。下面是具体的步骤: 首先定义一个互斥锁mutex和条件变量condition_variable,用来实现多个线程之间的互斥和同步操作: std::mutex mtx; std::condition_variable cv; 然后在线程函数中加入while循环,…

    C 2023年5月22日
    00
  • JSON在Java中的使用方法实例

    下面是JSON在Java中的使用方法实例的详细攻略: 什么是JSON JSON是一种轻量级的数据交换格式,全称为JavaScript Object Notation。它是一种易于读写的文本格式,可与几乎所有编程语言一起使用,包括Java。 Java中的JSON库 Java中有多个库可以用于处理JSON,其中最流行的库是GSON和Jackson。这里我们以GS…

    C 2023年5月23日
    00
  • VSCode launch.json配置详细教程

    首先,我们需要了解什么是VSCode的launch.json文件。launch.json是配置VSCode调试器的文件,在这个文件中,我们可以设置如何运行我们的代码、哪些文件需要调试、以及如何传递命令行参数等等。 接下来,让我们通过以下步骤创建一个新的launch.json文件: 在VSCode中打开你的项目文件夹。 打开调试器工具栏。(快捷键F5) 在工具…

    C 2023年5月23日
    00
  • C++实现教工考勤信息管理系统

    C++实现教工考勤信息管理系统完整攻略 系统说明 教工考勤信息管理系统是一个基于C++的控制台应用程序,用于管理教工的考勤信息。其主要功能包括:添加教工信息、查找教工信息、浏览教工信息、删除教工信息、按照考勤情况进行筛选等。 系统设计 系统结构 教工考勤信息管理系统采用面向对象的设计思想,其系统结构包含以下几个类: 教工类:用于存储教工的基本信息,包括姓名、…

    C 2023年5月23日
    00
  • UltraEdit技巧总结

    UltraEdit 技巧总结攻略 简介 UltraEdit 是一款功能强大的文本编辑器,被广泛应用于程序员、系统管理员、DBA 等专业人群的日常工作中。UltraEdit 不仅仅是一个文本编辑器,还拥有丰富的编码、调试、FTP/SFTP 等功能。本文旨在总结 UltraEdit 的常见技巧,帮助使用者提高使用效率和体验。 使用技巧 以下是使用 UltraEd…

    C 2023年5月22日
    00
  • C语言中system()执行cmd命令打开关闭程序的方法

    下面是详细讲解“C语言中system()执行cmd命令打开关闭程序的方法”的完整攻略: 1. system()函数简介 在C语言中,system()函数是一个非常强大的函数,它可以让我们执行许多操作系统命令,包括打开和关闭程序。下面是system()函数的定义: #include <stdlib.h> int system(const char …

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部