现在的位置: 首页 > 综合 > 正文

java、交通灯管理系统

2018年05月06日 ⁄ 综合 ⁄ 共 4877字 ⁄ 字号 评论关闭

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

 

题目:

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

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

例如:

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

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

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

  。。。

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

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

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

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

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

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

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

--------------------------------------------------------------------------------------------------------------------------------

交通灯的逻辑分析:

总共有12条路线,分别是南向北、北向南、南向西、北向东、东向西、西向东、东向南、西向北加上四个右转弯南向东、东向北、北向西、西向南。

路线太多容易搞乱,画图对比下就清楚很多。(尽量画图分清逻辑)

每条路线都有一个红绿灯对其进行控制,总结规律如下:

右转弯的4条路线随时可以通行,所以假设控制等为常绿状态。

另外可以发现北向南和南向北通行状态是相同的,同样南向西和北向东、东向西和西向东、东向南和西向北的通行状态也是相同的,所以,只考虑南向北、南向西、东向西、东向南这4条路线相反方向的路线的控制灯跟随这4条路线切换,不额外考虑。


按照面向对象的思想进行分析: 

题目中涉及到的对象有:交通灯,交通灯的控制系统,汽车,路线

每条路线上都会出现多辆车,路线上要随机增加新的车,在灯绿期间还要每秒钟减少一辆车。按照面向对象的分析经验:谁拥有数据,谁就对外提供操作这些数据的方法。可以将车看成路上存储的数据。

需要设计Road类来表示路线,每个Road对象代表一条路线,总共有12条路线,即系统中总共要产生12个Road实例对象。

每条路线上随机增加新的车辆,增加到一个集合中保存。

每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。

每条路线每隔一秒都会检查控制本路线的灯是否为绿,一个灯由绿变红时,应该将下一个方向的灯变绿。

 

这时就需要设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:红灯或绿灯,每个交通灯要有变红和变绿的方法,并且方法能返回自己的红绿状态。

总共有12条路线,所以,系统中总共要产生12个交通灯。右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方式,故假设出有四个右拐弯的灯,只是这些灯为常绿状态,即永远不变红。

除了右拐弯方向的其他8条路线的灯,它们是两两成对的,可以归为4组,所以,在编程处理时,只要从这4组中各取出一个灯,对这4个灯依次轮询变亮,与这4个灯方向对应的灯则随之一同变化,因此Lamp类中要有一个变量来记住自己相反方向的灯,在一个Lamp对象的变绿和变红方法中,将对应方向的灯也变绿和变红。每个灯变红时,都伴随者下一个灯的变绿,Lamp类中还需要用一个变量来记住自己的下一个灯。

无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp类用枚举来做会更加的方便,永远都只有代表12个方向的灯的实例对象。

最后设计一个LampController类,它定时让当前的绿灯变红。


第一步:创建一个Road类,用来表示路线。路线上随机时间增加的车俩保存到集合中,每一条路线检查自己的灯是否为绿灯,是则将本路线集合中保存的车俩移除,并返回移除的对象名称。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

//创建一个路,路产生车
public class Road {
	// 车的集合
	private List<String> vechicles = new ArrayList<String>();
	// 给每个路创建一个名字
	private String name = null;

	public Road(String name) {
		this.name = name;
		// 线程池创建一组线程,将任务分配给这组线程。
		ExecutorService poll = Executors.newSingleThreadExecutor();
		// 执行一个线程
		poll.execute(new Runnable() {
			public void run() {
				// 为了让它每一秒钟都创建一辆车
				for (int i = 0; i < 1000; i++) {
					// 产生车,意思就是不停的往集合添加车。
					try {
						Thread.sleep((new Random().nextInt(10) + 1) * 1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					vechicles.add(Road.this.name + "的第" + i + "车");// 访问外部类的成员变量:外部类加上this.变量名,因为外部类的成员变量与局部变量重复了
				}
			}
		});
		// 创建一个定时器
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable() {
			public void run() {
				// 判断集合中是否有车,如果大于0
				if (vechicles.size() > 0) {
					// 假如灯是亮的
					boolean lighted = Lamp.valueOf(Road.this.name).islighted();// 访问外部名字,方法同上加类名.this
					if (lighted) {
						System.out.println(vechicles.remove(0) + "正在通过");// revove方法返回的是你正在取的对象的那个的字符串
					}
				}
			}
		}, 1, // 过多久执行
				1, // 没过多久执行
				TimeUnit.SECONDS // 执行时间的单位
		);
	}
}

第二步:创建一个枚举Lamp,来代表交通灯。每一个交通灯都维护一种状态变红或变绿,并且返回自己的红绿状态。当本路线灯变红时,下一个灯变绿。所以定义3个属性。交通灯的状态、本路线对应的灯、下一个路线的灯。

//创建一个灯的类
public enum Lamp {
	// 定义12方向
	S2N("N2S", "S2W", false), S2W("N2E", "E2W", false), E2W("W2E", "E2S", false), E2S(
			"W2N", "S2N", false), N2S(null, null, false), N2E(null, null, false), W2E(
			null, null, false), W2N(null, null, false), S2E(null, null, true), E2N(
			null, null, true), N2W(null, null, true), W2S(null, null, true);
	private Lamp(String opposite, String next, boolean lighted) {
		this.opposite = opposite;
		this.next = next;
		this.lighted = lighted;
	}

	private Lamp() {
	}

	// 定义灯是否是亮的
	private boolean lighted;
	// 定义对应的灯
	private String opposite;
	private String next;

	// 返回灯是否是亮的
	public boolean islighted() {
		return lighted;
	}

	// 定义个方法,将灯的颜色变绿
	public void greenLight() {
		this.lighted = true;
		if (opposite != null) {
			// 也将对应的灯变绿色,通过枚举的valueof方法,给它一个字符串返回字符串的对象
			Lamp.valueOf(opposite).greenLight();
		}
		System.out.println(name() + "方向的灯变绿了,下面总共有6个方向的能看到汽车穿过!");
	}

	// 定义一个方法,将灯的颜色变红
	public Lamp redLight() {
		this.lighted = false;
		if (opposite != null) {
			// 也将对应的灯变红色,通过枚举的valueof方法,给它一个字符串返回字符串的对象
			Lamp.valueOf(opposite).redLight();
		}
		// 假如还有下一个灯,那么然给下一个灯变绿
		Lamp nextLamp = null;
		if (next != null) {
			nextLamp = Lamp.valueOf(next);
			System.out.println("绿灯从" + name() + "切换为" + next);
			nextLamp.greenLight();
		}
		return nextLamp;
	}

}

第三步:创建一个交通灯的控制系统Lampcontroller类,定时让当前的绿灯变红。

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

//创建一个灯的控制器
public class Lampcontroller {
	// 既然它控制灯,那么它肯定有灯的变量
	private Lamp currentLamp;

	// 控制器一创建,那么就必须指示一个灯为绿色
	public Lampcontroller() {
		currentLamp = Lamp.S2N;
		// 并将它的构造方法变绿
		currentLamp.greenLight();
		// 让第一个灯变绿,那么就得过一段时间让下一个灯绿,这个灯红,再定义一个计时器
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			public void run() {
				currentLamp = currentLamp.redLight();
			}
		}, 6, // 过6秒钟后执行
				6, // 每过6秒后执行
				TimeUnit.SECONDS);// 执行单位为秒
	}
}

第四步:创建一个主类MainClass,用来启动该程序。

public class Mainclass {
	public static void main(String[] args) {

		String[] directions = { "S2N", "S2W", "E2W", "E2S", "N2S", "N2E",
				"W2E", "W2N", "S2E", "E2N", "N2W", "W2S" };
		for (int i = 0; i < directions.length; i++) {
			// 创建不同方向的路线
			new Road(directions[i]);
		}
		new Lampcontroller();
	}
}

结果:


----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

抱歉!评论已关闭.