From 209397ec8a20159faaf2ccea12c94d6a0dfca57f Mon Sep 17 00:00:00 2001 From: xamaryllis <114435320+xamaryllis@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:49:35 +0500 Subject: [PATCH] new solution --- src/index.js | 218 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 208 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index a01f912..2639407 100644 --- a/src/index.js +++ b/src/index.js @@ -27,33 +27,229 @@ function getCreatureDescription(card) { return 'Существо'; } +class Creature extends Card { + constructor(name, maxPower, image) { + super(name, maxPower, image); + this._currentPower = maxPower; + } + get currentPower() { + return this._currentPower; + } + set currentPower(value) { + this._currentPower = Math.min(value, this.maxPower); + } -// Основа для утки. -function Duck() { - this.quacks = function () { console.log('quack') }; - this.swims = function () { console.log('float: both;') }; + getDescriptions() { + return [ + getCreatureDescription(this), + ...super.getDescriptions(), + ]; + } } +// Основа для утки. +class Duck extends Creature { + constructor(name = 'Мирная утка', maxPower = 2) { + super(name, maxPower); + } + + quacks() { + console.log('quack'); + } + + swims() { + console.log('float: both;'); + } +} // Основа для собаки. -function Dog() { +class Dog extends Creature { + constructor(name = 'Пес-бандит', maxPower = 3) { + super(name, maxPower); + } } +class Trasher extends Dog { + constructor(name = 'Громила', maxPower = 5) { + super(name, maxPower); + } + + modifyTakenDamage(value, fromCard, gameContext, continuation) { + const modifiedValue = value - 1; + this.view.signalAbility(() => super.modifyTakenDamage(modifiedValue, fromCard, gameContext, continuation)); + } + + getDescriptions() { + return [ + 'Получает на 1 меньше урона', + ...super.getDescriptions(), + ]; + } +} + +class Gatling extends Creature { + constructor(name = 'Гатлинг', maxPower = 6) { + super(name, maxPower); + } + + attack(gameContext, continuation) { + const { oppositePlayer } = gameContext; + const taskQueue = new TaskQueue(); + + for (let card of oppositePlayer.table) { + taskQueue.push(onDone => { + this.view.showAttack(() => { + this.dealDamageToCreature(2, card, gameContext, onDone); + }); + }); + } + + taskQueue.continueWith(continuation); + } +} + +class Lad extends Dog { + static inGameCount = 0; + + constructor(name = 'Браток', maxPower = 2) { + super(name, maxPower); + } + + static getInGameCount() { + return Lad.inGameCount; + } + + static setInGameCount(value) { + Lad.inGameCount = value; + } + + static getBonus() { + const bonus = (Lad.getInGameCount() * (Lad.getInGameCount() + 1)) / 2; + return { + safety: bonus, + damage: bonus, + }; + } + + doAfterComingIntoPlay(gameContext, continuation) { + Lad.setInGameCount(Lad.getInGameCount() + 1); + super.doAfterComingIntoPlay(gameContext, continuation); + } + + doBeforeRemoving(continuation) { + Lad.setInGameCount(Lad.getInGameCount() - 1); + super.doBeforeRemoving(continuation); + } + + modifyDealedDamageToCreature(value, toCard, gameContext, continuation) { + const { damage } = Lad.getBonus(); + this.view.signalAbility(() => { + super.modifyDealedDamageToCreature(value + damage, toCard, gameContext, continuation); + }); + } + + modifyTakenDamage(value, fromCard, gameContext, continuation) { + const { safety } = Lad.getBonus(); + this.view.signalAbility(() => { + super.modifyTakenDamage(value - safety, fromCard, gameContext, continuation); + }); + } + + getDescriptions() { + return [ + 'Чем их больше, тем они сильнее', + ...super.getDescriptions() + ]; + } +} + +class Rogue extends Creature { + constructor(name = 'Изгой', maxPower = 2) { + super(name, maxPower); + } + + doBeforeAttack(gameContext, continuation) { + const { oppositePlayer, position, updateView } = gameContext; + const oppositeCard = oppositePlayer.tableposition; + if (oppositeCard) { + const oppositeCardProto = Object.getPrototypeOf(oppositeCard); + const abilities = ['modifyDealedDamageToCreature', 'modifyDealedDamageToPlayer', 'modifyTakenDamage']; + this.removeAbilities(oppositeCardProto, abilities, updateView, continuation); + } else { + super.doBeforeAttack(gameContext, continuation); + } + } + + removeAbilities(cardPrototype, abilities, updateView, continuation) { + this.view.signalAbility(() => { + for (let ability of abilities) { + if (cardPrototype.hasOwnProperty(ability)) { + delete oppositeCardProto[ability]; + } + } + updateView(); + super.doBeforeAttack(gameContext, continuation); + }); + } +} + +class Brewer extends Duck { + constructor(name = 'Пивовар', maxPower = 2) { + super(name, maxPower); + } + + async doBeforeAttack(gameContext, continuation) { + const { currentPlayer, oppositePlayer } = gameContext; + const ducks = [...currentPlayer.table, ...oppositePlayer.table].filter(card => isDuck(card)); + await this.view.signalAbility(); + ducks.forEach(card => { + card.maxPower += 1; + card.currentPower += 2; + card.view.signalHeal(() => card.updateView()); + }) + await super.doBeforeAttack(gameContext, continuation); + } +} + +class PseudoDuck extends Dog { + constructor(name = 'Псевдоутка', maxPower = 3) { + super(name, maxPower); + this.quacks = Duck.prototype.quacks.bind(this); + this.swims = Duck.prototype.swims.bind(this); + } +} + +class Nemo extends Creature { + constructor(name = 'Немо', maxPower = 4) { + super(name, maxPower); + } + + doBeforeAttack(gameContext, continuation) { + const { oppositePlayer, position, updateView } = gameContext; + const oppositeCard = oppositePlayer.table[position]; + if (oppositeCard) { + const proto = Object.getPrototypeOf(oppositeCard); + this.view.signalAbility(() => { + Object.setPrototypeOf(this, proto); + updateView(); + this.doBeforeAttack(gameContext, continuation); + }); + } else super.doBeforeAttack(gameContext, continuation); + } +} // Колода Шерифа, нижнего игрока. const seriffStartDeck = [ - new Card('Мирный житель', 2), - new Card('Мирный житель', 2), - new Card('Мирный житель', 2), + new Nemo(), ]; // Колода Бандита, верхнего игрока. const banditStartDeck = [ - new Card('Бандит', 3), + new Brewer(), + new Brewer(), ]; - // Создание игры. const game = new Game(seriffStartDeck, banditStartDeck); @@ -64,3 +260,5 @@ SpeedRate.set(1); game.play(false, (winner) => { alert('Победил ' + winner.name); }); + +