Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Бурдин Д #39

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Chrome уже поддерживает использование модулей
Инструктаж окончен. Твоя задача - создавать новые типы карт, наследующиеся от Card. Можешь приступать к решению задачи!


1. «Классы»
+++1. «Классы»
Во всем коде типы определены по-старому, через прототипы.
Изоляция кода при этом обеспечивает за счет техники IIFE:
https://developer.mozilla.org/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/IIFE
Expand All @@ -53,10 +53,10 @@ Chrome уже поддерживает использование модулей
Результат будет тот же, но запись будет более лаконичной.

Чтобы лучше понять разницу между старым и новым синтаксисом перепиши `TaskQueue` с использованием `class` и без IIFE:
- Убери обрамляющую определение `TaskQueue` самовызывающуюся функцию.
- Перенеси вверх функцию `runNextTask`, потому что это не метод `TaskQueue`.
- Объяви тип `TaskQueue` с помощью инструкции `class`, определи constructor и все методы.
- `export default` поставь сразу перед инструкции `class`.
++- Убери обрамляющую определение `TaskQueue` самовызывающуюся функцию.
++- Перенеси вверх функцию `runNextTask`, потому что это не метод `TaskQueue`.
++- Объяви тип `TaskQueue` с помощью инструкции `class`, определи constructor и все методы.
++- `export default` поставь сразу перед инструкции `class`.

Пример перехода от старого синтаксиса к новому:

Expand Down Expand Up @@ -98,7 +98,7 @@ function secret(value) {
```


2. «Утки против собак»
+++2. «Утки против собак»
Создай в `index.js` две новые карты, используй `class` и унаследовав их от `Card`:
- `Duck` с именем «Мирная утка» и силой 2
- `Dog` с именем «Пес-бандит» и силой 3
Expand All @@ -111,11 +111,11 @@ https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes#%D0%9D%D0

Не забудь вызвать базовый конструктор `Card` с помощью `super`!

- Новые карты должны создаваться, даже если им не передать параметров: `new Duck()` и `new Dog()`.
- Методы `quacks` и `swims` утки должны создаваться на уровне класса, а не добавляться в конструкторе.
- После добавления новых типов замени карты в колоде шерифа на уток, а в колоде бандита - на собак.
- Функция `isDuck` должна возвращать `true` для утки, а функция `isDog` — для собаки.
- Если все сделано правильно, то внизу карты утки должен быть текст Duck➔ Card, а у собаки Dog➔ Card.
++- Новые карты должны создаваться, даже если им не передать параметров: `new Duck()` и `new Dog()`.
++- Методы `quacks` и `swims` утки должны создаваться на уровне класса, а не добавляться в конструкторе.
++ После добавления новых типов замени карты в колоде шерифа на уток, а в колоде бандита - на собак.
++- Функция `isDuck` должна возвращать `true` для утки, а функция `isDog` — для собаки.
++- Если все сделано правильно, то внизу карты утки должен быть текст Duck➔ Card, а у собаки Dog➔ Card.

Колоды для проверки:
```js
Expand All @@ -130,12 +130,12 @@ const banditStartDeck = [
```


3. «Утка или собака?»
+++3. «Утка или собака?»
Метод `getDescriptions` в `Card` создан для того, чтобы на картах появлялась дополнительная информация.
Его функционал хочется расширить. Причем так, чтобы это работало и для уток, и для собак,
и для всех остальных существ, которые будут добавляться.

- Создай новый тип `Creature` и унаследуй его от `Card`.
++- Создай новый тип `Creature` и унаследуй его от `Card`.
- Сделай так, чтобы `Duck` и `Dog` наследовались от `Creature`.
- Переопредели в классе `Creature` реализацию `getDescriptions` на новую.
Теперь в ней должны возвращаться две строки описания в виде массива.
Expand All @@ -157,7 +157,7 @@ const banditStartDeck = [
а у собак надпись «Собака» над цепочкой наследования.


4. «Громила»
+++4. «Громила»
Для уток все становится плохо, когда в рядах бандитов появляется Громила.

Добавь карту `Trasher`:
Expand Down Expand Up @@ -192,7 +192,7 @@ const banditStartDeck = [
```


5. «Гатлинг»
+++5. «Гатлинг»
Нехорошо нападать на мирных жителей. Это еще может быть опасно, если в сарае припрятан Гатлинг.

Добавь карту `Gatling`:
Expand Down Expand Up @@ -222,7 +222,7 @@ const banditStartDeck = [
```


6. «Братки»
+++6. «Братки»
Чем их больше, тем они сильнее.

Добавь карту `Lad`:
Expand Down
63 changes: 30 additions & 33 deletions src/TaskQueue.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
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);
}
}

export default 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});
} else {
Expand All @@ -19,37 +43,10 @@ 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;
148 changes: 137 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SpeedRate from './SpeedRate.js';

// Отвечает является ли карта уткой.
function isDuck(card) {
return card && card.quacks && card.swims;
return card instanceof Duck;
}

// Отвечает является ли карта собакой.
Expand All @@ -27,30 +27,156 @@ function getCreatureDescription(card) {
return 'Существо';
}


class Creature extends Card {
constructor(name, maxPower) {
super(name, maxPower)
}
getDescriptions() {
let res = [];
res.push(getCreatureDescription(this));
res.push(super.getDescriptions())
return res;
}
}

// Основа для утки.
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() {
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() {
super('Громила', 5);
}


modifyTakenDamage(value, fromCard, gameContext, continuation) {
if (value > 1) {
this.view.signalAbility(() => super.modifyTakenDamage(value - 1, fromCard, gameContext, continuation));
} else {
this.view.signalAbility(continuation);
}
}

getDescriptions() {
return [
"Громила получает на 1 меньше урона",
...super.getDescriptions(),
];
}
}

class Gatling extends Creature{
constructor() {
super('Гатлинг', 6);
}

attack(gameContext, continuation) {
const taskQueue = new TaskQueue();

const {currentPlayer, oppositePlayer, position, updateView} = gameContext;
for(let e of oppositePlayer.table) {
if(e) {
taskQueue.push(onDone => this.view.showAttack(onDone));
taskQueue.push(onDone => this.dealDamageToCreature(2, e, gameContext, onDone));
}
}
taskQueue.continueWith(continuation);
console.log(Lad.countLad)
}
}

class Lad extends Dog {
constructor() {
super('Браток', 2);
}

static get InGameCount() { return this.inGameCount || 0; }

static set InGameCount(value) { this.inGameCount = value; }

static getBonus() {
return this.InGameCount * (this.InGameCount + 1) / 2;
}

doAfterComingIntoPlay(gameContext, continuation) {
Lad.InGameCount++;
continuation();
}

doBeforeRemoving(continuation) {
Lad.InGameCount--;
continuation();
}

modifyDealedDamageToCreature(value, toCard, gameContext, continuation) {
this.view.signalAbility(() => {
continuation(value + Lad.getBonus());
})
}

modifyTakenDamage(value, fromCard, gameContext, continuation) {
this.view.signalAbility(() => {
continuation(value - Lad.getBonus());
})
}

getDescriptions() {
let description = super.getDescriptions();
if (Lad.prototype.hasOwnProperty('modifyDealedDamageToCreature') && Lad.prototype.hasOwnProperty('modifyTakenDamage')) {
description.unshift('Чем больше братков находится в игре, тем больше урона без потерь поглощается' +
' и больше урона по картам наносится каждым из них');
}
return description;
}
}

class Rogue extends Creature {
constructor() {
super('Изгой', 2);
}
}

class Brewer extends Duck {
constructor() {
super('Пивозавр', 2);
}


}




// Колода Шерифа, нижнего игрока.
const seriffStartDeck = [
new Card('Мирный житель', 2),
new Card('Мирный житель', 2),
new Card('Мирный житель', 2),
new Duck(),
new Duck(),
new Duck(),

];

// Колода Бандита, верхнего игрока.
const banditStartDeck = [
new Card('Бандит', 3),
new Lad(),
new Lad(),
];


Expand Down