天天看點

java 交通燈 黑馬程式員學習筆記(10)

;

;

java 交通燈 黑馬程式員學習筆記(10)

總結交通燈管理系統

 通過上圖可以看出,每個路口的車到十字路口有三個選擇:筆直向前、右拐彎、左拐彎,那麼總共有3*4=12條路線。

分别是:

E(east)、W(west)、S(south)、N(north)。

E2W(東往西),E2N(東往北),E2S(東往南);

S2N(

南往北),S2E(南往東),S2W(南往西)

W2E(西往東),W2S(西往南),W2N(西往北)

N2S(北往南),N2W(北往西),N2E(北往東) ;

分析對象

1.汽車判斷前面是否有車,問路,路中存儲車的集合。路提供增加減少車輛的方法

1.1.誰擁有資料,誰就提供對外操作的方法

1.2人在黑闆上畫圓。

誰提供畫圓,黑闆。半徑、圓心

1.3列車司機刹車

1.燈、控制系統、汽車、路線、控制器

2.路提供汽車減少的方法

這麼以想程式的核心就出來了

出來就是三個對象,可以把車去掉

1)   路與交通燈的對應情況

因為右拐彎不受紅綠燈影響,那麼右轉彎的4條路線的控制燈可以假設成為常綠狀态。此外,其他的8條路線是成對出現,隻是方向不同,可以分為4組,所 以,交通燈排程隻考4條路線控制燈的切換順序,這4條路線相反方向的控制燈跟随這4條路線切換,是以不必額外考慮。

2)  異步随機生成按照各個路線行駛的車輛:

由東向而來去往西向的車輛-------直行車輛;

由東向而來去往北向的車輛-------右轉車輛;

由東向而來去往南向的車輛-------左轉車輛;

由南向而來去往北向的車輛-------直行車輛;

由南向而來去往東向的車輛-------右轉車輛;

由南向而來去往西向的車輛-------左轉車輛;

由西向而來去往東向的車輛-------直行車輛;

由西向而來去往南向的車輛-------右轉車輛;

由西向而來去往北向的車輛-------左轉車輛;

由北向而來去往南向的車輛-------直行車輛;

由北向而來去往西向的車輛-------右轉車輛;

由北向而來去往東向的車輛-------左轉車輛;

2.1.信号燈忽略黃燈,隻考慮紅燈和綠燈。

2.2. 應考慮左轉車輛控制信号燈,右轉車輛不受信号燈控制。

2.3. 具體信号燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。

注:東西南北方向順序放行。預設南北為綠燈,(首先通車)

1. 每輛車通過路口時間為1秒(提示:可通過線程sleep()模拟,停止的時間)。

2. 随機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設定。

3.定義一個擷取下一個燈狀态的參數,用來接收目前燈狀态改變後,傳回下一個等狀态的參數。

package com.isoftone.interview.traffic;
 
publicclass MainClass {
 
     publicstaticvoid main(String[] args) {
    //NEW 12個方向,可以使用數組來循環便于偷懶
          
           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();
          new LampController();
 
    }
}
燈控制器
package com.isoftone.interview.traffic;

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

public class LampController {

      private Lamp currenLamp;
      public LampController(){
           //初始化燈
           currenLamp=Lamp.S2N;
           //路燈亮
           currenLamp.light();

      ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
      timer.scheduleAtFixedRate(
                 new Runnable() {
                      public void run() {
                            currenLamp=currenLamp.blackOut();


                      }
                 },
                 10,
                 10,
                 TimeUnit.SECONDS);

      }
}

燈
package com.isoftone.interview.traffic;
 
/**
 *每個Lamp元素代表一個方向上的燈,總共有12個方向,所有總共有12個Lamp元素。
 *有如下一些方向上的燈,每兩個形成一組,一組燈同時變綠或變紅,是以,
 *程式代碼隻需要控制每組燈中的一個燈即可:
 * s2n,n2s   
 * s2w,n2e
 * e2w,w2e
 * e2s,w2n
 * s2e,n2w
 * e2n,w2s
 *上面最後兩行的燈是虛拟的,由于從南向東和從西向北、以及它們的對應方向不受紅綠燈的控制,
 *是以,可以假想它們總是綠燈。
 *@author張孝祥org
 *
 */
 
publicenum Lamp {
   //十二個燈的狀态
     S2N("N2S","S2W",false),S2W("N2W","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 Stringnext;
     privatebooleanlighted;
     private Stringopposite;//對應的燈
     publicboolean isLighted(){
          returnlighted;
      }
     
       //燈變綠時,它對應方向的燈也要變綠
       
       
     publicvoid light(){
          this.lighted=true;
          //不這樣寫會死循環
          if(opposite!=null){
                //傳回枚舉對象
                 Lamp.valueOf(opposite).light();
           }
          
           System.out.println(name()+"Lamp is green,下面總共應該有6個方向能看到汽車穿過");
      }
     
     public Lamp blackOut(){
          this.lighted=false;
          if(opposite!=null){
                //傳回枚舉對象
                 Lamp.valueOf(opposite).blackOut();
           }
          //綠等為null會影響下面的執行
           Lamp nextLamp=null;
          if (next!=null) {
                 nextLamp=Lamp.valueOf(next);
                 nextLamp.light();
          System.out.println("綠燈從"+name()+"--------->>切換為"+next);
           }
          return nextLamp;
      }
 
}
路
package com.isoftone.interview.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;

public class Road {


        //1.外部類+final
      //2.通路外部類的成員變量,内部類,使用外部類的名字+this.内部類的成員變

      List<String> vechicles = new ArrayList<String>();
    private String name=null;

    public Road(String name){
           this.name=name;
           ExecutorService pool=Executors.newSingleThreadExecutor();
           //new一個實作類
           pool.execute(new Runnable() {

                 public void run() {

                     for(int i=1;i<1000;i++){
                       try {
                            Thread.sleep(new Random().nextInt(10)+1*1000);
                            System.out.println("随機停頓時間");
                            } catch (Exception e) {
                                  System.out.println("出現線程異常,情況!");
                            }

                       //重名通路外部類name
                       vechicles.add(Road.this.name+"_"+i);
                       System.out.println("增加第"+i+"車輛");
                     }

                 }
           });
           //做定時器
           ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
           timer.scheduleAtFixedRate(
                      new Runnable() {

                            public void run() {
                                  //移走路上的車
                                  if(vechicles.size()>0){
                                       boolean lightd=true;
                                       if (lightd) {
                                             //傳回拿出的資料
                                             System.out.println(vechicles.remove(0)+"is traveling!");

                                       }
                                  }


                            }
                      },
                      1,
                      1,
                      TimeUnit.SECONDS);

    }
}*/


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執行個體對象。
 *每條路線上随機增加新的車輛,增加到一個集合中儲存。
 *每條路線每隔一秒都會檢查控制本路線的燈是否為綠,是則将本路線儲存車的集合中的第一輛車移除,即表示車穿過了路口。
 * @author張孝祥 www.it315.org
 *
 */
public class Road {
      private List<String> vechicles = new ArrayList<String>();

      private String name =null;
      public Road(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);

      }
}