From a7e5ba84ae1b5fee715a93ecf7a31fa29d890154 Mon Sep 17 00:00:00 2001 From: Vladislav Ostanin Date: Thu, 2 Nov 2023 01:04:35 +0500 Subject: [PATCH] Vladislav Ostanin task4 8/10 --- src/TaskQueue.js | 64 ++++++++-------- src/index.js | 191 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 197 insertions(+), 58 deletions(-) diff --git a/src/TaskQueue.js b/src/TaskQueue.js index f3a9c6a..7d8a7ee 100644 --- a/src/TaskQueue.js +++ b/src/TaskQueue.js @@ -1,12 +1,36 @@ -const TaskQueue = function() { - function TaskQueue() { +function runNextTask(taskQueue) { + if (taskQueue.running || taskQueue.tasks.length === 0) { + return; + } + taskQueue.running = true; + const task = taskQueue.tasks.shift(); + + if (task.runAndContinue) { + setTimeout(() => { + task.runAndContinue(() => { + task.dispose && task.dispose(); + taskQueue.running = false; + + setTimeout(() => { + runNextTask(taskQueue); + }); + }); + }, 0); + } + else { + runNextTask(taskQueue); + } +} + +class TaskQueue { + constructor() { this.tasks = []; this.running = false; } - TaskQueue.prototype.push = function(run, dispose, duration) { + push(run, dispose, duration) { if (duration === undefined || duration === null) { - this.tasks.push({runAndContinue: run, dispose}); + this.tasks.push({ runAndContinue: run, dispose }); } else { this.tasks.push({ runAndContinue: (continuation) => { @@ -19,37 +43,13 @@ const TaskQueue = function() { }); } runNextTask(this); - }; - - TaskQueue.prototype.continueWith = function(action) { + } + continueWith(action) { this.push(action, null, 0); - }; - function runNextTask(taskQueue) { - if (taskQueue.running || taskQueue.tasks.length === 0) { - return; - } - taskQueue.running = true; - const task = taskQueue.tasks.shift(); - - if (task.runAndContinue) { - setTimeout(() => { - task.runAndContinue(() => { - task.dispose && task.dispose(); - taskQueue.running = false; + }; - setTimeout(() => { - runNextTask(taskQueue); - }); - }); - }, 0); - } - else { - runNextTask(taskQueue); - } - } - return TaskQueue; -}(); +} export default TaskQueue; diff --git a/src/index.js b/src/index.js index a01f912..5937dae 100644 --- a/src/index.js +++ b/src/index.js @@ -3,17 +3,174 @@ import Game from './Game.js'; import TaskQueue from './TaskQueue.js'; import SpeedRate from './SpeedRate.js'; -// Отвечает является ли карта уткой. +class Creature extends Card{ + constructor(name, maxPower) { + super(name, maxPower); + this._currentPower = maxPower; + } + + getDescriptions(){ + let description1 = super.getDescriptions(); + let description2 = getCreatureDescription(this) + return [description1, description2]; + } + + get currentPower() { + return this._currentPower; + } + + set currentPower(value) { + this._currentPower = value > this.maxPower ? this.maxPower : value; + } +} + +class Duck extends Creature{ + constructor(name = 'Мирная утка', maxPower = 2) { + super(name, maxPower) + } + + quacks() { console.log('quack') }; + swims() { console.log('float: both;') }; +} + +class Brewer extends Duck { + constructor(name = 'Пивовар', maxPower = 2, image = null) { + super(name, maxPower, image); + } + + doBeforeAttack(gameContext, continuation) { + const { currentPlayer, oppositePlayer, position, updateView } = + gameContext; + const allCards = currentPlayer.table.concat(oppositePlayer.table); + allCards + .filter((card) => isDuck(card)) + .forEach((card) => { + card.maxPower += 1; + card.currentPower += 2; + card.view.signalHeal(); + card.updateView(); + }); + updateView(); + continuation(); + } +} + +class Gatling extends Creature{ + constructor(name = 'Gatling', maxPower=6){ + super(name, maxPower) + } + attack(gameContext, continuation){ + const taskQueue = new TaskQueue(); + const {currentPlayer, oppositePlayer, position, updateView} = gameContext; + this.table = gameContext.oppositePlayer.table; + + for (let pos = 0; pos < this.table.length; pos++){ + const card = this.table[pos] + taskQueue.push(onDone => this.view.showAttack(onDone)); + this.dealDamageToCreature(2, card, gameContext, continuation); + + } + taskQueue.continueWith(continuation); + } + +} + +class Dog extends Creature{ + constructor(name = 'Пёс бандит', maxPower = 3) { + super(name, maxPower) + } +} + +class Trasher extends Dog { + constructor() { + super("Громила", 5) + } + + getDescriptions() { + return ["Если Громилу атакуют, то он получает на 1 меньше урона", super.getDescriptions(this)] + } + + modifyTakenDamage(value, fromCard, gameContext, continuation) { + this.view.signalAbility(() => { super.modifyTakenDamage(value - 1, fromCard, gameContext, continuation) }) + } +} + +class Lad extends Dog { + constructor() { + super('Братки', 2); + } + + static getBonus() { + const inGameCount = this.getLadCount(); + return (inGameCount * (inGameCount + 1)) / 2; + } + + static getLadCount() { + return this.inGameCount || 0; + } + + static setLadCount(value) { + this.inGameCount = value; + } + + + doAfterComingIntoPlay(gameContext, continuation) { + if (Lad.inGameCount === undefined) { + Lad.setLadCount(1); + continuation(); + return; + } + Lad.setLadCount(Lad.inGameCount + 1); + continuation(); + } + + doBeforeRemoving(continuation) { + Lad.setLadCount(Lad.inGameCount - 1); + continuation(); + } + + modifyDealtDamageToCreature(value, toCard, gameContext, continuation) { + continuation(value + Lad.getBonus()); + } + + modifyTakenDamage(value, fromCard, gameContext, continuation) { + continuation(value - Lad.getBonus()); + } + + getDescriptions() { + let descriptions = super.getDescriptions(); + if ( + Lad.prototype.hasOwnProperty('modifyDealtDamageToCreature') || + Lad.prototype.hasOwnProperty('modifyTakenDamage') + ) + descriptions.unshift('Чем их больше, тем они сильнее'); + return descriptions; + } +} + + +class PseudoDuck extends Dog { + constructor() { + super('Псевдоутка', 3); + } + + quacks() { + console.log('quack'); + } + + swims() { + console.log('float: both;'); + } +} + function isDuck(card) { return card && card.quacks && card.swims; } -// Отвечает является ли карта собакой. function isDog(card) { return card instanceof Dog; } -// Дает описание существа по схожести с утками и собаками function getCreatureDescription(card) { if (isDuck(card) && isDog(card)) { return 'Утка-Собака'; @@ -27,40 +184,22 @@ function getCreatureDescription(card) { return 'Существо'; } - - -// Основа для утки. -function Duck() { - this.quacks = function () { console.log('quack') }; - this.swims = function () { console.log('float: both;') }; -} - - -// Основа для собаки. -function Dog() { -} - - -// Колода Шерифа, нижнего игрока. const seriffStartDeck = [ - new Card('Мирный житель', 2), - new Card('Мирный житель', 2), - new Card('Мирный житель', 2), + new Brewer(), + new Duck(), + new Duck(), ]; -// Колода Бандита, верхнего игрока. const banditStartDeck = [ - new Card('Бандит', 3), + new PseudoDuck(), + new Lad(), ]; -// Создание игры. const game = new Game(seriffStartDeck, banditStartDeck); -// Глобальный объект, позволяющий управлять скоростью всех анимаций. SpeedRate.set(1); -// Запуск игры. game.play(false, (winner) => { alert('Победил ' + winner.name); });