黑马程序员_交通灯管理系统之详细分析

----------  android培训java培训、期待与您交流! ----------



先简单模拟真实的交通灯情况,例如:

南北直线为绿灯:S2E,E2N,N2W,W2S----四个右转一直为绿灯,可随意通行。

S2N, N2S ----南北直线为绿灯

S2W, N2E, E2W, W2E, E2S, W2N ----为红灯

当南北直线能通行时,一共有6条线路通车-----南北两直线方向和4个右转弯。


南北方向结束后,南北直线方向变为红灯,南北左转方向变为绿灯


南北左转为绿灯:S2E,E2N,N2W,W2S ----四个右转一直为绿灯,可随意通行。

S2W, N2E----南北左转为绿灯

S2N, N2S, E2W,W2E,E2S,W2N ----为红灯

当南北左转能通行时,一共有6条线路通车-----南北左转方向和4个右转弯。


南北左转方向结束之后,南北左转方向变为红灯,东西直线方向变为绿灯。


东西直线方向为绿灯:S2E,E2N,N2W,W2S ----四个右转一直为绿灯,可随意通行。

E2W, W2E ----东西直线为绿灯

S2N, N2S,S2W,N2E,E2S,W2N----为红灯

当东西直线能通行时,一共有6条线路通车-----东西直线方向和4个右转弯。


东西直线方向结束后,东西直线方向变为红灯,东西左转方向变为绿灯。

东西左转方向为绿灯:S2E,E2N,N2W,W2S ----四个右转一直为绿灯,可随意通行。

E2S,W2N----东西左转为绿灯

S2N,N2S,S2W,N2E, E2W,W2E----为红灯

当东西左转能通行时,一共有6条线路通车-----东西左转方向和4个右转弯。


南北直线---->南北左转---->东西直线---->东西左转---->又回到南北直线,反复如此。

记住一点,当某一对交通灯为绿灯时,除了四个右转的道路外,其他交通灯都为红灯,每一次都会有6条道路可通行。

交通灯红绿灯的变换情况基本上说完了。


现在分析如何将实际情况变成为编程的模型,或者说转化为编程代码模拟实现这个实际问题。


将实际生活的情况转化为编程模型,需要准确的分析实际情况和准确定位所需要的现实实物为编程所需的对象。

车辆在十字马路不断穿梭运行,首先模拟十字路口车辆来往的模型。

因为我们在模拟交通灯管理系统,所关心的问题是十字路口的车辆情况,

可以这样分析:车辆在当前路线行驶通过路口时,如果当前线路为绿灯,则快速通过路口。红灯时,不能通过路口。

在编程模型中,所需要模拟的是车辆生成和车辆消失的这两个过程。

车辆生成代表,该线路有车辆行驶,即将通过该路口。

车辆消失代表,该线路十字路口为绿灯,快速通过该路口。

道路所需要模拟的车辆情况就是上面这两种:车辆生成和车辆消失。

分析到这里,就应该想如何用代码实现这个问题。

车辆生成:我们可以随机生成车辆,车辆可以用一个list集合代表,添加集合元素等于生成一辆车,移除集合元素等于车辆通过路口消失。

注意,道路上的车辆是不挺的随机生成和按照道路交通灯红绿情况判断是否移除车辆。

两件事都是单独不断的在自己执行,所以生成车辆和移除车辆都得让单独的线程不断执行。

道路车辆模拟完成了,既然移除车辆要依赖线路交通灯红绿情况,所以接下来是考虑交通灯的部分:

交通灯是按线路来安装的,十字路口一共有12条线路。如上面画的大图,右转的线路都是绿灯,可通行的。所以我们要分析考虑的是其余8条线路。

其余8条线路又有对应相同的交通灯,例如:N2S,N2S 这两条线路交通灯是红绿同步的,这里我们把他叫做对面的交通灯。东西直线,东西左转,南北左转都一样。

所以我们要重点考虑的情况只剩4条线路了。


如何模拟真实的交通灯系统呢?

回顾这个:

南北直线---->南北左转---->东西直线---->东西左转---->又回到南北直线,反复如此。

交通灯系统运行的规律是这样的,运用面向对象编程的思想,每一条道路都有对应的交通灯,所以这里要意识到将线路做成对象,交通灯为对象的成员变量,这样设计思路就清晰一点了。现在了解交通灯为一个类,类里12条线路为类的对象,我们要重点考虑关键4条。

设计道路交通灯红或绿系统,首先意识到这交通灯类里要有 设置交通灯变绿方法,设置交通灯变红方法,返回给交通灯当前状态方法

接下来事情,就需要一些巧妙的设计了。

如何让 南北直线---->南北左转---->东西直线---->东西左转----> 又回到南北直线,反复如此。 这个情况转动起来

先是开启交通灯,第一步可以先默认所有交通灯为红色,开启时,南北直线为绿灯,右转4路线一直为绿。

假定工作10s后,交通灯要切换了,这时我们要知道下个组交通灯是那一组。知道下一组以后,关闭当前组,将下一组设置为绿灯。

反复如此就行了。


具体细节看下面的代码吧:

Road类编写:

package TrafficLampSystem2;

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> vehicles=new ArrayList<String>();
	private String name=null;
	
		public Road(String name){
			this.name=name;
			//自动随机生成小汽车上路,1-10S生成一辆。分一个线程执行,让这个线程专门负责生成小汽车
			ExecutorService newcar=Executors.newSingleThreadExecutor();
			newcar.execute(new Runnable(){
				public void run(){
					for (int i = 1; i < 100; i++) {
						try {
							Thread.sleep((new Random().nextInt(10)+1)*1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						vehicles.add(Road.this.name+"这条路线生成小汽车--");
						System.out.println(Road.this.name+"这条路线生成小汽车--"+i);
					}
					
				}
			});
			//生成小汽车end
			//检查交通灯红绿情况,如果是绿灯则移除一辆车代表此车辆以通过路口,红灯则不做移除处理。
			//设定每一秒检查一次交通灯情况,所以使用到定时器,并且也由一个线程单独负责执行
			ScheduledExecutorService pool=Executors.newScheduledThreadPool(1);
			pool.scheduleAtFixedRate(new Runnable(){
				public void run(){
					//先检查是否有车辆
					if(vehicles.size()>0){
						//有车辆,其次检查当前线路交通灯情况
						boolean lighted=Lamp.valueOf(Road.this.name).getlighted();
						if(lighted){
							//移除一辆汽车代表已通过路口
							System.out.println(vehicles.remove(0)+"该车辆已通过路口消失");
						}
					}
					
				}
				
			}, 
			1, 
			1, 
			TimeUnit.SECONDS);
			
		}
	

}

Lamp类编写:

package TrafficLampSystem2;



/*S2N,S2W,E2W,E2S,
N2S,N2E,W2E,W2N,
S2E,E2N,N2W,W2S;*/
public enum Lamp {
	//建立12个路口交通灯,并初始化,对面的交通灯,下个交通灯和当前交通灯的情况
	//false is red,true is green
	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 String opposite;
		private String next;
		private boolean lighted;
		
		private Lamp(String opposite,String next,boolean lighted){
			this.opposite=opposite;
			this.next=next;
			this.lighted=lighted;
			}
		
		//提供交通灯红绿情况
		public boolean getlighted(){
			return lighted;
		}
		
		//设置交通灯的变绿
		public void light(){
			lighted=true;//当前
			if(opposite!=null){//对面
				Lamp.valueOf(opposite).light();
			}
			
			System.out.println(name()+"此条道路绿灯已开启!");
		}
		
		//设置交通灯变红和下个一个灯变绿
		public Lamp blackOut(){
			lighted=false;
			if(opposite!=null){
				Lamp.valueOf(opposite).blackOut();
			}
			
			System.out.println(name()+"此条道路绿灯已关闭!");
			Lamp nextLamp=null;
			if(next!=null){
				nextLamp=Lamp.valueOf(next);
				nextLamp.light();
				
			}
			
				return nextLamp;
		}

}

LampController 类编写:

package TrafficLampSystem2;

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

public class LampController {
	private Lamp currentLamp;
			public LampController(){
				//初始化交通灯控制器,使路口交通灯工作起来.
				System.out.println("十字路口交通灯开始工作!6个路线开始通车");
				currentLamp=Lamp.S2N;
				currentLamp.light();
				
				//每10s改变一次交通灯的红绿情况,使交通灯正常运行起来.
				//使用计时器newScheduledThreadpool
				ScheduledExecutorService timerun=Executors.newScheduledThreadPool(1);
				timerun.scheduleAtFixedRate(new Runnable(){
					public void run(){
						currentLamp=currentLamp.blackOut();//每10s自动切换下个交通灯变绿
					}
				},
				10, 
				10, 
				TimeUnit.SECONDS);
				
			};

}

MainClass类编写:

package TrafficLampSystem2;

public class MainClass {
	public static void main(String[] args){
	String[] directions=new String[]{
			"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培训、期待与您交流! ----------


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值