Advertisement
Guest User

Untitled

a guest
Sep 15th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.78 KB | None | 0 0
  1. class GameTreeNode {
  2. constructor(obj = {}) {
  3. this.parentNode = obj.parentNode || null;
  4.  
  5. this.upNode = null;
  6. this.rightNode = null;
  7. this.downNode = null;
  8. this.leftNode = null;
  9.  
  10. this.minScore = obj.parentNode ? obj.parentNode.minScore + 1 : 0;
  11. this.score = null;
  12.  
  13. this.dir = obj.dir || null;
  14. }
  15.  
  16. getNextNode() {
  17. if (!this.upNode || !this.upNode.score) {
  18. if (!this.upNode) {
  19. this.upNode = new GameTreeNode({ parentNode: this, dir: 'u' });
  20. }
  21.  
  22. return this.upNode;
  23. }
  24.  
  25. if (!this.rightNode || !this.rightNode.score) {
  26. if (!this.rightNode) {
  27. this.rightNode = new GameTreeNode({ parentNode: this, dir: 'r' });
  28. }
  29.  
  30. return this.rightNode;
  31. }
  32.  
  33. if (!this.downNode || !this.downNode.score) {
  34. if (!this.downNode) {
  35. this.downNode = new GameTreeNode({ parentNode: this, dir: 'd' });
  36. }
  37.  
  38. return this.downNode;
  39. }
  40.  
  41. if (!this.leftNode || !this.leftNode.score) {
  42. if (!this.leftNode) {
  43. this.leftNode = new GameTreeNode({ parentNode: this, dir: 'l' });
  44. }
  45.  
  46. return this.leftNode;
  47. }
  48.  
  49. return this.parentNode;
  50. }
  51.  
  52. getMoveList() {
  53. let str = this.dir;
  54. let node = this;
  55.  
  56. while (node.parentNode) {
  57. if (node.parentNode.dir) {
  58. str = `${node.parentNode.dir}${str}`;
  59. }
  60.  
  61. node = node.parentNode;
  62. }
  63.  
  64. return str;
  65. }
  66. }
  67.  
  68. class Solver {
  69. constructor() {
  70. this.nodeExamining = null;
  71. }
  72.  
  73. searchNextNode() {
  74. this.playNodeMoveOnGame(this.nodeExamining);
  75.  
  76. if (!window.dead) {
  77. this.nodeExamining = this.nodeExamining.getNextNode();
  78.  
  79. this.searchNextNode();
  80. }
  81. }
  82.  
  83. playNodeMoveOnGame(node) {
  84. if (node.dir) {
  85. this.dispatchMove(node.dir);
  86. if (window.dead) {
  87. node.score = node.minScore;
  88. console.log(node.score + ' - ' + node.getMoveList()); // eslint-disable-line
  89.  
  90. if (!this.bestNode || node.score > this.bestNode.score) {
  91. this.bestNode = node;
  92. console.log(` *** BEST: ${node.score} ***\n ${node.getMoveList()}\n`); // eslint-disable-line
  93. }
  94.  
  95. setTimeout(() => this.restartPlaying(), 0)
  96. }
  97. }
  98. }
  99.  
  100. dispatchMove(dir) {
  101. switch (dir) {
  102. case 'u':
  103. window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 38 }));
  104. break;
  105. case 'r':
  106. window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 39 }));
  107. break;
  108. case 'd':
  109. window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 40 }));
  110. break;
  111. case 'l':
  112. window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 37 }));
  113. break;
  114. }
  115. }
  116.  
  117. restartPlaying() {
  118. this.resetNodeExamining();
  119.  
  120. if (window.ogMap) {
  121. window.MAP = JSON.parse(JSON.stringify(window.ogMap));
  122. window.dead = false;
  123. window.myRPG = new RPG(document.getElementById('game').getContext('2d'), window.MAP, document.getElementById('score')); // eslint-disable-line
  124. this.searchNextNode();
  125. } else {
  126. window.ogMap = JSON.parse(JSON.stringify(window.MAP));
  127. this.createCustomRpg();
  128. document.querySelector('body').innerHTML = `<canvas id="game" width="32" height="32" style="height: 89vh;image-rendering: pixelated;image-rendering: crisp-edges;">
  129. Sorry, this game doesn't work on your browser. Please update it.
  130. </canvas><span id="score" style="font-size: 10em;position: relative;top: -1.5em;">0</span>`;
  131. this.restartPlaying();
  132. }
  133. }
  134.  
  135. resetNodeExamining() {
  136. if (this.nodeExamining) {
  137. while (this.nodeExamining.parentNode) {
  138. this.nodeExamining = this.nodeExamining.parentNode;
  139. }
  140. } else {
  141. this.nodeExamining = new GameTreeNode();
  142. }
  143. }
  144.  
  145. // I edited the `RPG` function a bit to remove unnecessary rendering and other
  146. // stuff that makes it take longer to play and reset the game.
  147. createCustomRpg() {
  148. window.RPG = function (ctx, map, score) {
  149. var _mapMeanings = {
  150. " ": {
  151. color: "#000000"
  152. },
  153. "E": {
  154. color: "#af0000"
  155. },
  156. "S": {
  157. color: "#ff9800"
  158. },
  159. "1": {
  160. color: "green"
  161. },
  162. "2": {
  163. color: "darkgreen"
  164. }
  165. };
  166. var _enemyLocations = [];
  167. var _health = 1;
  168. var over = false;
  169. var _enemyTick = function (perferAxis) {
  170. switch (_turnCount % 12) {
  171. case 0:
  172. _enemyLocations.push({x: 0, y: 0});
  173. break;
  174. case 3:
  175. _enemyLocations.push({x: 0, y: 31});
  176. break;
  177. case 6:
  178. _enemyLocations.push({x: 31, y: 0});
  179. break;
  180. case 9:
  181. _enemyLocations.push({x: 31, y: 31});
  182. break;
  183. }
  184. if (!perferAxis) perferAxis = "y";
  185. _enemyLocations.forEach(function (enemy, index) {
  186.  
  187. var xDistance = enemy.x - _player[_currentPlayer].X;
  188. var yDistance = enemy.y - _player[_currentPlayer].Y;
  189.  
  190. if (xDistance > 0.5) xDistance = -1;
  191. else if (xDistance < -0.5) xDistance = 1;
  192. else xDistance = 0;
  193.  
  194. if (yDistance > 0.5) yDistance = -1;
  195. else if (yDistance < -0.5) yDistance = 1;
  196. else yDistance = 0;
  197.  
  198. if ((xDistance !== 0) && (yDistance !== 0)) {
  199. if ((_turnCount % 2) === 0) {
  200. xDistance = 0;
  201. } else {
  202. yDistance = 0;
  203. }
  204. }
  205.  
  206. var newCoords = _putInBounds(enemy.x + xDistance, enemy.y + yDistance);
  207. xDistance = newCoords.x;
  208. yDistance = newCoords.y;
  209.  
  210. var conflict = false;
  211. enemy.current = true;
  212. for (var enemyName in _enemyLocations) {
  213. if (_enemyLocations[enemyName].current) continue;
  214. if ((_enemyLocations[enemyName].x === xDistance) && (_enemyLocations[enemyName].y === yDistance)) {
  215. conflict = true;
  216. break;
  217. }
  218. }
  219. enemy.current = false;
  220.  
  221. if (!conflict) {
  222. enemy.x = xDistance;
  223. enemy.y = yDistance;
  224. }
  225.  
  226. if ((enemy.x === _player[1].X) && (enemy.y === _player[1].Y)) {
  227. _health--;
  228. dead = true;
  229. if (onDeath === noop) {
  230. over = true;
  231. } else {
  232. onDeath();
  233. }
  234. }
  235.  
  236. _enemyLocations[index] = enemy;
  237. });
  238. };
  239. var _putInBounds = function (x, y) {
  240. if (x > 31) {
  241. x = 31;
  242. }
  243. if (y > 31) {
  244. y = 31;
  245. }
  246. if (x < 0) {
  247. x = 0;
  248. }
  249. if (y < 0) {
  250. y = 0;
  251. }
  252. return {x: x, y: y};
  253. };
  254. var _player = {};
  255. _player[1] = {
  256. X: 16,
  257. Y: 16
  258. };
  259. _player[2] = {
  260. X: 24,
  261. Y: 16
  262. };
  263. this.render = function () {
  264. window.scroll(0, 0);
  265.  
  266. score.innerText = _turnCount;
  267.  
  268. map.forEach(function (mapRow, y) {
  269. for (var x = 0; x < mapRow.length; x++) {
  270. let mapTile = mapRow[x];
  271. if (mapTile === "E") {
  272. mapTile = " ";
  273. }
  274. ctx.fillStyle = _mapMeanings[mapTile].color;
  275. ctx.fillRect(x, y, 1, 1);
  276. }
  277. });
  278.  
  279. ctx.fillStyle = _mapMeanings["E"].color;
  280. _enemyLocations.forEach(function (enemy) {
  281. ctx.fillRect(enemy.x, enemy.y, 1, 1);
  282. });
  283.  
  284. ctx.fillStyle = _mapMeanings["1"].color;
  285. ctx.fillRect(_player[1].X, _player[1].Y, 1, 1);
  286. };
  287. var _turnCount = 0;
  288. var _currentPlayer = 1;
  289. this.parseKeyPress = function (e) {
  290. if (over) return;
  291. var perferAxis = "y";
  292. switch (e.keyCode) {
  293. case 40: // Down arrow
  294. case 83: // S
  295. _player[_currentPlayer].Y++;
  296. break;
  297. case 38: // Up arrow
  298. case 87: // W
  299. _player[_currentPlayer].Y--;
  300. break;
  301. case 39: // Right arrow
  302. case 68: // D
  303. perferAxis = "x";
  304. _player[_currentPlayer].X++;
  305. break;
  306. case 37: // Left arrow
  307. case 65:
  308. perferAxis = "x";
  309. _player[_currentPlayer].X--;
  310. break;
  311. default:
  312. return;
  313. break;
  314. }
  315. _turnCount++;
  316. var newCoords = _putInBounds(_player[_currentPlayer].X, _player[_currentPlayer].Y);
  317. _player[_currentPlayer].X = newCoords.x;
  318. _player[_currentPlayer].Y = newCoords.y;
  319. _enemyTick(perferAxis);
  320. this.render();
  321. };
  322. this.render();
  323. };
  324. }
  325. }
  326.  
  327. s = new Solver()
  328. s.restartPlaying();
  329.  
  330. // Run this any time you want to see the best score so far:
  331. // console.log(s.bestNode.score)
  332.  
  333. // Run this any time you want to see the move list for the best score so far:
  334. // console.log(s.bestNode.getMoveList)
  335.  
  336. // You can do the same to look at the current node being examined:
  337. // console.log(s.nodeExamining)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement