warriorjs-ja
Version:
Game written in JavaScript for learning JavaScript and artificial intelligence
601 lines (493 loc) • 19.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _glob = require('glob');
var _glob2 = _interopRequireDefault(_glob);
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _warriorjsEngine = require('warriorjs-engine');
var _warriorjsEngine2 = _interopRequireDefault(_warriorjsEngine);
var _UI = require('./UI');
var _UI2 = _interopRequireDefault(_UI);
var _Config = require('./Config');
var _Config2 = _interopRequireDefault(_Config);
var _Profile = require('./Profile');
var _Profile2 = _interopRequireDefault(_Profile);
var _PlayerGenerator = require('./PlayerGenerator');
var _PlayerGenerator2 = _interopRequireDefault(_PlayerGenerator);
var _Tower = require('./Tower');
var _Tower2 = _interopRequireDefault(_Tower);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
_bluebird2.default.promisifyAll(_fsExtra2.default);
_bluebird2.default.promisifyAll(_glob2.default);
var Game = function () {
function Game() {
_classCallCheck(this, Game);
this._profilePath = _path2.default.join(_Config2.default.pathPrefix, '.profile');
this._gameDirectoryPath = _path2.default.join(_Config2.default.pathPrefix, 'warriorjs');
}
_createClass(Game, [{
key: 'start',
value: function start() {
var _this = this;
_UI2.default.printLine('Welcome to WarriorJS');
this.loadProfile().then(function (profile) {
_this._profile = profile;
if (_this._profile.isEpic()) {
return _this.hasLevelAfterEpic().then(function (hasLevel) {
if (hasLevel) {
return _this.goToNormalMode();
}
return _this.playEpicMode();
});
}
return _this.playNormalMode();
}).catch(function (err) {
return _UI2.default.printLine(err.message);
});
}
/*
* Play
*/
}, {
key: 'playEpicMode',
value: function playEpicMode() {
var _this2 = this;
if (_Config2.default.delay) {
_Config2.default.delay = _Config2.default.delay / 2;
}
this._profile.currentEpicScore = 0;
this._profile.currentEpicGrades = {};
if (_Config2.default.practiceLevel) {
return this.levelExists(_Config2.default.practiceLevel).then(function (exists) {
if (exists) {
_this2._profile.levelNumber = _Config2.default.practiceLevel;
return _this2.playCurrentLevel();
}
throw new Error('Unable to practice non-existent level, try another.');
});
}
var playLoop = function playLoop() {
return _this2.playCurrentLevel().then(function (playing) {
if (!playing) {
return _bluebird2.default.resolve();
}
_this2._profile.levelNumber += 1;
return playLoop();
});
};
this._profile.levelNumber += 1;
return playLoop().then(function () {
return _this2._profile.save();
});
}
}, {
key: 'playNormalMode',
value: function playNormalMode() {
var _this3 = this;
if (_Config2.default.practiceLevel) {
throw new Error('Unable to practice level while not in epic mode, remove -l option.');
} else {
if (this._profile.levelNumber === 0) {
return this.prepareNextLevel().then(function () {
return _UI2.default.printLine('First level has been generated. See the warriorjs/' + _this3._profile.directoryName + '/README for instructions.');
});
}
return this.playCurrentLevel();
}
}
}, {
key: 'playCurrentLevel',
value: function playCurrentLevel() {
var _this4 = this;
var playing = true;
return _bluebird2.default.join(this.getCurrentLevelConfig(), this.getPlayerCode(), function (levelConfig, playerCode) {
var newAbilities = levelConfig.floor.warrior.abilities || [];
var augmentedLevelConfig = _extends({}, levelConfig, {
floor: _extends({}, levelConfig.floor, {
warrior: _extends({}, levelConfig.floor.warrior, {
name: _this4._profile.warriorName,
abilities: [].concat(_toConsumableArray(newAbilities), _toConsumableArray(_this4._profile.abilities))
})
})
});
var _playLevel = (0, _warriorjsEngine2.default)(augmentedLevelConfig, playerCode);
var passed = _playLevel.passed;
var events = _playLevel.events;
var score = _playLevel.score;
return _UI2.default.printPlay(events).then(function () {
if (passed) {
return _this4.levelExists(_this4._profile.levelNumber + 1).then(function (exists) {
if (exists) {
_UI2.default.printLine('Success! You have found the stairs.');
} else {
playing = false;
_UI2.default.printLine('CONGRATULATIONS! You have climbed to the top of the tower.');
}
var aceScore = levelConfig.aceScore;
var floor = levelConfig.floor;
_this4.tallyPoints(_extends({}, score, { aceScore: aceScore }));
var abilities = floor.warrior.abilities;
_this4._profile.addAbilities(abilities);
if (_this4._profile.isEpic()) {
if (!playing && !_Config2.default.practiceLevel && _this4._profile.calculateAverageGrade()) {
_UI2.default.printLine(_this4.getFinalReport());
}
return _bluebird2.default.resolve(playing);
}
return _this4.requestNextLevel().then(function () {
return _bluebird2.default.resolve(playing);
});
});
}
playing = false;
_UI2.default.printLine('Sorry, you failed level ' + _this4._profile.levelNumber + '. Change your script and try ' + 'again.');
if (!_Config2.default.skipInput && levelConfig.clue) {
return _UI2.default.ask('Would you like to read the additional clues for this level?').then(function (answer) {
if (answer) {
_UI2.default.printLine(levelConfig.clue);
}
return _bluebird2.default.resolve(playing);
});
}
return _bluebird2.default.resolve(playing);
});
});
}
}, {
key: 'getPlayerCode',
value: function getPlayerCode() {
return _fsExtra2.default.readFileAsync(_path2.default.join(this._profile.playerPath, 'Player.js'), 'utf8');
}
}, {
key: 'generatePlayerFiles',
value: function generatePlayerFiles() {
var _this5 = this;
return this.getCurrentLevelConfig().then(function (level) {
return new _PlayerGenerator2.default(_this5._profile, level).generate();
});
}
}, {
key: 'requestNextLevel',
value: function requestNextLevel() {
var _this6 = this;
if (!_Config2.default.skipInput) {
return this.levelExists(this._profile.levelNumber + 1).then(function (exists) {
if (exists) {
return _UI2.default.ask('Would you like to continue on to the next level?').then(function (answer) {
if (answer) {
return _this6.prepareNextLevel().then(function () {
_UI2.default.printLine('See the updated README in the warriorjs/' + _this6._profile.directoryName + ' ' + 'directory.');
return _bluebird2.default.resolve();
});
}
return _bluebird2.default.resolve();
});
}
return _UI2.default.ask('Would you like to continue on to epic mode?').then(function (answer) {
if (answer) {
return _this6.prepareEpicMode().then(function () {
_UI2.default.printLine('Run warriorjs again to play epic mode.');
return _bluebird2.default.resolve();
});
}
return _bluebird2.default.resolve();
});
});
}
_UI2.default.printLine('Staying on current level. Try to earn more points next time.');
return _bluebird2.default.resolve();
}
}, {
key: 'prepareNextLevel',
value: function prepareNextLevel() {
var _this7 = this;
this._profile.levelNumber += 1;
return this.generatePlayerFiles().then(function () {
return _this7._profile.save();
});
}
}, {
key: 'prepareEpicMode',
value: function prepareEpicMode() {
this._profile.enableEpicMode();
this._profile.levelNumber = 0;
return this._profile.save();
}
}, {
key: 'goToNormalMode',
value: function goToNormalMode() {
var _this8 = this;
this._profile.enableNormalMode();
return this.prepareNextLevel().then(function () {
_UI2.default.printLine('Another level has been added since you started epic, going back to normal mode.');
_UI2.default.printLine('See the updated README in the warriorjs/' + _this8._profile.directoryName + ' directory.');
return _bluebird2.default.resolve();
});
}
/*
* Score
*/
}, {
key: 'tallyPoints',
value: function tallyPoints(_ref) {
var warrior = _ref.warrior;
var timeBonus = _ref.timeBonus;
var clearBonus = _ref.clearBonus;
var aceScore = _ref.aceScore;
var score = 0;
_UI2.default.printLine('Warrior Score: ' + warrior);
score += warrior;
_UI2.default.printLine('Time Bonus: ' + timeBonus);
score += timeBonus;
_UI2.default.printLine('Clear Bonus: ' + clearBonus);
score += clearBonus;
if (this._profile.isEpic()) {
if (aceScore) {
_UI2.default.printLine('Level Grade: ' + Game.getGradeFor(score, aceScore));
}
_UI2.default.printLine('Total Score: ' + Game.scoreCalculation(this._profile.currentEpicScore, score));
if (aceScore) {
this._profile.currentEpicGrades[this._profile.levelNumber] = score * 1.0 / aceScore;
}
this._profile.currentEpicScore += score;
} else {
_UI2.default.printLine('Total Score: ' + Game.scoreCalculation(this._profile.score, score));
this._profile.score += score;
}
}
}, {
key: 'getFinalReport',
value: function getFinalReport() {
var _this9 = this;
var report = '';
report += 'Your average grade for this tower is: ' + (Game.getGradeLetter(this._profile.calculateAverageGrade()) + '\n\n');
Object.keys(this._profile.currentEpicGrades).sort().forEach(function (level) {
report += ' Level ' + level + ': ' + (Game.getGradeLetter(_this9._profile.currentEpicGrades[level]) + '\n');
});
report += '\nTo practice a level, use the -l option.';
return report;
}
}, {
key: 'loadProfile',
/*
* Profiles
*/
value: function loadProfile() {
var _this10 = this;
return this.profileExists().then(function (exists) {
if (exists) {
return _Profile2.default.load(_this10._profilePath);
}
return _this10.chooseProfile();
});
}
}, {
key: 'profileExists',
value: function profileExists() {
var _this11 = this;
return new _bluebird2.default(function (resolve) {
_fsExtra2.default.statAsync(_this11._profilePath).then(function () {
return resolve(true);
}).catch({ code: 'ENOENT' }, function () {
return resolve(false);
});
});
}
}, {
key: 'chooseProfile',
value: function chooseProfile() {
var _this12 = this;
var newProfileChoice = 'New profile';
return this.getProfiles().then(function (profileChoices) {
return _UI2.default.choose('profile', profileChoices.concat(newProfileChoice));
}).then(function (profile) {
if (profile === newProfileChoice) {
return _this12.newProfile();
}
return _bluebird2.default.resolve(profile);
});
}
}, {
key: 'getProfiles',
value: function getProfiles() {
return this.getProfilePaths().then(function (profilePaths) {
return _bluebird2.default.map(profilePaths, function (profilePath) {
return _Profile2.default.load(profilePath);
});
});
}
}, {
key: 'getProfilePaths',
value: function getProfilePaths() {
return this.ensureGameDirectory().then(function () {
var profilePattern = _path2.default.join(_Config2.default.pathPrefix, 'warriorjs', '**', '.profile');
return _glob2.default.globAsync(profilePattern);
});
}
}, {
key: 'ensureGameDirectory',
value: function ensureGameDirectory() {
var _this13 = this;
return this.gameDirectoryExists().then(function (exists) {
if (!exists) {
return _this13.makeGameDirectory();
}
return _bluebird2.default.resolve();
});
}
}, {
key: 'gameDirectoryExists',
value: function gameDirectoryExists() {
var _this14 = this;
return new _bluebird2.default(function (resolve) {
_fsExtra2.default.statAsync(_this14._gameDirectoryPath).then(function () {
return resolve(true);
}).catch({ code: 'ENOENT' }, function () {
return resolve(false);
});
});
}
}, {
key: 'makeGameDirectory',
value: function makeGameDirectory() {
var _this15 = this;
return _UI2.default.ask('No warriorjs directory found, would you like to create one?').then(function (answer) {
if (answer) {
return _fsExtra2.default.mkdirAsync(_this15._gameDirectoryPath);
}
throw new Error('Unable to continue without directory.');
});
}
}, {
key: 'newProfile',
value: function newProfile() {
var _this16 = this;
var profile = new _Profile2.default();
return _UI2.default.request('Enter a name for your warrior:').then(function (warriorName) {
if (!warriorName) {
throw new Error('Your warrior must have a name if you want him to become a legend!');
}
profile.warriorName = warriorName;
return _this16.getTowers();
}).then(function (towerChoices) {
return _UI2.default.choose('tower', towerChoices);
}).then(function (tower) {
profile.towerPath = tower.path;
return _this16.isExistingProfile(profile);
}).then(function (exists) {
if (exists) {
return _UI2.default.ask('Are you sure you want to replace your existing profile for this tower?', false).then(function (answer) {
if (!answer) {
throw new Error('Unable to continue without profile.');
}
_UI2.default.printLine('Replacing existing profile...');
return _bluebird2.default.resolve(profile);
});
}
return _bluebird2.default.resolve(profile);
});
}
}, {
key: 'isExistingProfile',
value: function isExistingProfile(newProfile) {
return this.getProfiles().then(function (profiles) {
return _bluebird2.default.resolve(profiles.some(function (profile) {
return profile.playerPath === newProfile.playerPath;
}));
});
}
/*
* Towers
*/
}, {
key: 'getTowers',
value: function getTowers() {
return this.getTowerPaths().then(function (towerPaths) {
return _bluebird2.default.resolve(towerPaths.map(function (towerPath) {
return new _Tower2.default(towerPath);
}));
});
}
}, {
key: 'getTowerPaths',
value: function getTowerPaths() {
var towerPattern = _path2.default.resolve(__dirname, '..', 'towers', '*');
return _glob2.default.globAsync(towerPattern);
}
/*
* Levels
*/
}, {
key: 'getLevelPath',
value: function getLevelPath(levelNumber) {
return _path2.default.join(this._profile.towerPath, 'level' + String(levelNumber).padLeft(3, '0') + '.json');
}
}, {
key: 'levelExists',
value: function levelExists(levelNumber) {
var _this17 = this;
return new _bluebird2.default(function (resolve) {
_fsExtra2.default.statAsync(_this17.getLevelPath(levelNumber)).then(function () {
return resolve(true);
}).catch({ code: 'ENOENT' }, function () {
return resolve(false);
});
});
}
}, {
key: 'getCurrentLevelConfig',
value: function getCurrentLevelConfig() {
var levelNumber = this._profile.levelNumber;
return _fsExtra2.default.readJsonAsync(this.getLevelPath(levelNumber));
}
}, {
key: 'hasLevelAfterEpic',
value: function hasLevelAfterEpic() {
if (this._profile.lastLevelNumber) {
return this.levelExists(this._profile.lastLevelNumber + 1);
}
return _bluebird2.default.resolve(false);
}
}], [{
key: 'getGradeFor',
value: function getGradeFor(score, aceScore) {
return Game.getGradeLetter(score * 1.0 / aceScore);
}
}, {
key: 'getGradeLetter',
value: function getGradeLetter(percent) {
if (percent >= 1.0) {
return 'S';
} else if (percent >= 0.9) {
return 'A';
} else if (percent >= 0.8) {
return 'B';
} else if (percent >= 0.7) {
return 'C';
} else if (percent >= 0.6) {
return 'D';
}
return 'F';
}
}, {
key: 'scoreCalculation',
value: function scoreCalculation(currentScore, addition) {
if (currentScore === 0) {
return addition.toString();
}
return currentScore + ' + ' + addition + ' = ' + (currentScore + addition);
}
}]);
return Game;
}();
exports.default = Game;