Created
September 1, 2019 21:48
-
-
Save courthead/776f3f88c85b14d4c888ffe3d081aaef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.leftNode || !this.leftNode.score) { | |
if (!this.leftNode) { | |
this.leftNode = new GameTreeNode({ parentNode: this, dir: 'l' }); | |
} | |
return this.leftNode; | |
} | |
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; | |
} | |
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 Player { | |
constructor() { | |
this.nodeExamining = null; | |
this.numNodesSearched = 0; | |
} | |
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; | |
if (!this.bestNode || node.score > this.bestNode.score) { | |
this.bestNode = node; | |
console.log(`*** ${node.score}\t - ${node.getMoveList()}`); // eslint-disable-line | |
} | |
this.numNodesSearched++; | |
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(); | |
} | |
} | |
createCustomRpg() { | |
window.RPG = function (ctx, map, score) { | |
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) { | |
// Ignore ourself | |
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 | |
}; | |
var _turnCount = 0; | |
var _currentPlayer = 1; | |
this.parseKeyPress = function (e) { | |
if (over) return; | |
var perferAxis = "y"; | |
switch (e.keyCode) { | |
case 40: // Down arrow | |
_player[_currentPlayer].Y++; | |
break; | |
case 38: // Up arrow | |
_player[_currentPlayer].Y--; | |
break; | |
case 39: // Right arrow | |
perferAxis = "x"; | |
_player[_currentPlayer].X++; | |
break; | |
case 37: // Left arrow | |
perferAxis = "x"; | |
_player[_currentPlayer].X--; | |
break; | |
default: | |
return; | |
} | |
_turnCount++; | |
var newCoords = _putInBounds(_player[_currentPlayer].X, _player[_currentPlayer].Y); | |
_player[_currentPlayer].X = newCoords.x; | |
_player[_currentPlayer].Y = newCoords.y; | |
_enemyTick(perferAxis); | |
}; | |
}; | |
} | |
} | |
p = new Player() | |
p.restartPlaying(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment