Advertisement
Guest User

aadsd

a guest
Feb 22nd, 2017
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function solve() {
  2.     'use strict';
  3.  
  4.     const ERROR_MESSAGES = {
  5.         INVALID_NAME_TYPE: 'Name must be string!',
  6.         INVALID_NAME_LENGTH: 'Name must be between between 2 and 20 symbols long!',
  7.         INVALID_NAME_SYMBOLS: 'Name can contain only latin symbols and whitespaces!',
  8.         INVALID_MANA: 'Mana must be a positive integer number!',
  9.         INVALID_EFFECT: 'Effect must be a function with 1 parameter!',
  10.         INVALID_DAMAGE: 'Damage must be a positive number that is at most 100!',
  11.         INVALID_HEALTH: 'Health must be a positive number that is at most 200!',
  12.         INVALID_SPEED: 'Speed must be a positive number that is at most 100!',
  13.         INVALID_COUNT: 'Count must be a positive integer number!',
  14.         INVALID_SPELL_OBJECT: 'Passed objects must be Spell-like objects!',
  15.         NOT_ENOUGH_MANA: 'Not enough mana!',
  16.         TARGET_NOT_FOUND: 'Target not found!',
  17.         INVALID_BATTLE_PARTICIPANT: 'Battle participants must be ArmyUnit-like!'
  18.  
  19.     };
  20.  
  21.     const generateID = (function() {
  22.         let counter = 0;
  23.         return function() {
  24.             return counter += 1;
  25.         }
  26.     })();
  27.  
  28.     const VALIDATOR = {
  29.         Check_If_MANA_Is_Not_Undefined_Or_Type_Number_And_Positive_Number: function(x) {
  30.             if (x == undefined || x == NaN || typeof x != 'number' || x < 0) {
  31.                 throw Error(ERROR_MESSAGES.INVALID_MANA);
  32.             }
  33.         },
  34.         Check_If_NAME_Is_Not_Undefined_Or_Type_String: function(x) {
  35.             if (x == undefined || typeof x != 'string') {
  36.                 throw Error('Name must be between between 2 and 20 symbols long!');
  37.             }
  38.         },
  39.         Is_In_Range_Min_And_Max: function(x, min, max) {
  40.             if (x < min || x > max) {
  41.                 throw Error(ERROR_MESSAGES.INVALID_NAME_LENGTH);
  42.             }
  43.         },
  44.         String_Contains_Latin_Letters_And_Space: function(x) {
  45.             let pattern = /([A-Za-z\s])+/g;
  46.  
  47.             if (!(pattern.test(x))) {
  48.                 throw Error(ERROR_MESSAGES.INVALID_NAME_SYMBOLS);
  49.             }
  50.         },
  51.         Check_If_IT_Is_Less_Than_100_And_Is_Number_And_Not_Undefined_And_Positive: function(x, max, message) {
  52.             if (x == undefined || typeof x != 'number' || x > max || x < 0) {
  53.                 throw Error(message);
  54.             }
  55.         }
  56.  
  57.     };
  58.  
  59.  
  60.     class Unit {
  61.         constructor(name, alignment) {
  62.             this.name = name;
  63.             this.alignment = alignment;
  64.         }
  65.  
  66.         get name() {
  67.             return this._name;
  68.         }
  69.  
  70.         set name(x) {
  71.  
  72.             VALIDATOR.Check_If_NAME_Is_Not_Undefined_Or_Type_String(x);
  73.  
  74.             VALIDATOR.Is_In_Range_Min_And_Max(x.length, 2, 20);
  75.  
  76.             VALIDATOR.String_Contains_Latin_Letters_And_Space(x);
  77.  
  78.             this._name = x;
  79.         }
  80.  
  81.         get alignment() {
  82.             return this._alignment;
  83.         }
  84.  
  85.         set alignment(x) {
  86.  
  87.             if (x !== 'good' && x !== 'neutral' && x !== 'evil') {
  88.                 throw Error('Alignment must be good, neutral or evil!');
  89.             }
  90.  
  91.             this._alignment = x;
  92.         }
  93.     };
  94.  
  95.  
  96.     class ArmyUnit extends Unit {
  97.         constructor(name, alignment, damage, health, speed, count) {
  98.             super(name, alignment);
  99.  
  100.             this.id = generateID();
  101.             this.damage = damage;
  102.             this.health = health;
  103.             this.count = count;
  104.             this.speed = speed;
  105.         }
  106.  
  107.         get damage() {
  108.             return this._damage;
  109.         }
  110.  
  111.         set damage(x) {
  112.  
  113.             VALIDATOR.Check_If_IT_Is_Less_Than_100_And_Is_Number_And_Not_Undefined_And_Positive(x, 100, ERROR_MESSAGES.INVALID_DAMAGE);
  114.  
  115.             this._damage = x;
  116.         }
  117.  
  118.         get health() {
  119.             return this._health;
  120.         }
  121.  
  122.         set health(x) {
  123.  
  124.             VALIDATOR.Check_If_IT_Is_Less_Than_100_And_Is_Number_And_Not_Undefined_And_Positive(x, 200,
  125.                 ERROR_MESSAGES.INVALID_HEALTH);
  126.             this._health = x;
  127.         }
  128.  
  129.         get count() {
  130.             return this._count;
  131.         }
  132.  
  133.         set count(x) {
  134.  
  135.             if (x == undefined || typeof x != 'number' || x < 0) {
  136.                 throw Error(ERROR_MESSAGES.INVALID_COUNT);
  137.             }
  138.  
  139.             this._count = x;
  140.         }
  141.  
  142.         get speed() {
  143.             return this._speed;
  144.         }
  145.  
  146.         set speed(x) {
  147.  
  148.             VALIDATOR.Check_If_IT_Is_Less_Than_100_And_Is_Number_And_Not_Undefined_And_Positive(x, 100,
  149.                 ERROR_MESSAGES.INVALID_SPEED);
  150.  
  151.             this._speed = x;
  152.         }
  153.     };
  154.  
  155.  
  156.     class Commander extends Unit {
  157.         constructor(name, alignment, mana) {
  158.             super(name, alignment);
  159.  
  160.             this.mana = mana;
  161.             this.spellbook = [];
  162.             this.army = [];
  163.         }
  164.  
  165.         get mana() {
  166.             return this._mana;
  167.         }
  168.  
  169.         set mana(x) {
  170.  
  171.             if (x == undefined || typeof x != 'number' || x < 0) {
  172.                 throw Error('Mana must be a positive integer number!');
  173.             }
  174.  
  175.             this._mana = x;
  176.         }
  177.     }
  178.  
  179.  
  180.     class Spell {
  181.         constructor(name, manaCost, effect) {
  182.             this.name = name;
  183.             this.manaCost = manaCost;
  184.             this.effect = effect;
  185.         };
  186.  
  187.         get name() {
  188.             return this._name;
  189.         }
  190.  
  191.         set name(x) {
  192.  
  193.             VALIDATOR.Check_If_NAME_Is_Not_Undefined_Or_Type_String(x);
  194.  
  195.             VALIDATOR.Is_In_Range_Min_And_Max(x.length, 2, 20);
  196.  
  197.             VALIDATOR.String_Contains_Latin_Letters_And_Space(x);
  198.  
  199.             this._name = x;
  200.         }
  201.  
  202.         get manaCost() {
  203.             return this._manaCost;
  204.         }
  205.  
  206.         set manaCost(x) {
  207.  
  208.             VALIDATOR.Check_If_MANA_Is_Not_Undefined_Or_Type_Number_And_Positive_Number(x);
  209.  
  210.             this._manaCost = x;
  211.         }
  212.  
  213.         get effect() {
  214.             return this._effect;
  215.         }
  216.  
  217.         set effect(x) {
  218.  
  219.             if (x == undefined || typeof x != 'function' || x.length != 1) {
  220.                 throw Error(ERROR_MESSAGES.INVALID_EFFECT);
  221.             }
  222.  
  223.             this._effect = x;
  224.         }
  225.  
  226.     };
  227.  
  228.  
  229.     class Battlemanager {
  230.  
  231.         constructor() {
  232.             this._armyOfCommanders = [];
  233.             this._armyOfUnits = [];
  234.         }
  235.  
  236.         getCommander(name, alignment, mana) {
  237.             return new Commander(name, alignment, mana);
  238.         }
  239.  
  240.         getArmyUnit(options) {
  241.             let unit = new ArmyUnit(options.name, options.alignment, options.damage, options.health,
  242.                 options.speed, options.count);
  243.  
  244.             this._armyOfUnits.push(unit);
  245.             return unit;
  246.         }
  247.  
  248.         getSpell(name, manaCost, effect) {
  249.             return new Spell(name, manaCost, effect);
  250.         }
  251.  
  252.         addCommanders(...commanders) {
  253.  
  254.             //commanders.forEach(x => this._armyOfCommanders.push(x));
  255.  
  256.             this._armyOfCommanders = this._armyOfCommanders.concat(commanders);
  257.  
  258.             return this;
  259.         }
  260.  
  261.         addArmyUnitTo(commanderName, armyUnit) {
  262.  
  263.             let commander = this._armyOfCommanders.find(x => x.name == commanderName);
  264.  
  265.             if (commander == undefined) {
  266.                 throw Error('No such commander');
  267.             }
  268.  
  269.             commander.army.push(armyUnit);
  270.  
  271.  
  272.             return this;
  273.         }
  274.  
  275.         addSpellsTo(commanderName, ...spells) {
  276.  
  277.             let commander = this._armyOfCommanders.find(x => x.name === commanderName);
  278.  
  279.             if (commander == undefined) {
  280.                 throw Error('No such commander');
  281.             }
  282.  
  283.             for (let spell of spells) {
  284.                 if (spell == undefined || (!(spell instanceof Spell)) || typeof spell != 'object') {
  285.                     throw Error(ERROR_MESSAGES.INVALID_SPELL_OBJECT);
  286.                 }
  287.             }
  288.  
  289.             spells.forEach(x => commander.spellbook.push(x));
  290.  
  291.             return this;
  292.         }
  293.  
  294.  
  295.         findCommanders(query) {
  296.  
  297.  
  298.             if (Object.keys(query).length == 0) {
  299.  
  300.                 // this._armyOfCommanders.sort((a, b) => a.name > b.name);
  301.  
  302.                 return this._armyOfCommanders;
  303.             }
  304.  
  305.             let commanders = [];
  306.  
  307.             for (let c of this._armyOfCommanders) {
  308.                 if (Object.keys(query).every(x => c[x] == query[x])) {
  309.                     commanders.push(c);
  310.                 }
  311.             }
  312.  
  313.             //commanders.sort((a, b) => a.name > b.name);
  314.  
  315.             return commanders;
  316.         }
  317.  
  318.         findArmyUnitById(id) {
  319.             return this._armyOfUnits.find(x => x.id == id);
  320.         }
  321.  
  322.         findArmyUnits(query) {
  323.  
  324.             if (Object.keys(query).length == 0) {
  325.  
  326.                 // this._armyOfUnits.sort((a, b) => a.speed < b.speed);
  327.  
  328.                 // for (let i = 0; i < this._armyOfUnits.length - 1; i += 1) {
  329.                 //     if (this._armyOfUnits[i].speed == this._armyOfUnits[i + 1].speed) {
  330.                 //         let temp = this._armyOfUnits[i];
  331.                 //         this._armyOfUnits[i] = this._armyOfUnits[i + 1];
  332.                 //         this._armyOfUnits[i + 1] = temp;
  333.                 //     }
  334.                 // }
  335.  
  336.  
  337.  
  338.                 return this._armyOfUnits;
  339.             }
  340.  
  341.             let result = [];
  342.  
  343.             for (let unit of this._armyOfUnits) {
  344.                 if (Object.keys(query).every(x => unit[x] == query[x])) {
  345.                     result.push(unit);
  346.                 }
  347.             }
  348.  
  349.             // result.sort((a, b) => a.speed < b.speed);
  350.  
  351.             // for (let i = 0; i < result.length - 1; i += 1) {
  352.             //     if (result[i].speed == result[i + 1].speed) {
  353.             //         let temp = result[i];
  354.             //         result[i] = result[i + 1];
  355.             //         result[i + 1] = temp;
  356.             //     }
  357.             // }
  358.  
  359.             return result;
  360.  
  361.         }
  362.         spellcast(casterName, spellName, targetUnitId) {
  363.             let caster = this._armyOfCommanders.find(x => x.name == casterName);
  364.             if (caster == undefined) {
  365.                 throw Error('Can\'t cast with non-existant commander ' + casterName + '!');
  366.             }
  367.  
  368.             let spell = caster.spellbook.find(x => x.name == spellName);
  369.             if (spell == undefined) {
  370.                 throw Error(casterName + ' doesn\'t know ' + spellName);
  371.             }
  372.  
  373.             let target = this._armyOfUnits.find(x => x.id == targetUnitId);
  374.             if (target == undefined) {
  375.                 throw Error('Target not found!');
  376.             }
  377.  
  378.             if (caster.mana < spell.manaCost) {
  379.                 throw Error('Not enough mana!');
  380.             }
  381.  
  382.             spell.effect(target);
  383.  
  384.             if (caster.mana - spell.manaCost < 0) {
  385.                 caster.mana = 0;
  386.             } else {
  387.                 caster.mana -= spell.manaCost;
  388.             }
  389.  
  390.  
  391.             return this;
  392.         }
  393.  
  394.         battle(attacker, defender) {
  395.  
  396.             if (!(attacker instanceof ArmyUnit) || !(defender instanceof ArmyUnit)) {
  397.                 throw Error('Battle participants must be ArmyUnit-like!');
  398.             }
  399.             let attackerTotalDamage = attacker.damage * attacker.count;
  400.             let defenderTotalHealth = defender.health * defender.count;
  401.  
  402.  
  403.             defenderTotalHealth -= attackerTotalDamage;
  404.             let newCount = Math.ceil(defenderTotalHealth / defender.health);
  405.  
  406.  
  407.             defender.count = newCount < 0 ? 0 : newCount;
  408.  
  409.         }
  410.     };
  411.  
  412.  
  413.     return new Battlemanager;
  414. }
  415. module.exports = solve;
  416.  
  417. // let MANAGER = solve();
  418.  
  419. // const tinkyWinky = MANAGER.getCommander('Tinky Winky', 'good', 66),
  420. //     billGates = MANAGER.getCommander('Bill Gates', 'evil', 66)
  421.  
  422. // MANAGER.addCommanders(tinkyWinky, billGates)
  423.  
  424. // const armyUnits = {
  425. //     dwarfs: MANAGER.getArmyUnit({ name: 'Dwarfs', speed: 20, damage: 33, health: 44, alignment: 'good', count: 50 }),
  426. //     codeMonkeys: MANAGER.getArmyUnit({ name: 'Code Monkeys', speed: 20, damage: 5, health: 5, alignment: 'good', count: 300 }),
  427. //     students: MANAGER.getArmyUnit({ name: 'Students', speed: 20, damage: 25, health: 33, alignment: 'good', count: 100 }),
  428. //     mages1: MANAGER.getArmyUnit({ name: 'Mages One', speed: 15, damage: 60, health: 25, alignment: 'good', count: 5 }),
  429. //     mages2: MANAGER.getArmyUnit({ name: 'Mages Two', speed: 15, damage: 60, health: 25, alignment: 'good', count: 50 }),
  430. //     mages3: MANAGER.getArmyUnit({ name: 'Mages Three', speed: 15, damage: 60, health: 25, alignment: 'good', count: 3 }),
  431. // }
  432.  
  433. // MANAGER
  434. //     .addArmyUnitTo('Tinky Winky', armyUnits.dwarfs)
  435. //     .addArmyUnitTo('Bill Gates', armyUnits.codeMonkeys)
  436. //     .addArmyUnitTo('Bill Gates', armyUnits.students)
  437. //     .addArmyUnitTo('Bill Gates', armyUnits.mages1)
  438. //     .addArmyUnitTo('Tinky Winky', armyUnits.mages2)
  439. //     .addArmyUnitTo('Bill Gates', armyUnits.mages3)
  440.  
  441. // const allUnits = MANAGER.findArmyUnits({})
  442.  
  443. // const sortedArmyUnits = Object.keys(armyUnits).map(k => armyUnits[k]).sort(compareUnits)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement