UNPKG

warriorjs-ja

Version:

Game written in JavaScript for learning JavaScript and artificial intelligence

601 lines (493 loc) 19.2 kB
'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;