По легенде некий разработчик решил создать простую RPG игру и решил начать с разработки персонажей. В игре присутствуют различные персонажи Player
со следующими характеристиками:
- жизнь
- мана
- скорость
- атака
- ловкость
- удача
Также реализованы основные персонажи:
- Воин
- Маг
- Лучник
и улучшенные:
- Гном - улучшенный Воин
- Демиург - улучшенный Маг
- Арбалетчик - улучшенный Лучник
У каждого воина в руках есть оружие.
В игре присутствуют меч, лук и посох, а также их улучшенные версии: длинный меч, длинный лук и посох.
Реализован базовый класс Weapon со следующими свойствами:
- name - название
- attack - размер атаки
- durability - прочность
- range - дальность
И методами (действиями оружия):
- Метод takeDamage( damage ), добавляющий повреждение от соперника. Всё повреждение уменьшает значение прочности оружия (свойство durability). Значение durability не должно падать ниже 0.
- Метод getDamage(), рассчитывающий урон от удара данным оружием.
Если прочность оружия (durability) больше или равна 30% от изначального, необходимо выдать значение
свойства attack иначе
attack / 2
. При прочности менее 0, метод возвращает 0. - Метод isBroken(), показывающий, сломано ли оружие. Возвращает false при durability более 0 и true при durability равным 0.
В игре присутствуют базовые и улучшенные оружия
Таблица 1. Классы оружия.
class | name | attack | durability | range |
---|---|---|---|---|
Arm | Рука | 1 | Infinity | 1 |
Bow | Лук | 10 | 200 | 3 |
Sword | Меч | 25 | 500 | 1 |
Knife | Нож | 5 | 300 | 1 |
Staff | Посох | 8 | 300 | 2 |
Таблица 2. Классы усиленного оружия. Прочерк («-») - свойство берётся из наследуемого класса.
class | наследуется от | name | attack | range | durability |
---|---|---|---|---|---|
LongBow | Bow | Длинный лук | 15 | 4 | - |
Axe | Sword | Секира | 27 | - | 800 |
StormStaff | Staff | Посох Бури | 10 | 3 | - |
Реализован базовый класс игрока Player со следующими свойствами и их начальными значениями:
- life = 100 - количество здоровья
- magic = 20 - количество маны
- speed = 1 - скорость
- attack = 10 - уровень атаки
- agility = 5 - ловкость
- luck = 10 - удача
- description = 'Игрок' - тип игрока
- weapon = new Arm() - начальное оружие
- name - имя игрока
- position - положение игрока на оси координат
И методами:
- getLuck(), возвращающий коэффициент удачливости. Метод должен возвращать случайное значение от 0 до 1.
- dodged(), показывающий, получилось ли игроку уклониться от атаки.
Возвращает true в случае, если getLuck() больше значения
(100 - agility - speed * 3) / 100
, в ином случае - false. - isAttackBlocked(), который покажет, получилось ли игроку заблокировать удар
соперника. Возвращает true в случае, если getLuck() больше значения
(100 - luck) / 100
, в ином случае - false. - getDamage(distance), рассчитывающий силу удара по формуле:
(attack + weaponDamage) * getLuck() / distance
. distance - расстояние между игроками, weaponDamage - значение урона текущего оружия у игрока ( weapon.getDamage()). При значении distance, превышающем свойство range оружия, метод возвращает 0. - takeDamage(damage), принимающий полученный урон. Урон полностью вычитается из здоровья персонажа. Значение здоровья персонажа не может падать меньше 0.
- takeAttack(damage), который наносит удар другому игроку.
Работа метода идёт в следующем порядке:
- Если атака была заблокирована (isAttackBlocked), урон приходится по оружию (weapon.takeDamage).
- Если произошло уклонение (dodged), урон не засчитывается
- В иных случаях игрок получает урон, равный damage
- tryAttack(enemy), реализует атаку игроком.
- Рассчитать расстояние между игроком и врагом (distance).
- Если дальность оружия (weapon.range) не достаёт (больше distance) до врага, атака не засчитывается и метод прекращает работу.
- В ином случае записывается износ оружию (weapon.takeDamage) на
10 * getLuck()
- Нанесите урон (getDamage) противнику (enemy.takeAttack)
- Если игроки имеют одно и то же положение (position), атакуемый отскакивает
на 1 деление вправо и принимает урон (enemy.takeAttack) с удвоенной силой (
damage * 2
)
- checkWeapon, реализует проверку поломанности оружия. В случае, если оружие износилось (weapon.isBroken), игрок получает следущее классом ниже. Так, для класса Warrior это будет Sword -> Knife -> Arm. Детали смотрите в колонке «Основное оружие» соответствующего класса. P.S. У всех есть нож и голые руки. Руки не изнашиваются (у него durability = Infinity).
- moveLeft(distance) и moveRight(distance) - методы передвижения. За один вызов игрок может сместиться на расстояние distance, но не более значения свойства speed. moveLeft() уменьшает значение position, moveRight() увеличивает.
- move(distance) - метод передвижения. Если distance меньше нуля, вызывается moveLeft(distance), иначе и moveRight(distance).
- moveToEnemy(enemy), котрый осуществляет движение по направлению к врагу.
- chooseEnemy( players ), где players - массив живых игроков на поле. Метод выбирает для игрока противника с минимальным здоровьем, того кто находится ближе всех.
- turn(players) - каждый ход игрок совершает следующую последовательность действий (именно в таком порядке): выбирает врага, если у бойца нет врага (chooseEnemy), двигается (moveToEnemy), наносит удар (tryAttack).
- isDead(), возвращающий true при уровне жизни, равном 0 и false, если уровень здоровья больше 0.
В игре присутствуют уже готовые персонажи бойцов и их улучшенные версии.
Таблица 3. Классы бойцов. Прочерк («-») - свойство берётся из базового класса.
class | life | magic | speed | attack | agility | luck | description | weapon | Основное оружие |
---|---|---|---|---|---|---|---|---|---|
Warrior | 120 | - | 2 | 10 | - | - | Воин | new Sword | Sword -> Knife -> Arm |
Archer | 80 | 35 | - | 5 | 10 | - | Лучник | new Bow | Bow -> Knife -> Arm |
Mage | 70 | 100 | - | 5 | 8 | - | Маг | new Staff | Staff -> Knife -> Arm |
Таблица 4. Классы улучшенных бойцов. Прочерк («-») - свойство берётся из наследуемого класса.
class | наследуется от | life | magic | speed | attack | agility | luck | description | weapon | Основное оружие |
---|---|---|---|---|---|---|---|---|---|---|
Dwarf | Warrior | 130 | - | - | 15 | - | 20 | Гном | new Axe | Axe -> Knife -> Arm |
Crossbowman | Archer | 85 | - | - | 8 | 20 | 15 | Арбалетчик | new LongBow | LongBow -> Knife -> Arm |
Demiurge | Mage | 80 | 120 | - | 6 | - | 12 | Демиург | new StormStaff | StormStaff -> Knife -> Arm |
- Archer.getDamage(distance): сила удара рассчитывается по формуле
(attack + weaponDamage) * getLuck() * distance / weaponRange
- Warrior.takeDamage(damage): при уровне здоровья менее 50%, getLuck() > 0.8 и достаточном уровне маны, урон вычитается из маны, а не из здоровья. При нулевом значении маны урон вычитается из здоровья.
- Mage.takeDamage(damage): При уровне маны более 50%, маг получает урон в 1.5 раза меньше базового и уменьшает значение маны на 12.
- Dwarf.takeDamage(): Каждый шестой удар соперника наносит в 2 раза меньше урона.
- Demiurge.getDamage(): При уровне маны > 0 и удачи > 0.6, наносимый урон увеличавется в 1.5 раза.
Функция play(players), которая принимает массив игроков. И выполняется до тех пор, пока на поле не останется один игрок. Игра состоит из шагов, где каждый игрок сначала проверяется: живой ли он? Если он мертв, то он удаляется с поля и ход передаётся следующему игроку. Если игрок жив, то выполняется его ход.