---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
交通灯管理系统:
一.项目需求:
1、异步随机生成按照各个路线行驶的车辆。
2、信号灯忽略黄灯,只考虑红灯和绿灯。
3、应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。 4、具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
5、每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。 6、随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7、不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
二.需求分析:
1).交通信号灯控制器的分析:
1基本概念:将两个方向对立的信号灯归为一组,如南信号灯和北信号灯为一组,东南信号灯和西北信号灯为一组
2.基本逻辑:任意时刻,只能有一组信号灯保持亮的状态,右转车辆不受信号灯控制,因此右转方向不设信号灯
3.基本功能:按照顺时针方向,循环让每一组信号灯保持亮的状态一段时间
2.交通信号灯控制器的数据结构:设置一个方向数组,用来保存需要被调度的方向,
以组为单位 :String[] Direction={"N方向-S方向","NE方向-SW方向","E方向-W方向","ES方向-WN方向"}
3.交通信号灯控制器的方法:
获取当前信号灯状态方法,该方法返回当前一组保存亮状态的信号灯:public String getCurrentStatues();
循环让信号灯保存亮的状态一段时间的方法,该方法按照顺时针 让每一组信号灯保存亮的状态一段时间(我这里设置成10秒钟):public void ControlerRun();
2).车辆的行为分析:
1.基本逻辑:车辆在通过路口时必须检查当前信号灯状态,只有当前信号灯状态和自己的行进状态相同时才能通过路口,
否则等待信号灯转为自己行进方向时再通过。车辆必须按顺序通过路口,当自己前面有车没通过路口时排队等前面的车通过路口再通过
2.车辆的数据结构:车辆对象要保存车辆名称,车辆所属的路,以及车辆的行进方向;
String CarName//车辆的名称
String WhichRoad//车辆在那个路上
String RunDirection//车辆开往的方向
2.车辆应该具有的方法:
1.获取当前信号灯状态: private String getCurrentStatues();
2.判断当前能否通过路口 :boolean CanPass(String CurrentStatues);
3.通过路口 :void PassRoad();
4继续等待 :void WaitForPass();
3).路的行为分析:
1.基本逻辑:所有的车辆都要在路上,因此路是一个容器 ,每辆车通行的时间为一秒因此路每过一秒钟就要查看当前路口的车是否能通过,
通过调用car类的CanPass()函数。如果当前路口的车辆能通过就调用当前车辆的PassRoad()函数,否则调用当前车辆的WaitForPass()函数使车辆在路口继续等待
具体实现代码如下:
/**
* 交通灯控制类,该交通灯类可以定时的改变信号灯状态,小汽车类可以
* 通过该类身上的getCurrentStatus()方法得到当前的信号灯状态以判断是否
* 能够通过路口
*/
class LampControler extends Thread {
final private static String[] Direction = { "ND方向-SD方向", "NE方向-SW方向",
"ED方向-WD方向", "ES方向-WN方向" };// 交通灯可以控制的方向数组
private static int CurrentDirection = 0;//当前的信号灯状态
public void run() {
ControlerRun();
}
public static String getCurrentStatus() {/* 获取当前的交通灯状态 */
return Direction[CurrentDirection];
}
//改变信号灯状态
private void setCurrentDirection() {
CurrentDirection = CurrentDirection + 1;
CurrentDirection = CurrentDirection % 4;
System.out
.println("-------------------------------------------------------------------------------");
System.out.println("现在可以通行车辆的方向是" + getCurrentStatus());
System.out
.println("-------------------------------------------------------------------------------");
}
//定时的改变信号灯状态
private void ControlerRun() {
while (true) {
setCurrentDirection();
holdOn(10);
}
}
private void holdOn(int time) {/* 以秒为单位,可以通过设置这个值来控制每组交通灯亮的时间 */
try {
Thread.sleep(time * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 小汽车类,每一个小汽车对象内部都封装了该小汽车的名称,现在在哪条路上以及要开往的方向
* 小汽车通过交通灯类的getCurrentStatus()方法得到当前的信号灯状态,再和自己要开往的方向
* 作比较,如果当前的信号灯状态和自己要开往的方向相同则通过路口,如果不相同则在路口等待,
* 等待的时候定时的查询交通灯状态直到交通灯状态允许自己通过路口然后通过路口。
*
*/
class Car {
private final static String IgnoreDirection = "NW方向-SE方向-EN方向-WS方向";
private String CarName; // 汽车的名称
private String WhichRoad;// 汽车在哪条路上
private String RunDirection;// 汽车开往哪个方向
private String CurrentStatus;// 当前的交通灯状态
//创建小汽车对象的时候需要指明小汽车的名字,在哪条路上已经要开往哪个方向
public Car(String CarName, String WhichRoad, String Rundirection) {
this.CarName = CarName;
this.WhichRoad = WhichRoad;
this.RunDirection = Rundirection;
}
private void getCurrentStatus() {/* 获取当前的交通灯状态 */
CurrentStatus = LampControler.getCurrentStatus();
}
public boolean CanPass() {/* 判断当前能否通过路口 */
getCurrentStatus();
if (IgnoreDirection.indexOf(RunDirection) != -1) {
return true;
}
return (CurrentStatus.indexOf(RunDirection) != -1) ? true : false;
}
public void PassRoad() {/* 通过路口 */
System.out.println("在" + WhichRoad + "路上的开往" + RunDirection + "的"
+ CarName + "现在已经通过路口");
}
public void WaitForPass() {/* 在路口等待 */
System.out.println("在" + WhichRoad + "路上的开往" + RunDirection + "的"
+ CarName + "正在路口等待");
}
}
/**
* 公路类,公路类是被当做小汽车容器和小汽车产生器来使用的,公路类会不定时的生产小
* 汽车,然后把小汽车对象保存到自己内部的List中,然后每隔一秒钟都会试图从List顶部
* 取出一辆小汽车让他去通过路口,但能否通过路口还要看当前的信号灯状态和小汽车要开往
* 的方向,如果能通过则将该List顶部的小汽车移除,以表示当前小汽车已经通过路口,不能通过
* 则什么也不做,等待一秒继续尝试。
*/
class Road extends Thread {
private LinkedList
RoadCollection = new LinkedList
();//保存小汽车对象的List
private final static String[] WRoad = { "ED方向", "WN方向", "WS方向" };//每条路可以开往的方向
private final static String[] ERoad = { "WD方向", "EN方向", "ES方向" };
private final static String[] NRoad = { "SD方向", "NW方向", "NE方向" };
private final static String[] SRoad = { "ND方向", "SW方向", "SE方向" };
private String[] CanRunDirection;
private int CarNum = 0;// 汽车编号
private String RoadName;// 路的名称
private Car WaitForPassCar;// 在路口等待的那辆车
private Random random = new Random();
//通过创建公路类时给出的名称来决定该公路类上可以开往的方向,
//共有四个公路类,分别为东西南北,每个公路类可以开往的方向不同
public Road(String RoadName) {
this.RoadName = RoadName;
if (RoadName == "WRoad")
CanRunDirection = WRoad;
if (RoadName == "ERoad")
CanRunDirection = ERoad;
if (RoadName == "NRoad")
CanRunDirection = NRoad;
if (RoadName == "SRoad")
CanRunDirection = SRoad;
}
private void RandomCar() {/* 模拟路上的汽车,每隔一段时间随机产生一辆车 */
if (random.nextBoolean()) {
RoadCollection.addLast(new Car("汽车--" + Integer.toString(CarNum++),
RoadName, CanRunDirection[random.nextInt(3)]));
}
}
public void run() {
while (true) {
if (RoadCollection.size() == 0) {
System.out.println(RoadName + "路上一辆车也没有了");//打印提示信息
RandomCar();
} else {
WaitForPassCar = RoadCollection.getFirst();
if (WaitForPassCar.CanPass()) {
WaitForPassCar.PassRoad();//当前信号灯状态允许小汽车通行,则让小汽车通过
RoadCollection.pollFirst();
} else {
WaitForPassCar.WaitForPass();//当前信号灯不允许小汽车通行,则让小汽车等待
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//启动类,用来启动整个程序
public class LampDemo {
public static void main(String[] args) {
new LampControler().start();
new Road("WRoad").start();
new Road("ERoad").start();
new Road("SRoad").start();
new Road("NRoad").start();
}
}
详细请查看: www.itheima.com