This commit is contained in:
Timothy Warren 2016-08-03 20:28:52 -04:00
parent 93a8a455e0
commit 3fccf4adb5
6 changed files with 428 additions and 0 deletions

View File

@ -0,0 +1 @@
eyJfdG93ZXJQYXRoIjoiQzovVXNlcnMvVGltL0FwcERhdGEvUm9hbWluZy9ucG0vbm9kZV9tb2R1bGVzL3dhcnJpb3Jqcy90b3dlcnMvaW50ZXJtZWRpYXRlIiwiX3dhcnJpb3JOYW1lIjoiVGltIiwiX3Njb3JlIjo5MiwiX2VwaWMiOmZhbHNlLCJfZXBpY1Njb3JlIjowLCJfY3VycmVudEVwaWNTY29yZSI6MCwiX2N1cnJlbnRFcGljR3JhZGVzIjp7fSwiX2F2ZXJhZ2VHcmFkZSI6bnVsbCwiX2FiaWxpdGllcyI6W3sibmFtZSI6ImRpcmVjdGlvbk9mU3RhaXJzIiwiYXJncyI6W119LHsibmFtZSI6IndhbGsiLCJhcmdzIjpbXX0seyJuYW1lIjoiZmVlbCIsImFyZ3MiOltdfSx7Im5hbWUiOiJhdHRhY2siLCJhcmdzIjpbXX0seyJuYW1lIjoiaGVhbHRoIiwiYXJncyI6W119LHsibmFtZSI6InJlc3QiLCJhcmdzIjpbXX1dLCJfbGV2ZWxOdW1iZXIiOjMsIl9sYXN0TGV2ZWxOdW1iZXIiOm51bGwsIl9wbGF5ZXJQYXRoIjoid2FycmlvcmpzL3RpbS1pbnRlcm1lZGlhdGUifQ==

View File

@ -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;
}
}

View File

@ -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.

View File

@ -0,0 +1 @@
eyJfdG93ZXJQYXRoIjoiQzovVXNlcnMvVGltL0FwcERhdGEvUm9hbWluZy9ucG0vbm9kZV9tb2R1bGVzL3dhcnJpb3Jqcy90b3dlcnMvYmVnaW5uZXIiLCJfd2Fycmlvck5hbWUiOiJUb20iLCJfc2NvcmUiOjU0NywiX2VwaWMiOnRydWUsIl9lcGljU2NvcmUiOjU5MywiX2N1cnJlbnRFcGljU2NvcmUiOjU5MywiX2N1cnJlbnRFcGljR3JhZGVzIjp7IjEiOjEsIjIiOjAuOTYxNTM4NDYxNTM4NDYxNiwiMyI6MSwiNCI6MC45NTU1NTU1NTU1NTU1NTU2LCI1IjowLjkxMDU2OTEwNTY5MTA1NjksIjYiOjAuOTIzODA5NTIzODA5NTIzOSwiNyI6MC45NiwiOCI6MSwiOSI6MC45OH0sIl9hdmVyYWdlR3JhZGUiOjAuOTY1NzE5MTgyOTU0OTU1MywiX2FiaWxpdGllcyI6W3sibmFtZSI6IndhbGsiLCJhcmdzIjpbXX0seyJuYW1lIjoiYXR0YWNrIiwiYXJncyI6W119LHsibmFtZSI6ImZlZWwiLCJhcmdzIjpbXX0seyJuYW1lIjoiaGVhbHRoIiwiYXJncyI6W119LHsibmFtZSI6InJlc3QiLCJhcmdzIjpbXX0seyJuYW1lIjoicmVzY3VlIiwiYXJncyI6W119LHsibmFtZSI6InBpdm90IiwiYXJncyI6W119LHsibmFtZSI6Imxvb2siLCJhcmdzIjpbXX0seyJuYW1lIjoic2hvb3QiLCJhcmdzIjpbXX1dLCJfbGV2ZWxOdW1iZXIiOjAsIl9sYXN0TGV2ZWxOdW1iZXIiOjksIl9wbGF5ZXJQYXRoIjoid2FycmlvcmpzL3RvbS1iZWdpbm5lciJ9

View File

@ -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;
}
}

View File

@ -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.