Трябва да направите проста 2D конзолна игра, в която ще има герои, врагове, съкровища и магии. Вашият герой ще има възможност да се бие със зли противници, да събира съкровища и да си проправя път през коварни подземия.
Героят трябва да има следните публични методи:
- конструктор, който прима следните аргументи -
String name, int health, int mana String getName()- връща името на герояint getHealth()- връща останалата кръв на герояint getMana()- връща останалата мана на герояboolean isAlive()- връща true, ако кръвта на героя е повече от 0takeHealing(healingPoints)- ако героят е жив, добавяhealingPointsкъм кръвта му, но не повече от началната му кръв. Ако героят не е жив, не прави нищоtakeDamage(damagePoints)- отнема кръв на героя (кръвта не може да бъде по-малко от 0)takeMana(manaPoints)- добавяmanaPointsкъм маната на героя, но не повече от началнатаequip(weapon)- въоръжава героя с това оръжие (заменя го, ако героят има друго). Ако текущото оръжие на героя е по-силно, методът не прави нищо. Първоначално всеки герой е без оръжие.Weapon getWeapon()- връща оръжието на герояlearn(spell)- героят научава магията (заменя текущата, ако тази е по силна). Първоначално всеки герой няма магияSpell getSpell()- връща магиятаint attack()- връща атакуващите точки героя - по-силното от оръжието и магията (за да се използва магия, героят трябва да има поне толкова мана, колкото струва магията. При използване на магия, от маната се отнемат толкова точки, колкото струва магията). Възможно е в даден момент героят да има само оръжие или само магия
Врагът трябва да има следните публични методи:
- конструктор, който прима следните аргументи -
String name, int health, int mana, Weapon weapon, Spell spell String getName()- връща името на врагаint getHealth()- връща останалата кръв на врагаint getMana()- връща останалата мана на врагаboolean isAlive()- връща true, ако кръвта на врага е повече от 0Weapon getWeapon()- връща оръжието на врагаSpell getSpell()- връща магията на врагаtakeDamage(damagePoints)- отнема кръв на врага (кръвта не може да бъде по-малко от 0)int attack()- връща атакуващите точки врага - по-силното от оръжието и магията (за да се използва магия, врагът трябва да има поне толкова мана, колкото струва магията. При използване на магия, от маната се отнемат толкова точки, колкото струва магията). Възможно е в даден момент врагът да има само оръжие или само магия
Всички артефакти (Оръжие, Магия, Отвара за кръв и Отвара за мана) трябва да имплементират интерфейса Treasure
Оръжието трябва да има следните публични методи:
- конструктор, който прима следните аргументи -
String name, int damage String getName()- връща името на оръжиетоint getDamage()- връща атаката на оръжиетоString collect(Hero)- въоръжава героя с това оръжие (ако то е по-силно от текущото) и връщаString, съдържащ "Weapon found! Damage points: X", където X е атаката на оръжието
Магията трябва да има следните публични методи:
- конструктор, който прима следните аргументи -
String name, int damage, int manaCost String getName()- връща името на магиятаint getDamage()- връща атаката на магиятаint getManaCost()- връща цената (в мана) на магиятаString collect(Hero)- героят научава магията (ако тя е по-силна) и връщаString, съдържащ "Spell found! Damage points: X, Mana cost: Y", където X е атаката на магията, а Y е цената на магията
- конструктор, който прима следните аргументи -
int healingPoints int heal()- връща точките кръв, които отварата добавяString collect(Hero)- към точките кръв се добавят тези от колбата с отварата (кръвта на героя не може да стане повече от началната; ако героят е с 0 кръв, колбата не прави нищо) и връщаString, съдържащ "Health potion found! X health points added to your hero!", където X са точките кръв, които съдържа отварата (може да се различават от реално добавените към кръвта на героя)
- конструктор, който прима следните аргументи -
int manaPoints int heal()- връща точките мана, които отварата добавяString collect(Hero)- към точките мана се добавят тези от колбата с мана (маната на героя не може да стане повече от началната) и връщаString, съдържащ "Mana potion found! X mana points added to your hero!", където X са точките мана, които съдържа отварата (може да се различават от реално добавените към маната на героя)
Ще ни е нужно подземие, където нашият герой ще се бие с врагове, ще намира могъщи оръжия, магии и отвари.
Подземието ще бъде 2D карта, която изглежда по следния начин:
S . ## . . . . . T
#T## . . ### .
# . ###E###E
# . E . . . ### .
###T#####G
където:
- S - Стартовата позиция, от която тръгва нашият герой.
- H - Текущата позицията на героя.
- # - Препятствие, през което нашият герой не може да минава.
- T - Съкровище.
- . - Пътят, през който нашият герой трябва да излезе от подземието.
- Е - Врагът.
- G - Изходът от подземието.
Ще трябва да имплементирате и логиката на играта, като за целта ще трябва да реализирате GameEngine класа.
GameEngine класът трябва да има следните публични методи:
- конструктор, който прима следните аргументи -
char[][] map, Hero hero, Enemy[] enemies, Treasure[] treasures char[][] getMap()- връща текущото състояние на картатаHero getHero()- връща героя.Position getHeroPosition()- връща текущата позиция на герояString makeMove(Direction direction)- къдетоdirectionе посоката на движение на героя.- ако при извикването на метода клетката е свободна - героят се отмества на тази клетка и се връща съобщението "You moved successfully to the next position."
- след преместване на героя на следващата позиция, позицията на която героят е бил се заменя с "."
- ако при извикването на метода клетката е с препятствие - героят запазва старата си позиция и се връща съобщението "Wrong move. There is an obstacle and you cannot bypass it."
- ако при извикването на метода клетката е със съкровище - съкровището се премахва от картата, първото невзето съкровище от масива със съкровища бива взето от героя, героят премества позицията си на мястото на позицията на съкровището и се връща съобщението от съответното съкровище.
- ако при извикването на метода клетката е с враг, започва битка между героя и първия непобеден враг от масива с врагове. Логиката зад битката е следната - първо атакува героят, като от точките живот на врага се отнемат точките на атака на героя; След това атакува врагът (ако още е жив) - от точките живот на героя се отнемат атакуващите точки на врага. Действието се повтаря докато точките живот на героя или врага станат 0. При победа на героя, той заема (маркира със символа си) клетката на врага, а предишната му позиция се замества с '.' и се връща "Enemy died.", а при загуба "Hero is dead! Game over!"
- ако при извикването на метода клетката е изхода на подземието, играта приключва и се връща съобщението "You have successfully passed through the dungeon. Congrats!"
- ако при извикването на метода командата не е от валидните, да се върне съобщението "Unknown command entered."
- Интерфейсът
Actorи класоветеEnemy,HeroиPositionтрябва да са в пакетbg.sofia.uni.fmi.mjt.dungeon.actor - Интерфейсът
Treasureи класоветеHealthPotion,ManaPotion,SpellиWeaponтрябва да са в пакетbg.sofia.uni.fmi.mjt.dungeon.treasure - Класът
GameEngineи Enum-ътDirectionтрябва да се намират в пакетbg.sofia.uni.fmi.mjt.dungeon - Добра практика за чист код и добър ООП дизайн е една функция да не променя състоянието на обекти, получила от външния свят.
За всички допълнителни интерфейси и класове (т.е. неспоменати изрично в условието), които бихте добавили, пакетът е по ваша преценка.