From 3fccf4adb508bfdaedcf26a535f1f1960b7c6677 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Wed, 3 Aug 2016 20:28:52 -0400 Subject: [PATCH] Add node --- nodeJS/warriorjs/tim-intermediate/.profile | 1 + nodeJS/warriorjs/tim-intermediate/Player.js | 165 ++++++++++++++++++ nodeJS/warriorjs/tim-intermediate/README | 39 +++++ nodeJS/warriorjs/tom-beginner/.profile | 1 + nodeJS/warriorjs/tom-beginner/Player.js | 181 ++++++++++++++++++++ nodeJS/warriorjs/tom-beginner/README | 41 +++++ 6 files changed, 428 insertions(+) create mode 100644 nodeJS/warriorjs/tim-intermediate/.profile create mode 100644 nodeJS/warriorjs/tim-intermediate/Player.js create mode 100644 nodeJS/warriorjs/tim-intermediate/README create mode 100644 nodeJS/warriorjs/tom-beginner/.profile create mode 100644 nodeJS/warriorjs/tom-beginner/Player.js create mode 100644 nodeJS/warriorjs/tom-beginner/README diff --git a/nodeJS/warriorjs/tim-intermediate/.profile b/nodeJS/warriorjs/tim-intermediate/.profile new file mode 100644 index 0000000..ba8a539 --- /dev/null +++ b/nodeJS/warriorjs/tim-intermediate/.profile @@ -0,0 +1 @@ +eyJfdG93ZXJQYXRoIjoiQzovVXNlcnMvVGltL0FwcERhdGEvUm9hbWluZy9ucG0vbm9kZV9tb2R1bGVzL3dhcnJpb3Jqcy90b3dlcnMvaW50ZXJtZWRpYXRlIiwiX3dhcnJpb3JOYW1lIjoiVGltIiwiX3Njb3JlIjo5MiwiX2VwaWMiOmZhbHNlLCJfZXBpY1Njb3JlIjowLCJfY3VycmVudEVwaWNTY29yZSI6MCwiX2N1cnJlbnRFcGljR3JhZGVzIjp7fSwiX2F2ZXJhZ2VHcmFkZSI6bnVsbCwiX2FiaWxpdGllcyI6W3sibmFtZSI6ImRpcmVjdGlvbk9mU3RhaXJzIiwiYXJncyI6W119LHsibmFtZSI6IndhbGsiLCJhcmdzIjpbXX0seyJuYW1lIjoiZmVlbCIsImFyZ3MiOltdfSx7Im5hbWUiOiJhdHRhY2siLCJhcmdzIjpbXX0seyJuYW1lIjoiaGVhbHRoIiwiYXJncyI6W119LHsibmFtZSI6InJlc3QiLCJhcmdzIjpbXX1dLCJfbGV2ZWxOdW1iZXIiOjMsIl9sYXN0TGV2ZWxOdW1iZXIiOm51bGwsIl9wbGF5ZXJQYXRoIjoid2FycmlvcmpzL3RpbS1pbnRlcm1lZGlhdGUifQ== \ No newline at end of file diff --git a/nodeJS/warriorjs/tim-intermediate/Player.js b/nodeJS/warriorjs/tim-intermediate/Player.js new file mode 100644 index 0000000..f0f75cc --- /dev/null +++ b/nodeJS/warriorjs/tim-intermediate/Player.js @@ -0,0 +1,165 @@ +const reverseMap = { + forward: 'backward', + backward: 'forward', + left: 'right', + right: 'left' +}; + +/** + * Class determining player actions for warriorjs 'game' + */ +class Player { + constructor() { + this.warrior = null; + this.direction = 'forward'; + + this.status = { + _health: 20, + health: 20, + isHealing: false, + damage: false + }; + + this.adjacent = { + forward: null, + backward: null, + left: null, + right: null + }; + } + /** + * Collect information about the world for the Turn + */ + sense() { + this.status.health = this.warrior.health(); // Health of current turn + this.status.damage = (this.status._health > this.status.health); + + this.direction = this.warrior.directionOfStairs(); + + this.adjacent = { + forward: this.warrior.feel('forward'), + backward: this.warrior.feel('backward'), + left: this.warrior.feel('left'), + right: this.warrior.feel('right') + }; + } + /** + * Logic for resting to gain health + */ + heal() { + if (this.status.isHealing === false) { + this.status.isHealing = true; + } + + this.warrior.rest(); + + // Stop healing when at penultimate heath level + // or if taking damage + if (this.status.health >= 18 || this.status.damage) { + this.status.isHealing = false; + } + } + isNothingAdjacent() { + let allClear = true; + + for (const dir in this.adjacent) { + if ( ! (this.adjacent[dir].isEmpty() || this.adjacent[dir].isWall())) { + return false; + } + } + + return allClear; + } + /** + * Does an adjacent enemy exist? + */ + isEnemyInRange() { + for (const dir in this.adjacent) { + if (this.adjacent[dir].isEnemy()) { + return true; + } + } + + return false; + } + /** + * Determine if there are multiple adjacent enemies + */ + areMultipleEnemiesAdjacent() { + let numEnemies = 0; + + for(const dir in this.adjacent) { + if (this.adjacent[dir].isEnemy() { + numEnemies++; + } + } + + return (numEnemies > 1); + } + /** + * Return the direction of the first ajacent enemy found + * + * @return {string | boolean} + */ + findAdjacentEnemy() { + let enemy = false; + + for (const dir in this.adjacent) { + if (this.adjacent[dir].isEnemy()) { + return dir; + } + } + + return false; + } + /** + * Determine what to do based on what you've found with the senses + * + * @param direction - The direction to go for the next turn + */ + next(direction) { + switch(true) { + // There are multiple adjacent enemies + case this.areMultipleEnemiesAdjacent(): + this.warrior.bind(this.findAdjacentEnemy()); + break; + + // There's an adjacent enemy + case this.isEnemyInRange(): + this.warrior.attack(this.findAdjacentEnemy()); + break; + + // Nothing directly adjacent + case this.isNothingAdjacent(): + // Check health (From 0 to 20) + if ( ! this.status.damage && (this.status.health <= 16 || this.status.isHealing === true)) { + this.heal(); + } else if (this.status.damage && this.status.health <= 12) { + // Low health and taking damage + // Retreat to be able to heal + this.warrior.walk(reverseMap[direction]); + } else { + this.warrior.walk(direction); + } + break; + } + } + /** + * Callback for each Turn + * + * @param warrior - The player object + */ + playTurn(warrior) { + // Save the warrior object for other methods + this.warrior = warrior; + + // Examine the world + this.sense(); + + // Figure out what to do with the next space + this.next(this.direction); + + // Save current health + this.status._health = this.status.health; + } +} diff --git a/nodeJS/warriorjs/tim-intermediate/README b/nodeJS/warriorjs/tim-intermediate/README new file mode 100644 index 0000000..047780f --- /dev/null +++ b/nodeJS/warriorjs/tim-intermediate/README @@ -0,0 +1,39 @@ +Level 3 + +You feel slime on all sides, you're surrounded! + +Tip: Call `warrior.bind(direction)` to bind an enemy to keep him from attacking. Bound enemies look like captives. + + +╔═══╗ +║>s ║ +║s@s║ +║ C ║ +╚═══╝ + + > = stairs + @ = Tim + C = captive + s = sludge + + +Warrior abilities: + + warrior.directionOfStairs() + + warrior.walk() + + warrior.feel() + + warrior.attack() + + warrior.health() + + warrior.rest() + + warrior.bind() (NEW!) + + warrior.rescue() (NEW!) + + +When you're done editing Player.js, run the warriorjs command again. diff --git a/nodeJS/warriorjs/tom-beginner/.profile b/nodeJS/warriorjs/tom-beginner/.profile new file mode 100644 index 0000000..1e0e0c7 --- /dev/null +++ b/nodeJS/warriorjs/tom-beginner/.profile @@ -0,0 +1 @@ +eyJfdG93ZXJQYXRoIjoiQzovVXNlcnMvVGltL0FwcERhdGEvUm9hbWluZy9ucG0vbm9kZV9tb2R1bGVzL3dhcnJpb3Jqcy90b3dlcnMvYmVnaW5uZXIiLCJfd2Fycmlvck5hbWUiOiJUb20iLCJfc2NvcmUiOjU0NywiX2VwaWMiOnRydWUsIl9lcGljU2NvcmUiOjU5MywiX2N1cnJlbnRFcGljU2NvcmUiOjU5MywiX2N1cnJlbnRFcGljR3JhZGVzIjp7IjEiOjEsIjIiOjAuOTYxNTM4NDYxNTM4NDYxNiwiMyI6MSwiNCI6MC45NTU1NTU1NTU1NTU1NTU2LCI1IjowLjkxMDU2OTEwNTY5MTA1NjksIjYiOjAuOTIzODA5NTIzODA5NTIzOSwiNyI6MC45NiwiOCI6MSwiOSI6MC45OH0sIl9hdmVyYWdlR3JhZGUiOjAuOTY1NzE5MTgyOTU0OTU1MywiX2FiaWxpdGllcyI6W3sibmFtZSI6IndhbGsiLCJhcmdzIjpbXX0seyJuYW1lIjoiYXR0YWNrIiwiYXJncyI6W119LHsibmFtZSI6ImZlZWwiLCJhcmdzIjpbXX0seyJuYW1lIjoiaGVhbHRoIiwiYXJncyI6W119LHsibmFtZSI6InJlc3QiLCJhcmdzIjpbXX0seyJuYW1lIjoicmVzY3VlIiwiYXJncyI6W119LHsibmFtZSI6InBpdm90IiwiYXJncyI6W119LHsibmFtZSI6Imxvb2siLCJhcmdzIjpbXX0seyJuYW1lIjoic2hvb3QiLCJhcmdzIjpbXX1dLCJfbGV2ZWxOdW1iZXIiOjAsIl9sYXN0TGV2ZWxOdW1iZXIiOjksIl9wbGF5ZXJQYXRoIjoid2FycmlvcmpzL3RvbS1iZWdpbm5lciJ9 \ No newline at end of file diff --git a/nodeJS/warriorjs/tom-beginner/Player.js b/nodeJS/warriorjs/tom-beginner/Player.js new file mode 100644 index 0000000..f079743 --- /dev/null +++ b/nodeJS/warriorjs/tom-beginner/Player.js @@ -0,0 +1,181 @@ +const reverseMap = { + forward: 'backward', + backward: 'forward', + left: 'right', + right: 'left' +}; + +/** + * Class determining player actions for warriorjs 'game' + */ +class Player { + constructor() { + this.warrior = null; + this.status = { + _health: 20, + health: 20, + isHealing: false, + damage: false, + direction: 'forward', + space: null + }; + } + /** + * Collect information about the world for the Turn + */ + sense() { + this.status.health = this.warrior.health(); // Health of current turn + this.status.damage = (this.status._health > this.status.health); + this.status.space = this.warrior.feel(this.status.direction); + } + /** + * Determine if the adjacent spaces are empty + * + * @param {String} direction + * @return {Space | boolean} + */ + isNotEmptyInSight(direction) { + return this.warrior.look(direction).find(space => ! space.isEmpty()); + } + /** + * See if there is an enemy within sight + * + * @param {String} direction + * @return {boolean} + */ + isEnemyInSight(direction) { + const space = this.isNotEmptyInSight(direction); + return space && space.isEnemy(); + } + /** + * See if the wall is in sight + * + * @param {String} direction + * @return {boolean} + */ + isWallInSight(direction) { + const space = this.isNotEmptyInSight(direction); + return space && space.isWall(); + } + /** + * See if a captive is in sight + * + * @param {String} direction + * @return {boolean} + */ + isCaptiveInSight(direction) { + const space = this.isNotEmptyInSight(direction); + return space && space.isCaptive(); + } + /** + * Check if you can see the stairs + * + * @param {String} direction + * @return {boolean} + */ + areStairsInSight(direction) { + const space = this.warrior.look(direction).find(space => space.isStairs()); + return Boolean(space); + } + /** + * Logic for resting to gain health + */ + heal() { + if (this.status.isHealing === false) { + this.status.isHealing = true; + } + + this.warrior.rest(); + + // Stop healing when at penultimate heath level + // or if taking damage + if (this.status.health >= 18 || this.status.damage) { + this.status.isHealing = false; + } + } + /** + * Reverse direction and pivot + */ + turnAround() { + const newDirection = reverseMap[this.status.direction]; + this.status.direction = newDirection; + + this.warrior.pivot(newDirection); + } + /** + * Determine what to do based on what you've found with the senses + * + * @param direction - The direction to go for the next turn + */ + next(direction) { + switch(true) { + case this.status.space.isWall(): + this.turnAround(); + break; + + case this.status.space.isEnemy(): + this.warrior.attack(direction); + break; + + case this.status.space.isCaptive(): + this.warrior.rescue(direction); + break; + + // Empty space + default: + // Check health (From 0 to 20) + if ( ! this.status.damage && (this.status.health <= 16 || this.status.isHealing === true)) { + this.heal(); + } else if (this.status.damage && this.status.health <= 12) { + // Low health and taking damage + // Retreat to be able to heal + this.warrior.walk(reverseMap[this.status.direction]); + } else { + // Determine what to do based on what you can see + switch(true) { + // Take care of the enemy behind you + case this.isEnemyInSight(reverseMap[direction]): + this.warrior.shoot(reverseMap[direction]); + break; + + // Take care of the enemy in front of you + case this.isEnemyInSight(direction): + this.warrior.shoot(direction); + break; + + // After taking care of enemies, look behind + // to see if you should turn around because of a + // wall, or if you need to rescue some captives + case ( ! this.areStairsInSight(direction)) && this.isWallInSight(direction): + case this.isCaptiveInSight(reverseMap[direction]): + this.turnAround(); + break; + + // On to the next space! + default: + this.warrior.walk(direction); + break; + } + } + break; + } + } + /** + * Callback for each Turn + * + * @param warrior - The player object + */ + playTurn(warrior) { + // Save the warrior object for other methods + this.warrior = warrior; + + // Examine the world + this.sense(); + + // Figure out what to do with the next space + this.next(this.status.direction); + + // Save current health + this.status._health = this.status.health; + } +} diff --git a/nodeJS/warriorjs/tom-beginner/README b/nodeJS/warriorjs/tom-beginner/README new file mode 100644 index 0000000..416d80d --- /dev/null +++ b/nodeJS/warriorjs/tom-beginner/README @@ -0,0 +1,41 @@ +Level 9 + +Time to hone your skills and apply all of the abilities that you have learned. + +Tip: Watch your back. + + +╔═══════════╗ +║>Ca @ S wC║ +╚═══════════╝ + + > = stairs + @ = Tom + a = archer + S = thickSludge + w = wizard + C = captive + + +Warrior abilities: + + warrior.walk() + + warrior.attack() + + warrior.feel() + + warrior.health() + + warrior.rest() + + warrior.rescue() + + warrior.pivot() + + warrior.look() + + warrior.shoot() + + +When you're done editing Player.js, run the warriorjs command again.