-------
android培訓、java培訓、期待與您交流! ----------
交通燈管理系統
模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:
1、異步隨機生成按照各個路線行駛的車輛。
例如:
由南向而來去往北向的車輛 ---- 直行車輛
由西向而來去往南向的車輛 ---- 右轉車輛
由東向而來去往南向的車輛 ---- 左轉車輛
……
【思考:車子由什麼產生?產生的車子存儲在什麼裏面?怎麼產生車?】
2、信號燈忽略黃燈,只考慮紅燈和綠燈。
3、應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制。
【思路:考慮右轉的燈都爲長綠燈,表示車隨時可以右轉】
4、具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。
注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而後放行左轉車輛。
5、每輛車通過路口時間爲1秒(提示:可通過線程Sleep的方式模擬)。
【思考:車開過路口這個操作怎麼實現?在哪裏實現?】
6、隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設置。
7、不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
思路:
一、先看車行路線圖例:
二、邏輯中的12個方向的燈:
S2N(南到北),S2W(南到西),E2W(東到西),E2S(東到南) //主要的需要操作的四個燈,它控制通往四個方
向的車
N2S(北到南),N2E(北到東),W2E(西到東),W2N(西到北) //前面四個燈對應的反向燈,讓它們依託於前面
四個燈來運作。
S2E(南到東),N2W(北到西),E2N(東到北),W2S(西到南)//四個右轉燈,它們長亮
三、排除4個長亮燈,我們需要處理的燈有8個燈,不過,每一個燈都有反向的燈。比如S2N(南到北)和
N2S(北到南)。這樣的話,就表示,S2N綠燈的話,那麼N2S也是綠燈。這樣的話,也就是說,剩下的8個
燈中,有四個燈可以依託於它的反向燈的運作來進行相同的運作。【即它的反向燈綠,那麼它綠,它的
反向燈紅,那麼它紅】
四、在這裏車子可以用一個String來表示,根據不同的燈對應的路線,產生這條路線上的車。可以考慮
用12個線程來產生相對應的車。創建一個Road類,該類在構造函數中接受一個表示路線的String
roadName,比如:this. roadName = roadName; 然後根據傳入的路線,來創建這條路線上的車,並把
String表示的車存入這條路線上的ArrayList中。通過它的remove方法來移除這條路線上的車子。不過再
移除的時候,需要先判斷當前路線上的燈是否爲綠燈,綠燈才能移。車子移除出去,就表示車子開過路
口了。這個操作可以通過定時器完成。
五、燈控制器用於操作燈變化的時間,多長時間換下一個燈綠等等
六、一共需要創建三個類:燈(用枚舉),路,燈控制器
模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:
package com.iossoft.traffic;
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;
/*
每個Road對象代表一條路線,總共有12條路線,即系統中總共要產生12個Road實例對象。
每條路線上隨機增加新的車輛,增加到一個集合中保存。
每條路線每隔一秒都會檢查控制本路線的燈是否爲綠,是則將本路線保存車的集合中的第一輛車移除,
即表示車穿過了路口。*/
publicclassRoad{
privateList vechicles=newArrayList();
privateString name=null;
publicRoad(String name){
this.name= name;
//模擬車輛不斷隨機上路的過程
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
public void run(){
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name + "_" + i);
}
}
});
//每隔一秒檢查對應的燈是否爲綠,是則放行一輛車
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
if(vechicles.size()>0){
boolean lighted= Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechicles.remove(0) + " is traversing !");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
二)Lamp類
1.系統中有12個方向上的燈,在程序的其他地方要根據燈的名稱就可以獲得對應的燈的實例對象,綜
合這些因素,將Lamp類用java5中的枚舉形式定義更爲簡單。
2.每個Lamp對象中的亮黑狀態用lighted變量表示,選用S2N、S2W、E2W、E2N這四個方向上的Lamp對象
依次輪詢變亮,Lamp對象中還要有一個oppositeLampName變量來表示它們相反方向的燈,再用一個
nextLampName變量來表示此燈變亮後的下一個變亮的燈。這三個變量用構造方法的形式進行賦值,因爲
枚舉元素必須在定義之後引用,所以無法再構造方法中彼此相互引用,所以,相反方向和下一個方向的
燈用字符串形式表示。
3.增加讓Lamp變亮和變黑的方法:light和blackOut,對於S2N、S2W、E2W、E2N這四個方向上的Lamp對
象,這兩個方法內部要讓相反方向的燈隨之變亮和變黑,blackOut方法還要讓下一個燈變亮。
4.除了S2N、S2W、E2W、E2N這四個方向上的Lamp對象之外,其他方向上的Lamp對象的nextLampName和
oppositeLampName屬性設置爲null即可,並且S2N、S2W、E2W、E2N這四個方向上的Lamp對象的
nextLampName和oppositeLampName屬性必須設置爲null,以便防止light和blackOut進入死循環。
源碼如下:
package com.iossoft.traffic;
publicenumLamp{
//每個枚舉元素各表示一個方向的控制燈
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 Lamp(String opposite,Stringnext,boolean lighted){
this.opposite=opposite;
this.next=next;
this.lighted=lighted;
}
private Lamp(){
}
private boolean lighted;
public boolean isLighted(){
return lighted;
}
//某個燈變綠時,它對應方向的燈也要變綠
public void light(){
this.lighted=true;
if(opposite!=null){
Lamp.valueOf(opposite).light();
System.out.println(name()+" lamp is green,下面總共應該有6個方向能看到汽車穿過!");
}
}
//某個燈變紅時,對應方向的燈也要變紅,並且下一個方向的燈要變綠下一個要變綠的燈
publicLamp blackOut(){
this.lighted=false;
if(opposite!=null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp=null;
if(next!=null){
nextLamp =Lamp.valueOf(next);
System.out.println("綠燈從"+ name()+"-------->切換爲"+next);
nextLamp.light();
}
return nextLamp;
}
}
三)LampController類
1.整個系統中只能有一套交通燈控制系統,所以,LampController類最好是設計成單例。
2.LampController構造方法中要設定第一個爲綠的燈。
3.LampController對象的start方法中將當前燈變綠,然後啓動一個定時器,每隔10秒將當前燈變紅和
將下一個燈變綠。
源碼如下:
package com.iossoft.traffic;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
publicclassLampController{
privateLamp currentLamp;
publicLampController(){
//剛開始讓由南向北的燈變綠;
currentLamp = Lamp.S2N;
currentLamp.light();
/*每隔10秒將當前綠燈變爲紅燈,並讓下一個方向的燈變綠*/
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
四)MainClass類
1.用for循環創建出代表12條路線的對象。
2.接着創建出LampController對象。
package com.iossoft.traffic;
publicclassMainClass{
public static void main(String[] args){
/*產生12個方向的路線*/
String[] directions=newString[]{
}
-------android培訓、java培訓、期待與您交流! ----------