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

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 2023年5月23日
    00
  • 适合新手小白DEV C++的使用方法

    下面将为您详细讲解“适合新手小白DEV C++的使用方法”的完整攻略。 简介 DEV C++是一款免费、开源的C/C++ IDE,适用于初学者和中级开发人员开发C/C++应用程序。它具有易于使用、功能强大、跨平台等特点。本篇攻略将详细讲解如何使用DEV C++进行C/C++程序的编写、调试、编译和运行。 下载与安装 首先,你需要在官网上下载和安装DEV C+…

    C 2023年5月22日
    00
  • C++浅析数据在内存中如何存储

    C++浅析数据在内存中如何存储 概述 在计算机科学中,数据在内存中如何存储是一个非常重要的问题。C++是一门非常流行的编程语言,了解C++中数据在内存中的存储方式有助于更好地理解C++程序的工作原理。 数据类型 C++中的数据类型有很多,包括整型、浮点型、字符型等。每一种数据类型在内存中的存储方式不同,下面我们就来具体讲解不同数据类型在内存中的存储方式。 整…

    C 2023年5月23日
    00
  • vscode C++远程调试运行(学习C++用)

    下面是vscode C++远程调试运行的攻略: 准备工作 首先,我们需要在本地安装 Visual Studio Code 和 C++ 编译器,以及在远程服务器上安装 gdbserver 和相应的 C++ 编译器。 安装 Visual Studio Code:进入Visual Studio Code官网,下载并安装最新版本。 安装 C++ 编译器:如果你已经安…

    C 2023年5月23日
    00
  • PHP+JQUERY操作JSON实例

    关于“PHP+JQUERY操作JSON实例”的完整攻略,我会从以下几个方面进行详细讲解: 什么是JSON 如何使用PHP操作JSON 如何使用JQUERY操作JSON 示例说明 1. 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,很多前端开发人员都会使用JSON来传输数据,特别是在AJAX中经常使…

    C 2023年5月22日
    00
  • 解析MySQL中mysqldump工具的基本用法

    我们来详细讲解一下“解析MySQL中mysqldump工具的基本用法”的完整攻略。 什么是mysqldump工具? mysqldump是MySQL数据库备份工具,可以备份MySQL数据。该工具可以将MySQL数据库的数据复制到另一个地方,如另一个服务器或另一个本地文件系统。 基本用法 mysqldump工具的基本用法非常简单,下面给出一个实例。 mysqld…

    C 2023年5月22日
    00
  • C语言字符串原地压缩实现方法

    C语言字符串原地压缩实现方法 基本原理 C语言中的字符串实际上是字符数组,以’\0’结尾。要实现字符串的压缩,可以对字符数组进行压缩,即将连续重复的字符替换为该字符和重复次数的组合。 实现步骤 定义两个指针,一个指向原始的字符数组,另一个指向压缩后的字符数组的末尾。 定义一个计数器,用于统计连续相同字符的个数。 遍历原始字符数组,如果当前字符和上一个字符相同…

    C 2023年5月22日
    00
  • 如何快速辨别USB Type-C数据线的好与坏?

    当购买USB Type-C数据线时,要注意以下几点: 步骤一:看外观 数据线的外观可以直接反映其质量。一般而言,好的USB Type-C数据线的线材会采用高质量的材料,比如高纯度铜线或高密度尼龙编织线,手感较为舒适,并且线料表面会进行人性化的设计,如添加防滑纹路。此外,好的USB Type-C数据线会采用高质量的接头,面料通常会采用金属材质,防止耐用性下降。…

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