Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class GameTreeNode {
- constructor(obj = {}) {
- this.parentNode = obj.parentNode || null;
- this.upNode = null;
- this.rightNode = null;
- this.downNode = null;
- this.leftNode = null;
- this.minScore = obj.parentNode ? obj.parentNode.minScore + 1 : 0;
- this.score = null;
- this.dir = obj.dir || null;
- }
- getNextNode() {
- if (!this.upNode || !this.upNode.score) {
- if (!this.upNode) {
- this.upNode = new GameTreeNode({ parentNode: this, dir: 'u' });
- }
- return this.upNode;
- }
- if (!this.rightNode || !this.rightNode.score) {
- if (!this.rightNode) {
- this.rightNode = new GameTreeNode({ parentNode: this, dir: 'r' });
- }
- return this.rightNode;
- }
- if (!this.downNode || !this.downNode.score) {
- if (!this.downNode) {
- this.downNode = new GameTreeNode({ parentNode: this, dir: 'd' });
- }
- return this.downNode;
- }
- if (!this.leftNode || !this.leftNode.score) {
- if (!this.leftNode) {
- this.leftNode = new GameTreeNode({ parentNode: this, dir: 'l' });
- }
- return this.leftNode;
- }
- return this.parentNode;
- }
- getMoveList() {
- let str = this.dir;
- let node = this;
- while (node.parentNode) {
- if (node.parentNode.dir) {
- str = `${node.parentNode.dir}${str}`;
- }
- node = node.parentNode;
- }
- return str;
- }
- }
- class Solver {
- constructor() {
- this.nodeExamining = null;
- }
- searchNextNode() {
- this.playNodeMoveOnGame(this.nodeExamining);
- if (!window.dead) {
- this.nodeExamining = this.nodeExamining.getNextNode();
- this.searchNextNode();
- }
- }
- playNodeMoveOnGame(node) {
- if (node.dir) {
- this.dispatchMove(node.dir);
- if (window.dead) {
- node.score = node.minScore;
- console.log(node.score + ' - ' + node.getMoveList()); // eslint-disable-line
- if (!this.bestNode || node.score > this.bestNode.score) {
- this.bestNode = node;
- console.log(` *** BEST: ${node.score} ***\n ${node.getMoveList()}\n`); // eslint-disable-line
- }
- setTimeout(() => this.restartPlaying(), 0)
- }
- }
- }
- dispatchMove(dir) {
- switch (dir) {
- case 'u':
- window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 38 }));
- break;
- case 'r':
- window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 39 }));
- break;
- case 'd':
- window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 40 }));
- break;
- case 'l':
- window.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 37 }));
- break;
- }
- }
- restartPlaying() {
- this.resetNodeExamining();
- if (window.ogMap) {
- window.MAP = JSON.parse(JSON.stringify(window.ogMap));
- window.dead = false;
- window.myRPG = new RPG(document.getElementById('game').getContext('2d'), window.MAP, document.getElementById('score')); // eslint-disable-line
- this.searchNextNode();
- } else {
- window.ogMap = JSON.parse(JSON.stringify(window.MAP));
- this.createCustomRpg();
- document.querySelector('body').innerHTML = `<canvas id="game" width="32" height="32" style="height: 89vh;image-rendering: pixelated;image-rendering: crisp-edges;">
- Sorry, this game doesn't work on your browser. Please update it.
- </canvas><span id="score" style="font-size: 10em;position: relative;top: -1.5em;">0</span>`;
- this.restartPlaying();
- }
- }
- resetNodeExamining() {
- if (this.nodeExamining) {
- while (this.nodeExamining.parentNode) {
- this.nodeExamining = this.nodeExamining.parentNode;
- }
- } else {
- this.nodeExamining = new GameTreeNode();
- }
- }
- // I edited the `RPG` function a bit to remove unnecessary rendering and other
- // stuff that makes it take longer to play and reset the game.
- createCustomRpg() {
- window.RPG = function (ctx, map, score) {
- var _mapMeanings = {
- " ": {
- color: "#000000"
- },
- "E": {
- color: "#af0000"
- },
- "S": {
- color: "#ff9800"
- },
- "1": {
- color: "green"
- },
- "2": {
- color: "darkgreen"
- }
- };
- var _enemyLocations = [];
- var _health = 1;
- var over = false;
- var _enemyTick = function (perferAxis) {
- switch (_turnCount % 12) {
- case 0:
- _enemyLocations.push({x: 0, y: 0});
- break;
- case 3:
- _enemyLocations.push({x: 0, y: 31});
- break;
- case 6:
- _enemyLocations.push({x: 31, y: 0});
- break;
- case 9:
- _enemyLocations.push({x: 31, y: 31});
- break;
- }
- if (!perferAxis) perferAxis = "y";
- _enemyLocations.forEach(function (enemy, index) {
- var xDistance = enemy.x - _player[_currentPlayer].X;
- var yDistance = enemy.y - _player[_currentPlayer].Y;
- if (xDistance > 0.5) xDistance = -1;
- else if (xDistance < -0.5) xDistance = 1;
- else xDistance = 0;
- if (yDistance > 0.5) yDistance = -1;
- else if (yDistance < -0.5) yDistance = 1;
- else yDistance = 0;
- if ((xDistance !== 0) && (yDistance !== 0)) {
- if ((_turnCount % 2) === 0) {
- xDistance = 0;
- } else {
- yDistance = 0;
- }
- }
- var newCoords = _putInBounds(enemy.x + xDistance, enemy.y + yDistance);
- xDistance = newCoords.x;
- yDistance = newCoords.y;
- var conflict = false;
- enemy.current = true;
- for (var enemyName in _enemyLocations) {
- if (_enemyLocations[enemyName].current) continue;
- if ((_enemyLocations[enemyName].x === xDistance) && (_enemyLocations[enemyName].y === yDistance)) {
- conflict = true;
- break;
- }
- }
- enemy.current = false;
- if (!conflict) {
- enemy.x = xDistance;
- enemy.y = yDistance;
- }
- if ((enemy.x === _player[1].X) && (enemy.y === _player[1].Y)) {
- _health--;
- dead = true;
- if (onDeath === noop) {
- over = true;
- } else {
- onDeath();
- }
- }
- _enemyLocations[index] = enemy;
- });
- };
- var _putInBounds = function (x, y) {
- if (x > 31) {
- x = 31;
- }
- if (y > 31) {
- y = 31;
- }
- if (x < 0) {
- x = 0;
- }
- if (y < 0) {
- y = 0;
- }
- return {x: x, y: y};
- };
- var _player = {};
- _player[1] = {
- X: 16,
- Y: 16
- };
- _player[2] = {
- X: 24,
- Y: 16
- };
- this.render = function () {
- window.scroll(0, 0);
- score.innerText = _turnCount;
- map.forEach(function (mapRow, y) {
- for (var x = 0; x < mapRow.length; x++) {
- let mapTile = mapRow[x];
- if (mapTile === "E") {
- mapTile = " ";
- }
- ctx.fillStyle = _mapMeanings[mapTile].color;
- ctx.fillRect(x, y, 1, 1);
- }
- });
- ctx.fillStyle = _mapMeanings["E"].color;
- _enemyLocations.forEach(function (enemy) {
- ctx.fillRect(enemy.x, enemy.y, 1, 1);
- });
- ctx.fillStyle = _mapMeanings["1"].color;
- ctx.fillRect(_player[1].X, _player[1].Y, 1, 1);
- };
- var _turnCount = 0;
- var _currentPlayer = 1;
- this.parseKeyPress = function (e) {
- if (over) return;
- var perferAxis = "y";
- switch (e.keyCode) {
- case 40: // Down arrow
- case 83: // S
- _player[_currentPlayer].Y++;
- break;
- case 38: // Up arrow
- case 87: // W
- _player[_currentPlayer].Y--;
- break;
- case 39: // Right arrow
- case 68: // D
- perferAxis = "x";
- _player[_currentPlayer].X++;
- break;
- case 37: // Left arrow
- case 65:
- perferAxis = "x";
- _player[_currentPlayer].X--;
- break;
- default:
- return;
- break;
- }
- _turnCount++;
- var newCoords = _putInBounds(_player[_currentPlayer].X, _player[_currentPlayer].Y);
- _player[_currentPlayer].X = newCoords.x;
- _player[_currentPlayer].Y = newCoords.y;
- _enemyTick(perferAxis);
- this.render();
- };
- this.render();
- };
- }
- }
- s = new Solver()
- s.restartPlaying();
- // Run this any time you want to see the best score so far:
- // console.log(s.bestNode.score)
- // Run this any time you want to see the move list for the best score so far:
- // console.log(s.bestNode.getMoveList)
- // You can do the same to look at the current node being examined:
- // console.log(s.nodeExamining)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement