From 248cff3be6e3b19f7665f8f7427b997b60fe968e Mon Sep 17 00:00:00 2001 From: debebantur Date: Thu, 28 Oct 2021 21:35:24 +0500 Subject: [PATCH] =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=201-?= =?UTF-8?q?10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 6 +- src/TaskQueue.js | 34 ++++--- src/index.js | 222 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 229 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62879f0..b5765b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,9 +89,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "mime": { "version": "1.6.0", diff --git a/src/TaskQueue.js b/src/TaskQueue.js index f3a9c6a..33688c4 100644 --- a/src/TaskQueue.js +++ b/src/TaskQueue.js @@ -1,10 +1,10 @@ -const TaskQueue = function() { - function TaskQueue() { +export default class TaskQueue { + constructor() { this.tasks = []; this.running = false; } - TaskQueue.prototype.push = function(run, dispose, duration) { + push = function(run, dispose, duration) { if (duration === undefined || duration === null) { this.tasks.push({runAndContinue: run, dispose}); } else { @@ -18,38 +18,34 @@ const TaskQueue = function() { dispose }); } - runNextTask(this); + this.#runNextTask(); }; - TaskQueue.prototype.continueWith = function(action) { + continueWith = function(action) { this.push(action, null, 0); }; - function runNextTask(taskQueue) { - if (taskQueue.running || taskQueue.tasks.length === 0) { + #runNextTask() { + if (this.running || this.tasks.length === 0) { return; } - taskQueue.running = true; - const task = taskQueue.tasks.shift(); - + this.running = true; + const task = this.tasks.shift(); + if (task.runAndContinue) { setTimeout(() => { task.runAndContinue(() => { task.dispose && task.dispose(); - taskQueue.running = false; - + this.running = false; + setTimeout(() => { - runNextTask(taskQueue); + this.#runNextTask(); }); }); }, 0); } else { - runNextTask(taskQueue); + this.#runNextTask(); } } - - return TaskQueue; -}(); - -export default TaskQueue; +} diff --git a/src/index.js b/src/index.js index a01f912..c4bacbd 100644 --- a/src/index.js +++ b/src/index.js @@ -27,30 +27,230 @@ function getCreatureDescription(card) { return 'Существо'; } +class Creature extends Card { + constructor(name = "кто?", maxPower = 1) { + super(name, maxPower); + } + getDescriptions() { + return [getCreatureDescription(this), + super.getDescriptions()] + } + + get currentPower() { + return this._power; + }; + set currentPower(value) { + this._power = Math.min(value, this.maxPower); + }; +} // Основа для утки. -function Duck() { - this.quacks = function () { console.log('quack') }; - this.swims = function () { console.log('float: both;') }; +class Duck extends Creature { + constructor(name = "Мирная утка", maxPower = 2) { + super(name, maxPower); + } + + quacks = function () { console.log('quack') }; + swims = function () { 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(actualValue, fromCard, gameContext, continuation) { + this.view.signalAbility(() => continuation(actualValue - 1)); + } + + getDescriptions() { + return ['Получает на 1 меньше урона', + ...super.getDescriptions()] + } +} + +//Гатлинг +class Gatling extends Duck { + constructor(name = 'Гатлинг', maxPower = 6) { + super(name, maxPower); + } + + attack(gameContext, continuation) { + const taskQueue = new TaskQueue(); + + const { currentPlayer, oppositePlayer, position, updateView } = gameContext; + + taskQueue.push(onDone => this.view.showAttack(onDone)); + + for (let oppositeCard of oppositePlayer.table) + taskQueue.push(onDone => this.dealDamageToCreature(2, oppositeCard, gameContext, onDone)); + + taskQueue.continueWith(continuation); + }; + + getDescriptions() { + return ['Наносит всем противникам 2 урона', + ...super.getDescriptions()] + } +} + +//Браток +class Lad extends Dog { + constructor(name = 'Браток', maxPower = 2) { + super(name, maxPower); + } + + static getInGameCount() { return this.inGameCount || 0; } + static setInGameCount(value) { this.inGameCount = value; } + static getBonus() { return this.inGameCount * (this.inGameCount + 1) / 2; } + + doAfterComingIntoPlay(gameContext, continuation) { + Lad.setInGameCount(Lad.getInGameCount() + 1); + continuation(); + } + + doBeforeRemoving(continuation) { + Lad.setInGameCount(Lad.getInGameCount() - 1); + continuation(); + } + + modifyTakenDamage(actualValue, fromCard, gameContext, continuation) { + this.view.signalAbility(() => continuation(actualValue - Lad.getBonus())); + } + + modifyDealedDamageToCreature(value, toCard, gameContext, continuation) { + this.view.signalAbility(() => + super.modifyDealedDamageToCreature(value + Lad.getBonus(), toCard, gameContext, continuation) + ) + } + + getDescriptions() { + if (Lad.prototype.hasOwnProperty("modifyDealedDamageToCreature") && Lad.prototype.hasOwnProperty("modifyDealedDamageToCreature")) + return ["Их больше - они сильнее", ...super.getDescriptions()] + return super.getDescriptions(); + } +} + +//Изгой +class Rogue extends Creature { + constructor(name = 'Изгой', maxPower = 2) { + super(name, maxPower); + } + + doBeforeAttack(gameContext, continuation) { + const taskQueue = new TaskQueue(); + const { currentPlayer, oppositePlayer, position, updateView } = gameContext; + let proto = Object.getPrototypeOf(oppositePlayer.table[position]); + + taskQueue.push(onDone => { + if (proto.hasOwnProperty('modifyDealedDamageToCreature')) + this['modifyDealedDamageToCreature'] = proto['modifyDealedDamageToCreature']; + delete proto['modifyDealedDamageToCreature']; + if (proto.hasOwnProperty('modifyDealedDamageToPlayer')) + this['modifyDealedDamageToPlayer'] = proto['modifyDealedDamageToPlayer']; + delete proto['modifyDealedDamageToPlayer']; + if (proto.hasOwnProperty('modifyTakenDamage')) + this['modifyTakenDamage'] = proto['modifyTakenDamage']; + delete proto['modifyTakenDamage']; + + this.view.signalAbility(onDone); + gameContext.updateView(); + }); + + taskQueue.continueWith(continuation); + } + + getDescriptions() { + return ['Крадёт способности', + ...super.getDescriptions()] + } +} + +//Пивовар +class Brewer extends Duck { + constructor(name = 'Пивовар', maxPower = 2) { + super(name, maxPower); + } + + doBeforeAttack(gameContext, continuation) { + const taskQueue = new TaskQueue(); + const { currentPlayer, oppositePlayer, position, updateView } = gameContext; + let ducks = currentPlayer.table.concat(oppositePlayer.table).filter(x => isDuck(x)); + + for (let i of ducks) { + taskQueue.push(onDone => { + i.maxPower += 1; + i.currentPower += 2; + i.view.signalHeal(onDone); + i.updateView(); + }); + } + + taskQueue.continueWith(continuation); + } + + getDescriptions() { + return ['Восстанавливает здоровье', + ...super.getDescriptions()] + } +} + +//Псевдоутка +class PseudoDuck extends Dog { + constructor(name = 'Уткопёс', maxPower = 3) { + super(name, maxPower); + } + + quacks = function () { console.log('Woof') }; + swims = function () { console.log('byl`k') }; + + getDescriptions() { + return ['Притворяется уткой', + ...super.getDescriptions()] + } } +//Мимик +class Nemo extends Creature { + constructor(name = 'Немо', maxPower = 4) { + super(name, maxPower); + } + + doBeforeAttack(gameContext, continuation) { + const taskQueue = new TaskQueue(); + const { currentPlayer, oppositePlayer, position, updateView } = gameContext; + + taskQueue.push(onDone => { + Object.setPrototypeOf(this, Object.getPrototypeOf(oppositePlayer.table[position])); + this.doBeforeAttack(gameContext, continuation); + this.view.signalAbility(onDone); + gameContext.updateView(); + }); + + taskQueue.continueWith(continuation); + } + + getDescriptions() { + return ['копирует прототип', + ...super.getDescriptions()] + } +} -// Колода Шерифа, нижнего игрока. const seriffStartDeck = [ - new Card('Мирный житель', 2), - new Card('Мирный житель', 2), - new Card('Мирный житель', 2), + new Nemo(), ]; - -// Колода Бандита, верхнего игрока. const banditStartDeck = [ - new Card('Бандит', 3), + new PseudoDuck(), ];