Advertisement
Guest User

Untitled

a guest
Aug 27th, 2016
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. function getCommands(field, power) {
  2. var myField = new Field(field);
  3. var robby = new Robot(myField.startPoint, power, Directions.NORTH, []);
  4. myField.prettyPrint();
  5.  
  6. var winnerRobots = [];
  7. var explored = new PathSet();
  8. var frontier = new PathSet();
  9.  
  10. // initial frontier value
  11. frontier.add(robby.getState(), robby);
  12.  
  13. while(frontier.states.length) {
  14. var fs = frontier.states.shift();
  15. consume(fs);
  16. }
  17.  
  18. function consume(fs) { // fs for frontier state
  19. // 1 transfer to explored
  20. explored.add(fs.state, fs.robot);
  21. // 2 check solution
  22. if(fs.state.isPointEqual(myField.targetPoint)) {
  23. winnerRobots.push(fs.robot);
  24. return;
  25. }
  26. // 3 check power level
  27. if(fs.robot.power === 0) {
  28. return;
  29. }
  30. // 4 discover options, add to frontier if new
  31. var options = fs.robot.discoverOptions(myField);
  32. options.forEach(function(opt) {
  33. var resultState = fs.robot.predictState(opt, myField);
  34. if(!frontier.exists(resultState) && !explored.exists(resultState)) {
  35. var roboSpawn = fs.robot.clone();
  36. roboSpawn.executeCommand(opt, myField);
  37. frontier.add(resultState, roboSpawn);
  38. }
  39. });
  40.  
  41. }
  42.  
  43. console.log('The winners are:');
  44. console.log(winnerRobots);
  45. if(!winnerRobots.length) {
  46. return [];
  47. }
  48. return winnerRobots.sort((r1, r2) => r2.power - r1.power)[0].commandLog;
  49. }
  50.  
  51. var Commands = {
  52. "TURN_RIGHT": "r", // turn right by 90°
  53. "TURN_LEFT": "l", // turn left by 90°
  54. "MOVE_FORWARDS": "f" // move one field forwards into current direction
  55. };
  56.  
  57. var Fields = {
  58. "WALKABLE": ".", // Robby may walk on this
  59. "BLOCKED": "#", // Robby must not walk on this
  60. "START": "S", // Robby is starting here, he may also walk here
  61. "TARGET": "T" // The target cell, Robby has to reach
  62. };
  63.  
  64. var Directions = {
  65. "NORTH": 0,
  66. "EAST": 1,
  67. "SOUTH": 2,
  68. "WEST": 3
  69. }
  70.  
  71. function State(x, y, d) {
  72. this.x = x;
  73. this.y = y;
  74. this.d = d;
  75. }
  76.  
  77. State.prototype = {
  78. isEqual: function(otherState) {
  79. return this.x === otherState.x && this.y === otherState.y && this.d === otherState.d;
  80. },
  81. isPointEqual: function(point) {
  82. return this.x === point.x && this.y === point.y;
  83. }
  84. }
  85.  
  86. function PathSet(states) {
  87. this.states = states || [];
  88. }
  89.  
  90. PathSet.prototype = {
  91. add: function(state, robot) {
  92. if(!this.exists(state)) {
  93. this.states.push({state: state, robot: robot});
  94. }
  95. },
  96. exists: function(state) {
  97. return this.states.filter((s) => {
  98. return state.isEqual(s.state);
  99. }).length;
  100. }
  101. }
  102.  
  103. function Field(field) {
  104. this.size = Math.sqrt(field.length);
  105. this.square = [];
  106. for(var i = 0; i < this.size; i++) {
  107. this.square.push([]);
  108. for(var j = 0; j < this.size; j++) {
  109. this.square[i][j] = field[this.size * i + j];
  110. if(this.square[i][j] === Fields.START) {
  111. this.startPoint = { x: i, y: j }
  112. }
  113. if(this.square[i][j] === Fields.TARGET) {
  114. this.targetPoint = { x: i, y: j }
  115. }
  116. }
  117. }
  118. }
  119.  
  120. Field.prototype = {
  121. prettyPrint: function() {
  122. console.log('\n');
  123. for(var i = 0; i < this.size; i++) {
  124. console.log(this.square[i].join(' '));
  125. console.log('\n');
  126. }
  127. console.log('\n');
  128. }
  129.  
  130. }
  131.  
  132. function Robot(startPoint, power, direction, commandLog) {
  133. this.x = startPoint.x;
  134. this.y = startPoint.y;
  135. this.power = power;
  136. this.direction = direction;
  137. this.commandLog = [...commandLog];
  138. }
  139.  
  140. Robot.prototype = {
  141. turnRight: function() {
  142. this.direction++;
  143. if(this.direction > Directions.WEST) {
  144. this.direction = Directions.NORTH;
  145. }
  146. this.power--;
  147. this.commandLog.push(Commands.TURN_RIGHT);
  148. },
  149. turnLeft: function() {
  150. this.direction--;
  151. if(this.direction < Directions.NORTH) {
  152. this.direction = Directions.WEST;
  153. }
  154. this.power--;
  155. this.commandLog.push(Commands.TURN_LEFT);
  156. },
  157. moveForward: function(field) {
  158. if(this.canWalk(field)) {
  159. var np = this.getNextPoint(field);
  160. this.x = np.x;
  161. this.y = np.y;
  162. this.power--;
  163. this.commandLog.push(Commands.MOVE_FORWARDS);
  164. }
  165. },
  166. canWalk: function(field) {
  167. var np = this.getNextPoint();
  168. var outOfSquare = np.x < 0 || np.y < 0 || np.x >= field.size || np.y>= field.size;
  169. if(outOfSquare) {
  170. return false;
  171. }
  172. var isBlocked = (field.square[np.x][np.y] === Fields.BLOCKED);
  173. return !isBlocked;
  174. },
  175. getNextPoint: function() {
  176. var p = {};
  177. if(this.direction === Directions.NORTH) {
  178. p.x = this.x - 1;
  179. p.y = this.y;
  180. }
  181. else if(this.direction === Directions.EAST) {
  182. p.x = this.x;
  183. p.y = this.y + 1;
  184. }
  185. else if(this.direction === Directions.SOUTH) {
  186. p.x = this.x + 1;
  187. p.y = this.y;
  188. }
  189. else if(this.direction === Directions.WEST) {
  190. p.x = this.x;
  191. p.y = this.y - 1;
  192. }
  193. return p;
  194. },
  195. getState: function() {
  196. return new State(this.x, this.y, this.direction);
  197. },
  198. discoverOptions: function(field) {
  199. var options = [Commands.TURN_LEFT, Commands.TURN_RIGHT];
  200. if(this.canWalk(field)) {
  201. options.unshift(Commands.MOVE_FORWARDS);
  202. }
  203. return options;
  204. },
  205. predictState: function(command, field) {
  206. var clone = this.clone();
  207. if(command === Commands.TURN_LEFT) {
  208. clone.turnLeft();
  209. }
  210. else if(command === Commands.TURN_RIGHT) {
  211. clone.turnRight();
  212. }
  213. else if(command === Commands.MOVE_FORWARDS) {
  214. clone.moveForward(field);
  215. }
  216. return clone.getState();
  217. },
  218. executeCommand: function(command, field) {
  219. if(command === Commands.TURN_LEFT) {
  220. this.turnLeft();
  221. }
  222. else if(command === Commands.TURN_RIGHT) {
  223. this.turnRight();
  224. }
  225. else if(command === Commands.MOVE_FORWARDS) {
  226. this.moveForward(field);
  227. }
  228. },
  229. clone: function() {
  230. return new Robot({ x: this.x, y: this.y }, this.power, this.direction, this.commandLog);
  231. }
  232. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement