作业描述
一个十字路口,共有四组红绿灯,每个路口的车辆都遵循“红灯停、绿灯行”的原则,假设将每一台汽车都作为一个进程,请设计良好的机制,展示出合理的“十字路口交通管理”情况。
作业要求
车辆数目:每个路口的车辆数目不超过5辆,程序能够提供参数来设定初始的车辆数目。
交通灯设定:初始情况一个路口为红灯、一个路口为绿灯;红灯变为绿灯的间隔为3秒,必须保持十字路口交通灯的设定正确。
车辆通行设定:路口宽度不限,对一个路口而言,只有当一辆车通过路口(越过对面路口的交通灯后)后,其后续车辆才能继续通过交通灯,车辆通过路口的时间可以固定、可以自行计算,但是不能为3秒。(即必须体现交通灯对通行的管制)。
实现要求:本道作业可以在Windows平台或Minix平台实现,在两种平台下,都必须实现动态界面展示,Windows平台可以使用GUI界面或者文本字符界面,在Minix平台下,实现文本字符界面。
解决方案
设计两个类,分别为TTrafficCross和TVehicle,分别为路口类和车辆类。
用TTime控件持续调用TTafficCross的Refresh函数来保持路口的实时运行。
用TTafficCross的VehicleCreate函数每秒按几率在各个方向生成车辆。
用datCrossOccupied作为路口占用的信号量,用以维护路口指挥同时被南北或东西方向占用。
用datLights储存各个路口交通灯的状态。
每个车辆TVehicle自身维护一个一维坐标系,作为自己在自己方向上的状态。
绘图是根据方向和车辆自身的坐标系坐标,转变为二维坐标绘制在datImage上。
车辆数量、交通灯时间也已经能够在界面设置。
部分代码
窗体文件fromMain.pas
var
TrafficCross: TTrafficCross;
IsCreated: bool; //判定是否已经创建对象
procedure Tfrmmain.FormCreate(Sender: TObject);
//初始化Timer及窗体
procedure Tfrmmain.btnStartClick(Sender: TObject);
//读入初始化数据,并创建TrafficCross对象
procedure Tfrmmain.btnFinishClick(Sender: TObject);
//释放TrafficCross对象
procedure Tfrmmain.timerMainTimer(Sender: TObject);
//Timer触发事件,调用TrafficCross. Refresh
路口类classCross.pas
TTrafficCross= class
public
constructor Create(var image: TImage; time_green,time_red,time_yellow: TLightsTime;
initialnum: TCrosses; timerinterval: TTime;
speed: TCoordinateSD; maxnum: TUInt; createprop: TUInt);
//initialnum记录初始交通状况,
车辆列队于道路外边界坐标依次 0, [1].long, [2].head+[2].long, …
//timerinterval记录外部timer的扫描周期
procedure Refresh;
private
conTimerInterval: TTime;
conMaxVehicle: TUInt; //单向最大车辆数
conCreateProp: TUInt; //每秒车辆生成率
conTimeGreen, conTimeRed, conTimeYellow: TLightsTime; //交通灯时间长度
conFrontier: TCrossesFrontier;
//各个车道外边缘左上角的坐标,用于绘制车辆时的参考坐标
datImage: TImage; //绘图区域,设为400*400
datTimeLights: array[0..3]of TTime;
// 从绿色开始的 绿黄红黄 一个循环的时间变更点
datVehicles: array[1..4,1..50] of TVehicle;
//各个方向的车辆列表 const_MaxVehicle=50
datVehiclesCount: TCrosses;
//当前各个方向的车辆数的计数器
datVehiclesColor: TCrosses;
//当前新创建车辆的颜色,在1–5之间循环
datVehiclesHead: array[1..4]of TCoordinateSD;
//当前新创建车的起始位置
datVehicleType: TVehicleType;
// 在初始化时定义的除了颜色外的标准化模型
datLights: TCrossLights;
// 对各个路口交通灯状态的记录,每次模拟都以1–3方向为绿灯开始
datLightTime: TTime;
//记录交通灯使用时间,以便更颜色
datCrossOccupied: TDirection;
// 路口占用信号量,只在0,1中取值,基数号路口为1,偶数号路口为0
procedure VehicleMove; //判断车辆状态并移动车辆
procedure VehicleCreate; //随机车辆生成器
procedure VehicleFree; //车辆释放
procedure Draw; //总的绘图
procedure DrawRoad; //绘制路口和交通灯
procedure ClockMove; //红绿灯变更
procedure CrossOccupy; //路口占用信号亮变更
procedure VehicleIncrease(direction: TCoordinateSD); // 按几率生成车辆
published
property Image: TImage read datImage;
end;
车辆类classVehicle.pas
TVehicle= class
public
constructor Create(var image: TImage; vtype: TVehicleType; direction: TDirection; head: TCoordinateSD; timeinterval: TTime);
//head表示车头在自己道路上相距街道外边缘的距离,
正值表示在街道内,负职表示在街道外等候
procedure Move;
//移动
procedure Draw(frontier: TCoordinateDD);
//BoundaryCoordinate–各个路口外边线线左上角相对于canvas的坐标
private
datImage: TImage;
//绘图区域
datHead: TCoordinateSD;
//车头的相对坐标
datType: TVehicleType;
//车辆特点描述
datMoveable: TMoveable;
//判断能否移动
datRealSpeed: TCoordinateSD;
//每个时间周期的速度
conTimerInterval: TTime;
//扫描的时间周期
conDirection: TDirection;
//车辆方向
procedure setMoveable(moveable: TMoveable);
//用于改变Moveable的属性
published
property Moveable: TMoveable read datMoveable write setMoveable;
//能否移动
property Long: TCoordinateSD read datType.long;
//车长
property Head: TCoordinateSD read datHead;
//车辆头坐标
property Speed: TCoordinateSD read datRealSpeed;
//每个时间周期的速度
end;
常量及类型表unitConst.pas
{ 画布大小400*400
单个车道宽度20
车辆宽度10
车辆长度20
车辆据车道边界距离5
单边街道长度180
模拟从1-3方向通行开始
}
//自定义类型表
Type
TInt= integer;
TShort= shortint;
TUShort= byte;
TUInt= Word;
TULong= Longword;
TBool= boolean;
TLightColor= TUShort;
// green 0 , yellow 1 , red 2 , yellow 3
TCrossLights= array[1..4] of TLightColor;
TTime= TULong;
TLightsTime= array[1..4]of TTime;
//四个路口同一种信号灯的时间长度
TCrosses= array[1..4]of TUShort;
TDirection= TUShort;
TCrossesFrontier= array[1..4] of TCoordinateDD;
TMoveable= TBool;
TCoordinateSD= TInt;
//一维坐标
TCoordinateDD= record //二维坐标
x,y :TCoordinateSD;
end;
TVehicleType=record
speed: TCoordinateSD;
long, width: TCoordinateSD;
color: TColor;
end;
//自定义常熟表
Const
const_Red: TLightColor= 2;
const_Green: TLightColor= 0;
const_Timer_Interval=50;
// 时钟周期,单位:毫秒
const_Light_Color: array[0..3]of TColor=(clGreen,clYellow,clRed,clYellow);
//交通灯颜色列表
const_Cross_WholeLong: TCoordinateSD= 400;
// 画布大小
const_Cross_StreetLong: TCoordinateSD= 180;
// 单边街道长度
const_Cross_HalfCrossLong: TCoordinateSD= 20;
// 单个车道宽度
const_Vehicle_Long: TCoordinateSD= 20;
// 车辆长度
const_Vehicle_Width: TCoordinateSD= 10;
// 车辆宽度
const_Vehicle_Colors: array[1..5]of TColor=(clSkyBlue,clYellow,clBlue,clLime,clRed);
//用于生成车辆的颜色表
const_MaxVehicle: TUInt= 50;
//单车道最大容量
const_PerTime= 1000;
//单位时间周期,为1秒,1000纳秒
附件
可执行文件和源代码包:TrafficLights
3 Comments
你好!很想和你交流下关于交通灯的问题。可以叫我的QQ吗??急切期待中。。。。
交通灯 漂亮~
似乎并没用到多线程……..