黑馬程序員 JAVA 紅綠燈系統邏輯

 

              ------- 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培訓期待與您交流! ----------

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章