結對項目小組成員:張永、吳盈盈
又是一周過去了,在上周對電梯調度問題做過大概的分析之后,本周末我們開始對這個項目進行實現,因為時間緊迫,我們目前只實現了其中的電梯的外部調度的部分,也是較為重要的一部分。
周五白天和永哥進行了一番商量,下午因為永哥要練車,於是我開始了對界面進行設計。
我們的界面分為三個部分,一是電梯外部控制模塊,二是電梯內部的控制模塊,三是電梯運行狀態的顯示模塊。在外部控制模塊中有0-20層,每層(除0和20外)都有上下鍵按鈕,用於乘客向電梯發出請求;在電梯的內部控制模塊中,都有0-20的按鍵用於乘客選擇目的樓層;在電梯運行狀態的模塊,我們用了四個電梯門來表示電梯門的運動狀態,當到達知道指定樓層時,電梯門會開啟,電梯門上面顯示的是當前的樓層,旁邊則記錄着當前人數和重量,如遇超載則發出警報。
其中電梯按鍵都是用的checkbox,因為可以支持多選。電梯門用的panel。
周六的上午,永哥開始為我們的程序填充內容。
首先按照我們之前的設想建立了如下幾個類:
因為本次項目樓層眾多,電梯數目也較多,算法和思想雖並不難理解,但重復的代碼較為繁雜。
我們首先實現的是電梯的外部控制。
在電梯的外部控制中,我們對其算法的設想是:
准備:我們把電梯的運行狀態分為以下五種,(1)靜止STOP,(2)向上運行UP,(3)向下運行DOWN,(4)向上運行暫停UP_STOP,(5)向下運行暫停DOWN_STOP。
第一步:用電梯的當前樓層減去乘客發出請求的樓層,並對其差值進行比較排序,按差值從小到達存入數組a[]中。
代碼實現如下:
public static ElevatorObject choseElevator(People people, ElevatorObject elevator1, ElevatorObject elevator2, ElevatorObject elevator3, ElevatorObject elevator4) { ElevatorObject chosenElevator=new ElevatorObject(0) ; ElevatorObject testElevator=null; ElevatorObject[] a_Elevator = new ElevatorObject[]{elevator1,elevator2,elevator3,elevator4}; int test = 0; int elevator1_distance=elevator1.getCurFloor()-people.getPeopleFloor();//1號電梯現在的樓層距當前乘客的距離 int elevator2_distance=elevator2.getCurFloor()-people.getPeopleFloor();//2號電梯現在的樓層距當前乘客的距離 int elevator3_distance=elevator3.getCurFloor()-people.getPeopleFloor();//3號電梯現在的樓層距當前乘客的距離 int elevator4_distance=elevator4.getCurFloor()-people.getPeopleFloor();//4號電梯現在的樓層距當前乘客的距離 int[] a = new int[] { elevator1_distance, elevator2_distance, elevator3_distance, elevator4_distance }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3 - i; j++) { if (a[j] > a[j + 1]) { test = a[j]; testElevator = a_Elevator[j]; a[j] = a[j + 1]; a_Elevator[j] = a_Elevator[j + 1]; a[j + 1] = test; a_Elevator[j + 1] = testElevator; } } }
第二步:以電梯上升時為例,分情況進行調度。
1、當四部電梯的當前樓層都在乘客指定樓層之下時,選定a[0]對其運動狀態進行判斷,當其的運動狀態為(1)(2)(4)時,則對它進行調度,若為其他狀態則判斷a[1],以此類推。
case Number.UP: if (a[3] < 0) { for (int i = 3; i >= 0; i--) { if (a_Elevator[i].getElevatorStates() == Number.UP || a_Elevator[i].getElevatorStates() == Number.UP_STOP || a_Elevator[i].getElevatorStates() == Number.STOP) { chosenElevator = a_Elevator[i]; i = -1;//跳出for循環 } } }
2、當只有三部電梯的當前樓層在乘客指定樓層之下時,首先判斷第四部電梯a[3]是否在指定樓層及其以上(<a[2])停止,若不是則繼續按1中判斷進行調度。
else if (a[2] < 0) { if ((a[3] == 0&&a_Elevator[3].getElevatorStates()==Number.UP_STOP)||(a_Elevator[3].getElevatorStates()==Number.STOP&&a[3]<(0-a[2]))) { chosenElevator = a_Elevator[3]; } else { for (int i = 2; i >= 0; i--) { if (a_Elevator[i].getElevatorStates() == Number.UP || a_Elevator[i].getElevatorStates() == Number.UP_STOP || a_Elevator[i].getElevatorStates() == Number.STOP) { chosenElevator = a_Elevator[i]; i = -1;//跳出for循環 } } } }
3、當只有兩部電梯的當前樓層在乘客指定的樓層之下時,首先判斷距離指定樓層最近的a[2]是在指定樓層及其以上(<|a[1]|)停止,其次再判斷a[3](<|a[2]|),都不是則繼續按1中判斷進行調度。
else if (a[1] < 0) { if ((a[2] == 0 && a_Elevator[2].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates()==Number.STOP && a[2] < (0 - a[1]))) { chosenElevator = a_Elevator[2]; } else if((a[3] == 0&&a_Elevator[3].getElevatorStates()==Number.UP_STOP)||(a_Elevator[3].getElevatorStates()==Number.STOP&&a[3]<(0-a[2]))) { chosenElevator = a_Elevator[3]; } else { for (int i = 1; i >= 0; i--) { if (a_Elevator[i].getElevatorStates() == Number.UP || a_Elevator[i].getElevatorStates() == Number.UP_STOP || a_Elevator[i].getElevatorStates() == Number.STOP) { chosenElevator = a_Elevator[i]; i = -1;//跳出for循環 } } } }
4、當只有一部電梯的當前樓層在乘客的指定樓層之下時,首先判斷距離指定樓層最近的a[1]是在指定樓層及其以上(<|a[0]|)停止,其次再判斷a[2](<|a[1]|),在判斷a[3](<|a[2]|)都不是則繼續按1中判斷進行調度。
else if (a[0] < 0) { if ((a[1] == 0 && a_Elevator[1].getElevatorStates() == Number.UP_STOP) || (a_Elevator[1].getElevatorStates()==Number.STOP && a[1] < (0 - a[0]))) { chosenElevator = a_Elevator[1]; } else if ((a[2] == 0 && a_Elevator[2].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[2] < (0 - a[1]))) { chosenElevator = a_Elevator[2]; } else if ((a[3] == 0 && a_Elevator[3].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[3] < (0 - a[2]))) { chosenElevator = a_Elevator[3]; }
5、當所有電梯都在指定樓層之上時,則選擇靜止狀態的進行調度。
else { if ((a[0] == 0 && a_Elevator[0].getElevatorStates() == Number.UP_STOP) || a_Elevator[0].getElevatorStates()==Number.STOP ) { chosenElevator = a_Elevator[0]; a_Elevator[0].setElevatorStates(Number.UP); } else if ((a[1] == 0 && a_Elevator[1].getElevatorStates() == Number.UP_STOP) || (a_Elevator[1].getElevatorStates() == Number.STOP && a[1] < (0 - a[0]))) { chosenElevator = a_Elevator[1]; } else if ((a[2] == 0 && a_Elevator[2].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[2] < (0 - a[1]))) { chosenElevator = a_Elevator[2]; } else if ((a[3] == 0 && a_Elevator[3].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[3] < (0 - a[2]))) { chosenElevator = a_Elevator[3]; } }
在多次調試之后,電梯的外部控制的調度告一段落。
以下是運行的截圖。
相比外部控制,內部的控制更為容易一些,我們已經實現了電梯一的內部控制,還沒來得及給剩下的三部添加。還有對人的類的隨機從產生人數和體重的功能還沒有實現,在接下來的開發中我們會慢慢的實現。
PS.跟着永哥做項目特別有收獲,我們在結對開發的過程中,絕大多數都是永哥作飛行員,我做導航的學員,在看他調試程序的過程中學到很多,同時也會提出一些可能存在的問題,或是出現問題的原因,永哥總是能按部就班的進行測試發現問題所在並很快的改正,這份踏實和機智是我特別應該學習的。OK,今天就先到這吧。