Code for Elevator Saga
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

elevator.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. {
  2. init: function(elevators, floors) {
  3. console.clear();
  4. // Get elevator/building info
  5. let elevatorCount = elevators.length;
  6. let floorCount = floors.length;
  7. let topFloor = floorCount - 1;
  8. let bottomFloor = 0;
  9. console.log("Starting (" + floorCount + " floors; " + elevatorCount + " elevator" + ((floorCount == 1) ? "s" : "") +")...");
  10. // Direction constants
  11. const UP = 0;
  12. const DOWN = 1;
  13. const IDLE = 2;
  14. // Create a data structure for floor requests
  15. let requests = [new Set(), new Set()];
  16. // ----
  17. // Functions
  18. // ----
  19. function getClosestFloor(currentFloor, floorList, ignoredFloors = new Set(), direction = IDLE){
  20. let closestFloor = currentFloor;
  21. let distance = floorCount;
  22. let newDistance = distance;
  23. floorList.forEach(function(floorNum) {
  24. switch (direction) {
  25. case UP:
  26. newDistance = floorNum - currentFloor;
  27. case DOWN:
  28. newDistance = currentFloor - floorNum;
  29. case IDLE:
  30. newDistance = Math.abs(floorNum - currentFloor);
  31. }
  32. if (newDistance < distance && newDistance > 0 && !(ignoredFloors.has(floorNum))) {
  33. closestFloor = floorNum;
  34. distance = newDistance;
  35. }
  36. })
  37. if (closestFloor != currentFloor) {
  38. return closestFloor;
  39. } else {
  40. throw new Error("No floor in selected direction");
  41. }
  42. }
  43. function sendToNext(elevators, elevatorIndex, destinations, requests, restFloors) {
  44. elevator = elevators[elevatorIndex]
  45. if (elevator.loadFactor() < 0.8) {
  46. if (requests[UP].size > 0 || requests[DOWN].size > 0 || destinations.size > 0) {
  47. let allStops = new Set([...destinations, ...requests[UP], ...requests[DOWN]]);
  48. try {
  49. floorNum = getClosestFloor(elevator.currentFloor(), allStops)
  50. console.log("> Sending elevator[" + elevatorIndex + "] to floor[" + floorNum + "]");
  51. elevator.goToFloor(floorNum);
  52. } catch (e) {
  53. console.log("> No closest floor. Sending elevator[" + elevatorIndex + "] to rest floor[" + restFloors[1] + "]");
  54. elevator.goToFloor(restFloors[1]);
  55. }
  56. } else {
  57. console.log("> Sending elevator[" + elevatorIndex + "] to rest floor[" + restFloors[1] + "]");
  58. elevator.goToFloor(restFloors[1]);
  59. }
  60. } else {
  61. floorNum = getClosestFloor(elevator.currentFloor(), destinations)
  62. console.log("> Sending elevator[" + elevatorIndex + "] to destination floor[" + floorNum + "]");
  63. elevator.goToFloor(floorNum);
  64. }
  65. }
  66. function bringClosestElevator(floorNum) {
  67. let closestElevator = 0;
  68. let distance = floorCount;
  69. let newDistance = distance;
  70. elevators.forEach(function (elevator, elevatorIndex) {
  71. newDistance = Math.abs(elevator.currentFloor() - floorNum);
  72. if (newDistance < distance) {
  73. distance = newDistance;
  74. closestElevator = elevatorIndex;
  75. }
  76. });
  77. //console.log("Closest is elevator[" + closestElevator + "]")
  78. elevators[closestElevator].goToFloor(floorNum);
  79. }
  80. function setDirection(elevator, direction){
  81. switch (direction) {
  82. case UP:
  83. elevator.goingUpIndicator(true);
  84. elevator.goingDownIndicator(false);
  85. break
  86. case DOWN:
  87. elevator.goingUpIndicator(false);
  88. elevator.goingDownIndicator(true);
  89. break
  90. default:
  91. elevator.goingUpIndicator(true);
  92. elevator.goingDownIndicator(true);
  93. }
  94. }
  95. // ----
  96. // Floors
  97. // ----
  98. floors.forEach(function (floor) {
  99. floor.on("up_button_pressed", function() {
  100. //console.log("> Up request on floor[" + floor.level + "]");
  101. requests[UP].add(floor.level);
  102. //bringClosestElevator(floor.level);
  103. });
  104. floor.on("down_button_pressed", function() {
  105. //console.log("> Down request on floor[" + floor.level + "]");
  106. requests[DOWN].add(floor.level);
  107. //bringClosestElevator(floor.level);
  108. });
  109. });
  110. // ----
  111. // Elevators
  112. // ----
  113. elevators.forEach(function (elevator, elevatorIndex) {
  114. // Basic elevator info
  115. const restFloors = [
  116. elevatorIndex * Math.floor(floorCount / (elevatorCount + 1)),
  117. (elevatorIndex + 1) * Math.floor(floorCount / (elevatorCount + 1)),
  118. (elevatorIndex + 2) * Math.floor(floorCount / (elevatorCount + 1))
  119. ]
  120. //console.log("Rest floors for elevator[" + elevatorIndex + "]: " + restFloors[0] + ", " + restFloors[1] + ", and " + restFloors[2])
  121. elevator.on("floor_button_pressed", function(floorNum) {
  122. //console.log("> Pressed floor[" + floorNum + "] on elevator[" + elevatorIndex + "]");
  123. destinations.add(floorNum);
  124. });
  125. // Elevator variables
  126. let destinations = new Set();
  127. // Start
  128. setDirection(elevator, IDLE); // Starts on the ground floor
  129. console.log("> Sending elevator[" + elevatorIndex + "] to floor[" + restFloors[0] + "]");
  130. elevator.goToFloor(restFloors[0]); // Closest rest floor
  131. // Idle
  132. elevator.on("idle", function() {
  133. console.log("> Elevator[" + elevatorIndex + "] is idle")
  134. setDirection(elevator, IDLE);
  135. if (requests[UP].size == 0 && requests[DOWN].size == 0 && destinations.size == 0) {
  136. elevator.goToFloor(restFloors[1]);
  137. } else {
  138. sendToNext(elevators, elevatorIndex, destinations, requests, restFloors);
  139. }
  140. });
  141. // Passing
  142. elevator.on("passing_floor", function(floorNum, direction) {
  143. if (elevator.loadFactor() < 1) {
  144. if (requests[UP].has(floorNum) || requests[DOWN].has(floorNum) || destinations.has(floorNum)) {
  145. elevator.goToFloor(floorNum, true);
  146. }
  147. } else if (destinations.has(floorNum)) {
  148. elevator.goToFloor(floorNum, true);
  149. }
  150. });
  151. // Stopped
  152. elevator.on("stopped_at_floor", function(floorNum) {
  153. //console.log("> elevator[" + elevatorIndex + "] stopped at floor[" + floorNum + "]");
  154. destinations.delete(floorNum);
  155. requests[UP].delete(floorNum);
  156. requests[DOWN].delete(floorNum);
  157. sendToNext(elevators, elevatorIndex, destinations, requests, restFloors);
  158. });
  159. });
  160. },
  161. update: function(dt, elevators, floors) {}
  162. }