+ Added Armors

+ Added Weapons
+ Added REPORT.md
+ Finished the classes
+ (fix) Fixed problems caused by class hierarchy
- (todo) main loop, key mechanic.
This commit is contained in:
2026-05-10 17:38:01 +03:30
parent 4e8daa6655
commit deb26fc24f
25 changed files with 305 additions and 116 deletions
@@ -1,15 +1,71 @@
package org.project;
import org.project.entity.enemies.Dragon;
import org.project.location.Location;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Main {
// Colors
private static final String RESET = "\u001B[0m"; // Reset ANSI code
private static final String RED = "\u001B[31m";
private static final String GREEN = "\u001B[32m";
private static final String YELLOW = "\u001B[33m";
private static final String BLUE = "\u001B[34m";
private static final String PURPLE = "\u001B[35m";
public static void main(String[] args) {
// TODO: ADD LOCATIONS TO YOUR GAME
// Scanner
Scanner scanner = new Scanner(System.in);
Random random1 = new Random(112233); // for initial location
Random random2 = new Random(123123); // to choose enemy
// Note : seed numbers don't mean anything (They are just magical numbers)
List<Location> locations = new ArrayList<>();
Location castle = new Location("Castle", new Dragon());
Location forest = new Location("Forest");
Location ruins = new Location("Ruins");
Location village = new Location("Village");
locations.add(castle);
locations.add(forest);
locations.add(ruins);
locations.add(village);
int randNum1 = random1.nextInt() % 3;
int randNum2 = random2.nextInt() % 3;
Location initialPlayerLoc = locations.get(randNum1 + 1); // since the index 0 : castle can't be the player initial location.
// Main loop
boolean isRunning = true;
while (isRunning){
System.out.println(YELLOW + "------------------Legend of AP------------------" + RESET);
System.out.println(" Choose your option :");
System.out.println(BLUE + " 1." + RESET + " Start a new game");
System.out.println(BLUE + " 2." + RESET + " Exit");
int option = scanner.nextInt();
switch (option){
case 1:
case 2:
System.out.println("Goodbye!");
isRunning = false;
break;
default:
continue;
}
}
// TODO: IMPLEMENT GAMEPLAY
}
}
@@ -1,42 +1,24 @@
package org.project.entity;
import org.project.entity.players.Player;
public abstract class Entity {
void takeDamage(int damage){};
void specialAbility(Entity target){};
void stun(){};
public abstract void stun(boolean value);
void makeCritical(boolean value){};
boolean isStunned(){};
public abstract void setHp(int newHp);
boolean isCritical(){};
public abstract boolean isCritical();
public abstract boolean isStunned();
boolean isDead(){};
public abstract void makeCritical(boolean value);
void makeDie(){};
public abstract void makeDie();
void setHp(int hp){};
public abstract void takeDamage(int damage);
void stun(boolean value){};
public abstract boolean isDead();
public abstract boolean isDead();
public abstract void heal(int health);
}
@@ -1,22 +1,21 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.item.weapons.DragonBreath;
import org.project.item.weapons.Weapon;
public class Dragon extends Enemy{
public Dragon(int hp, Weapon weapon){
super(hp, weapon);
private static final int HP = 600;
public Dragon(){
Weapon dragonBreath = new DragonBreath();
super(HP, dragonBreath);
}
@Override
public void specialAbility(Entity target) {
Player targetPlayer = (Player)target;
if (targetPlayer.isDefending()){
targetPlayer.breakShield();
}
super.attack(targetPlayer);
public void specialAbility(Player target) {
target.breakShield();
super.attack(target);
}
}
@@ -1,9 +1,10 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.item.weapons.Weapon;
public abstract class Enemy implements Entity {
public abstract class Enemy extends Entity {
Weapon weapon;
private int hp;
private boolean stunned = false;
@@ -26,6 +27,10 @@ public abstract class Enemy implements Entity {
}
}
@Override
public void heal(int health) {
hp += health;
}
@Override
public void takeDamage(int damage) {
@@ -53,7 +58,9 @@ public abstract class Enemy implements Entity {
}
@Override
public boolean isCritical(){ return critical;}
public boolean isCritical(){
return critical;
}
@Override
public boolean isStunned() {
@@ -73,5 +80,5 @@ public abstract class Enemy implements Entity {
return weapon;
}
public abstract void specialAbility(Entity target);
public abstract void specialAbility(Player target);
}
@@ -3,25 +3,28 @@ package org.project.entity.enemies;
import java.util.Random;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.item.weapons.Dagger;
import org.project.item.weapons.Weapon;
public class Goblin extends Enemy{
private static final Random random = new Random();
private static final int HEALTH_POINT = 100;
public Goblin(int mp, Weapon weapon){
super(HEALTH_POINT, weapon);
public Goblin(){
Weapon goblinDagger = new Dagger();
super(HEALTH_POINT, goblinDagger);
}
@Override
public void specialAbility(Entity target) {
public void specialAbility(Player target) {
this.criticality();
super.attack(target);
}
// makes the next move critical with a probability of 80
private void criticality(){
Random random = new Random();
int randNum = random.nextInt(100);
if (randNum < 80){
this.makeCritical(true);
@@ -1,21 +1,28 @@
package org.project.entity.enemies;
import org.project.entity.players.Player;
import org.project.item.weapons.Dagger;
import org.project.item.weapons.Weapon;
public class Skeleton extends Enemy {
private static final int HP = 100;
private int deathCounter = 0;
private int initialHp;
public Skeleton(int hp, Weapon weapon){
super(hp,weapon);
initialHp = hp;
public Skeleton(){
Weapon skeletonDagger = new Dagger();
super(HP,skeletonDagger);
}
@Override
public void specialAbility(Player target) {
super.attack(target);
}
@Override
public void makeDie() {
if (deathCounter == 0){
this.setHp(initialHp / 2);
this.setHp(HP / 2);
deathCounter++;
return;
}
@@ -1,19 +1,21 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.item.weapons.Weapon;
public class Vampire extends Enemy{
private static final int SPECIAL_ABL_DMG = 40;
private static final int RANDEMANT_PERCENT = 70; // this constant determines how much of dealt damage should be given to vamp.
private static final int HP = 350;
public Vampire(int hp, Weapon weapon){
super(hp, weapon);
public Vampire(){
super(HP, null); // vampire doesn't need a weapon.
}
@Override
public void specialAbility(Entity target) {
public void specialAbility(Player target) {
System.out.println("Stealing life!...");
target.takeDamage(SPECIAL_ABL_DMG);
this.heal((SPECIAL_ABL_DMG * RANDEMANT_PERCENT) / 100);
@@ -1,18 +1,27 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.entity.enemies.Enemy;
import org.project.item.armors.Armor;
import org.project.item.armors.AssasinArmor;
import org.project.item.weapons.LightSaber;
import org.project.item.weapons.Weapon;
public class Assassin extends Player{
public Assassin(String name, int hp, int mp, Weapon weapon, Armor armor){
super(name, hp, mp, weapon, armor, 300,50);
private static final int MAX_HP = 300;
private static final int MAX_MP = 50;
public Assassin(String name){
Weapon assassinSaber = new LightSaber("Green"); // idk why but i gave assassin a light saber.
Armor assassinArmor = new AssasinArmor();
super(name, MAX_HP, MAX_MP, assassinSaber, assassinArmor, MAX_HP,MAX_MP);
}
@Override
public void specialAbility(Entity target) {
public void specialAbility(Enemy target) {
System.out.println("Turning invisible...");
this.defend();
this.makeCritical(true);
}
}
@@ -1,21 +1,27 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.entity.enemies.Enemy;
import org.project.item.armors.Armor;
import org.project.item.armors.KnightArmor;
import org.project.item.weapons.Sword;
import org.project.item.weapons.Weapon;
// TODO: UPDATE IMPLEMENTATION
public class Knight extends Player {
public Knight(String name, int hp, int mp, Weapon weapon, Armor armor){
super(name, hp, mp, weapon, armor, 400,40);
private static final int MAX_HP = 400;
private static final int MAX_MP = 40;
public Knight(String name){
Weapon knightSword = new Sword();
Armor knightArmor = new KnightArmor();
super(name, MAX_HP, MAX_MP, knightSword, knightArmor, MAX_HP,MAX_MP);
}
@Override
public void specialAbility(Entity target) {
public void specialAbility(Enemy target) {
System.out.println("Performing shield bash...");
target.stun(true);
target.takeDamage(50);
}
@@ -1,10 +1,11 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.entity.enemies.Enemy;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
public abstract class Player implements Entity {
public abstract class Player extends Entity {
protected String name;
Weapon weapon;
Armor armor;
@@ -12,8 +13,8 @@ public abstract class Player implements Entity {
private int maxHP;
private int mp;
private int maxMP;
private boolean isDefending = false;
private boolean stunned = false;
private boolean isDefending = false;
private boolean critical = false;
private boolean dead = false;
@@ -71,6 +72,7 @@ public abstract class Player implements Entity {
public void takeDamage(int damage) {
if (!isDefending) {
hp -= damage - armor.getDefense();
armor.use();
}
else {
System.out.println("Defended the attack.");
@@ -79,6 +81,7 @@ public abstract class Player implements Entity {
}
@Override
public void heal(int health) {
mp -= HEAL_MP_COST;
hp += health;
@@ -93,7 +96,7 @@ public abstract class Player implements Entity {
mp = maxMP;
}
}
@Override
public void makeCritical(boolean value) {
critical = value;
@@ -104,9 +107,26 @@ public abstract class Player implements Entity {
dead = true;
}
public abstract void specialAbility(Enemy target);
@Override
public void stun(boolean value) {
stunned = value;
}
@Override
public void setHp(int newHp) {
hp = newHp;
}
@Override
public boolean isCritical(){ return critical;}
@Override
public boolean isStunned() {
return stunned;
}
public String getName() {
return name;
}
@@ -1,19 +1,29 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.entity.enemies.Enemy;
import org.project.item.armors.Armor;
import org.project.item.armors.WizardArmor;
import org.project.item.weapons.FireBall;
import org.project.item.weapons.Weapon;
public class Wizard extends Player{
public Wizard(String name, int hp, int mp, Weapon weapon, Armor armor){
super(name, hp, mp, weapon, armor, 500,30);
private static final int MAX_HP = 500;
private static final int MAX_MP = 30;
private static final int SPELL_DAMAGE = 40;
private static final int SPELL_HEAL_AMOUNT = 20;
public Wizard(String name ){
Weapon wizardWeapon = new FireBall();
Armor wizardArmor = new WizardArmor();
super(name, MAX_HP, MAX_MP, wizardWeapon, wizardArmor, MAX_HP, MAX_MP);
}
@Override
public void specialAbility(Entity target) {
public void specialAbility(Enemy target) {
System.out.println("Casting spell...");
target.takeDamage(30);
this.heal(10);
target.takeDamage(SPELL_DAMAGE);
this.heal(SPELL_HEAL_AMOUNT);
}
}
@@ -1,11 +0,0 @@
package org.project.item;
import org.project.entity.Entity;
public interface Item {
void use(Entity target);
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
@@ -1,33 +1,31 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Armor {
private int defense;
private int maxDefense;
private int durability;
private int maxDurability;
private int durabilityCost;
private boolean isBroke;
public Armor(int defense, int durability) {
public Armor(int defense, int durability, int durabilityCost) {
this.defense = defense;
this.durability = durability;
this.durabilityCost = durabilityCost;
}
public void checkBreak() {
public void use(){
durability -= durabilityCost;
checkBreak();
}
private void checkBreak() {
if (durability <= 0) {
isBroke = true;
durability = 0;
defense = 0;
}
}
// TODO: (BONUS) UPDATE THE REPAIR METHOD
public void repair() {
isBroke = false;
defense = maxDefense;
durability = maxDurability;
}
public int getDefense() {
return defense;
}
@@ -0,0 +1,11 @@
package org.project.item.armors;
public class AssasinArmor extends Armor{
private static final int DURABILITY = 75;
private static final int DEFENSE = 20;
private static final int SINGLE_DEFENSE_COST = 25;
public AssasinArmor(){
super(DEFENSE,DURABILITY,SINGLE_DEFENSE_COST);
}
}
@@ -1,6 +1,11 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public class KnightArmor extends Armor{
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
private static final int DURABILITY = 100;
private static final int DEFENSE = 30;
private static final int SINGLE_DEFENSE_COST = 25;
public KnightArmor(){
super(DEFENSE,DURABILITY,SINGLE_DEFENSE_COST);
}
}
@@ -0,0 +1,11 @@
package org.project.item.armors;
public class WizardArmor extends Armor{
private static final int DURABILITY = 50;
private static final int DEFENSE = 15;
private static final int SINGLE_DEFENSE_COST = 25;
public WizardArmor(){
super(DEFENSE,DURABILITY,SINGLE_DEFENSE_COST);
}
}
@@ -9,8 +9,8 @@ public class Flask extends Consumable {
*/
// TODO: UPDATE USE METHOD
@Override
public void use(Entity target) {
target.heal(target.getMaxHP() / 10);
}
// @Override
// public void use(Entity target) {
// target.heal(target.getMaxHP() / 10);
// }
}
@@ -0,0 +1,9 @@
package org.project.item.weapons;
public class Dagger extends Weapon{
private static final int DAMAGE = 25;
public Dagger(){
super(DAMAGE, 0); // the dagger is only meant to get used by skeleton and goblin, hence it doesen't use mana.
}
}
@@ -0,0 +1,9 @@
package org.project.item.weapons;
public class DragonBreath extends Weapon{
public static final int DAMAGE = 200;
public DragonBreath(){
super(DAMAGE, 0);
}
}
@@ -0,0 +1,10 @@
package org.project.item.weapons;
public class FireBall extends Weapon{
private static final int DAMAGE = 35;
private static final int MANA_COST = 8;
public FireBall() {
super(DAMAGE,MANA_COST);
}
}
@@ -0,0 +1,12 @@
package org.project.item.weapons;
public class LightSaber extends Weapon{ // xD
private static final int DAMAGE = 60;
private static final int MANA_COST = 9;
private String color; // color has no purpose at all, i just made it for fun.
public LightSaber(String color){
this.color = color;
super(DAMAGE,MANA_COST);
}
}
@@ -4,14 +4,13 @@ import org.project.entity.Entity;
import java.util.ArrayList;
// TODO: UPDATE IMPLEMENTATION
public class Sword extends Weapon {
private static final int DAMAGE = 50;
private static final int MANA_COST
private static final int MANA_COST = 8;
public Sword(int damage, int manaCost) {
super(damage, manaCost);
public Sword() {
super(DAMAGE,MANA_COST);
}
}
@@ -1,19 +1,12 @@
package org.project.item.weapons;
import org.project.entity.Entity;
public abstract class Weapon {
private int damage;
private int manaCost;
public Weapon(int damage, int manaCost) {
this.damage = damage;
this.manaCost = manaCost;
}
@Override
public void use(Entity target) {
target.takeDamage(damage);
public Weapon(int dmg, int mpCost) {
this.damage = dmg;
this.manaCost = mpCost;
}
public int getDamage() {
@@ -6,23 +6,35 @@ import java.util.ArrayList;
public class Location {
private String name;
private Enemy enemy;
private ArrayList<Enemy> enemies;
public Location(String name) {
this.name = name;
this.enemy = null;
}
public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies) {
this.locations = locations;
this.enemies = enemies;
public Location(String name, Enemy enemy) {
this.name = name;
this.enemy = enemy;
}
public String getName() {
return name;
}
public ArrayList<Location> getLocations() {
return locations;
public Enemy getEnemy() {
return enemy;
}
public ArrayList<Enemy> getEnemies() {
return enemies;
public void setEnemy(Enemy enemy) {
this.enemy = enemy;
}
}
public boolean hasEnemy() {
return enemy != null && !enemy.isDead();
}
public void clearEnemy() {
this.enemy = null;
}
}