Add node
This commit is contained in:
parent
93a8a455e0
commit
3fccf4adb5
1
nodeJS/warriorjs/tim-intermediate/.profile
Normal file
1
nodeJS/warriorjs/tim-intermediate/.profile
Normal file
|
@ -0,0 +1 @@
|
|||
eyJfdG93ZXJQYXRoIjoiQzovVXNlcnMvVGltL0FwcERhdGEvUm9hbWluZy9ucG0vbm9kZV9tb2R1bGVzL3dhcnJpb3Jqcy90b3dlcnMvaW50ZXJtZWRpYXRlIiwiX3dhcnJpb3JOYW1lIjoiVGltIiwiX3Njb3JlIjo5MiwiX2VwaWMiOmZhbHNlLCJfZXBpY1Njb3JlIjowLCJfY3VycmVudEVwaWNTY29yZSI6MCwiX2N1cnJlbnRFcGljR3JhZGVzIjp7fSwiX2F2ZXJhZ2VHcmFkZSI6bnVsbCwiX2FiaWxpdGllcyI6W3sibmFtZSI6ImRpcmVjdGlvbk9mU3RhaXJzIiwiYXJncyI6W119LHsibmFtZSI6IndhbGsiLCJhcmdzIjpbXX0seyJuYW1lIjoiZmVlbCIsImFyZ3MiOltdfSx7Im5hbWUiOiJhdHRhY2siLCJhcmdzIjpbXX0seyJuYW1lIjoiaGVhbHRoIiwiYXJncyI6W119LHsibmFtZSI6InJlc3QiLCJhcmdzIjpbXX1dLCJfbGV2ZWxOdW1iZXIiOjMsIl9sYXN0TGV2ZWxOdW1iZXIiOm51bGwsIl9wbGF5ZXJQYXRoIjoid2FycmlvcmpzL3RpbS1pbnRlcm1lZGlhdGUifQ==
|
165
nodeJS/warriorjs/tim-intermediate/Player.js
Normal file
165
nodeJS/warriorjs/tim-intermediate/Player.js
Normal 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;
|
||||
}
|
||||
}
|
39
nodeJS/warriorjs/tim-intermediate/README
Normal file
39
nodeJS/warriorjs/tim-intermediate/README
Normal 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.
|
1
nodeJS/warriorjs/tom-beginner/.profile
Normal file
1
nodeJS/warriorjs/tom-beginner/.profile
Normal file
|
@ -0,0 +1 @@
|
|||
eyJfdG93ZXJQYXRoIjoiQzovVXNlcnMvVGltL0FwcERhdGEvUm9hbWluZy9ucG0vbm9kZV9tb2R1bGVzL3dhcnJpb3Jqcy90b3dlcnMvYmVnaW5uZXIiLCJfd2Fycmlvck5hbWUiOiJUb20iLCJfc2NvcmUiOjU0NywiX2VwaWMiOnRydWUsIl9lcGljU2NvcmUiOjU5MywiX2N1cnJlbnRFcGljU2NvcmUiOjU5MywiX2N1cnJlbnRFcGljR3JhZGVzIjp7IjEiOjEsIjIiOjAuOTYxNTM4NDYxNTM4NDYxNiwiMyI6MSwiNCI6MC45NTU1NTU1NTU1NTU1NTU2LCI1IjowLjkxMDU2OTEwNTY5MTA1NjksIjYiOjAuOTIzODA5NTIzODA5NTIzOSwiNyI6MC45NiwiOCI6MSwiOSI6MC45OH0sIl9hdmVyYWdlR3JhZGUiOjAuOTY1NzE5MTgyOTU0OTU1MywiX2FiaWxpdGllcyI6W3sibmFtZSI6IndhbGsiLCJhcmdzIjpbXX0seyJuYW1lIjoiYXR0YWNrIiwiYXJncyI6W119LHsibmFtZSI6ImZlZWwiLCJhcmdzIjpbXX0seyJuYW1lIjoiaGVhbHRoIiwiYXJncyI6W119LHsibmFtZSI6InJlc3QiLCJhcmdzIjpbXX0seyJuYW1lIjoicmVzY3VlIiwiYXJncyI6W119LHsibmFtZSI6InBpdm90IiwiYXJncyI6W119LHsibmFtZSI6Imxvb2siLCJhcmdzIjpbXX0seyJuYW1lIjoic2hvb3QiLCJhcmdzIjpbXX1dLCJfbGV2ZWxOdW1iZXIiOjAsIl9sYXN0TGV2ZWxOdW1iZXIiOjksIl9wbGF5ZXJQYXRoIjoid2FycmlvcmpzL3RvbS1iZWdpbm5lciJ9
|
181
nodeJS/warriorjs/tom-beginner/Player.js
Normal file
181
nodeJS/warriorjs/tom-beginner/Player.js
Normal 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;
|
||||
}
|
||||
}
|
41
nodeJS/warriorjs/tom-beginner/README
Normal file
41
nodeJS/warriorjs/tom-beginner/README
Normal 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.
|
Loading…
Reference in New Issue
Block a user