feat : implement Java Knight game

This commit is contained in:
amirM.t
2026-05-11 21:12:18 +03:30
parent 78d4bedb08
commit 1e239ee39c
22 changed files with 1050 additions and 396 deletions
@@ -1,15 +1,13 @@
package org.project;
import org.project.location.Location;
import org.project.game.Game;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// TODO: ADD LOCATIONS TO YOUR GAME
List<Location> locations = new ArrayList<>();
// TODO: IMPLEMENT GAMEPLAY
public class Main
{
public static void main(String[] args)
{
Game game = new Game();
game.start();
}
}
}
@@ -1,21 +1,9 @@
package org.project.entity;
public interface Entity {
void attack(Entity target);
void defend();
void heal(int health);
void fillMana(int mana);
void takeDamage(int damage);
int getMaxHP();
int getMaxMP();
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
public interface Entity
{
String getName();
int getHealth();
int getMaxHealth();
boolean isAlive();
}
@@ -0,0 +1,12 @@
package org.project.entity.actions;
import org.project.entity.enemies.Enemy;
public interface ICombatActions
{
void lightAttack(Enemy enemy);
void heavyAttack(Enemy enemy);
void defend();
void heal();
void specialAbility(Enemy enemy);
}
@@ -0,0 +1,20 @@
package org.project.entity.enemies;
import org.project.entity.players.Player;
import org.project.utilities.Colors;
public class Dragon extends Enemy
{
public Dragon()
{
super("Dragon", 250, 30, 200);
}
@Override
public void attack(Player player)
{
System.out.println(Colors.RED + "🐉 Dragon used Fiery Breath!" + Colors.RESET);
player.takeDamage(damage);
}
}
@@ -1,34 +1,76 @@
package org.project.entity.enemies;
import org.project.item.weapons.Weapon;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.utilities.Colors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Enemy {
Weapon weapon;
private int hp;
private int mp;
public abstract class Enemy implements Entity
{
protected String name;
protected int maxHealth;
protected int health;
protected int damage;
protected int xpReward;
public Enemy(int hp, int mp, Weapon weapon) {
this.hp = hp;
this.mp = mp;
protected boolean stunned = false;
this.weapon = weapon;
public Enemy(String name, int maxHealth, int damage, int xpReward)
{
this.name = name;
this.maxHealth = maxHealth;
this.health = maxHealth;
this.damage = damage;
this.xpReward = xpReward;
}
public abstract void attack(Player player);
public void takeDamage(int amount)
{
health -= amount;
if (health < 0)
health = 0;
System.out.println(Colors.RED + name + " took " + amount + " damage!" + Colors.RESET);
}
public int getXpReward()
{
return xpReward;
}
public void setStunned(boolean stunned)
{
this.stunned = stunned;
}
public boolean isStunned()
{
return stunned;
}
@Override
public void takeDamage(int damage) {
hp -= damage;
public String getName()
{
return name;
}
public int getHp() {
return hp;
@Override
public int getHealth()
{
return health;
}
public int getMp() {
return mp;
@Override
public int getMaxHealth()
{
return maxHealth;
}
public Weapon getWeapon() {
return weapon;
@Override
public boolean isAlive()
{
return health > 0;
}
}
@@ -0,0 +1,30 @@
package org.project.entity.enemies;
import org.project.entity.players.Player;
import org.project.utilities.Colors;
import java.util.Random;
public class Goblin extends Enemy
{
Random random = new Random();
public Goblin()
{
super("Goblin", 60, 12, 25);
}
@Override
public void attack(Player player)
{
int dmg = damage;
if (random.nextInt(100) < 40)
{
dmg *= 2;
System.out.println(Colors.RED + "👹 Goblin landed CRITICAL HIT!" + Colors.RESET);
}
player.takeDamage(dmg);
}
}
@@ -1,6 +1,37 @@
package org.project.entity.enemies;
// TODO: UPDATE IMPLEMENTATION
public class Skeleton {
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
import org.project.entity.players.Player;
import org.project.utilities.Colors;
public class Skeleton extends Enemy
{
private boolean resurrected = false;
public Skeleton()
{
super("Skeleton", 80, 14, 35);
}
@Override
public void attack(Player player)
{
player.takeDamage(damage);
}
@Override
public boolean isAlive()
{
if (health <= 0 && !resurrected)
{
resurrected = true;
health = maxHealth / 2;
System.out.println(Colors.PURPLE + "☠️ Skeleton resurrected!" + Colors.RESET);
return true;
}
return health > 0;
}
}
@@ -0,0 +1,26 @@
package org.project.entity.enemies;
import org.project.entity.players.Player;
import org.project.utilities.Colors;
public class Vampire extends Enemy {
public Vampire()
{
super("Vampire", 90, 16, 45);
}
@Override
public void attack(Player player)
{
player.takeDamage(damage);
health += 8;
if (health > maxHealth)
health = maxHealth;
System.out.println(Colors.GREEN + "🦇 Vampire drained life!" + Colors.RESET);
}
}
@@ -0,0 +1,84 @@
package org.project.entity.players;
import org.project.entity.enemies.Enemy;
import org.project.utilities.Colors;
public class Assassin extends Player
{
public Assassin(String name)
{
super(name, 100, 120, 16);
}
@Override
public String getClassName()
{
return "Assassin";
}
@Override
public void lightAttack(Enemy enemy)
{
int dmg = damage;
if (criticalNext)
{
dmg *= 2;
criticalNext = false;
System.out.println(Colors.RED + "CRITICAL HIT!" + Colors.RESET);
}
enemy.takeDamage(dmg);
}
@Override
public void heavyAttack(Enemy enemy)
{
if (mana < 10) return;
mana -= 10;
enemy.takeDamage(damage + 14);
}
@Override
public void defend()
{
if (mana < 8) return;
mana -= 8;
defending = true;
System.out.println("🗡️ Assassin prepares to evade!");
}
@Override
public void heal()
{
if (mana < 12) return;
mana -= 12;
health += 18;
if (health > maxHealth)
health = maxHealth;
System.out.println(Colors.GREEN + "Assassin healed!" + Colors.RESET);
}
@Override
public void specialAbility(Enemy enemy)
{
if (mana < 20) return;
mana -= 20;
invisible = true;
criticalNext = true;
System.out.println(Colors.PURPLE + "👻 Assassin became invisible!" + Colors.RESET);
}
}
@@ -1,6 +1,76 @@
package org.project.entity.players;
// TODO: UPDATE IMPLEMENTATION
public class Knight {
// TODO: DESIGN KNIGHT'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR
import org.project.entity.enemies.Enemy;
import org.project.utilities.Colors;
public class Knight extends Player
{
public Knight(String name)
{
super(name, 120, 70, 18);
}
@Override
public String getClassName()
{
return "Knight";
}
@Override
public void lightAttack(Enemy enemy)
{
System.out.println("⚔️ Knight used Light Attack!");
enemy.takeDamage(damage);
}
@Override
public void heavyAttack(Enemy enemy)
{
if (mana < 10) return;
mana -= 10;
System.out.println("⚔️ Knight used Heavy Attack!");
enemy.takeDamage(damage + 10);
}
@Override
public void defend()
{
if (mana < 8) return;
mana -= 8;
defending = true;
System.out.println("🛡️ Knight is defending!");
}
@Override
public void heal()
{
if (mana < 12) return;
mana -= 12;
health += 20;
if (health > maxHealth)
health = maxHealth;
System.out.println(Colors.GREEN + "Knight healed!" + Colors.RESET);
}
@Override
public void specialAbility(Enemy enemy)
{
if (mana < 18) return;
mana -= 18;
enemy.takeDamage(damage + 20);
enemy.setStunned(true);
System.out.println(Colors.PURPLE + "⚔️ SHIELD BASH! Enemy stunned!" + Colors.RESET);
}
}
@@ -1,89 +1,146 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
import org.project.entity.actions.ICombatActions;
import org.project.utilities.Colors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Player {
import java.util.*;
public abstract class Player implements Entity, ICombatActions
{
protected String name;
Weapon weapon;
Armor armor;
private int hp;
private int maxHP;
private int mp;
private int maxMP;
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
protected int maxHealth;
protected int health;
protected int maxMana;
protected int mana;
protected int damage;
protected int level = 1;
protected int xp = 0;
protected boolean defending = false;
protected boolean invisible = false;
protected boolean criticalNext = false;
protected Set<String> keys = new HashSet<>();
public Player(String name, int maxHealth, int maxMana, int damage)
{
this.name = name;
this.hp = hp;
this.mp = mp;
this.maxHealth = maxHealth;
this.health = maxHealth;
this.weapon = weapon;
this.armor = armor;
this.maxMana = maxMana;
this.mana = maxMana;
this.damage = damage;
}
@Override
public void attack(Entity target) {
target.takeDamage(weapon.getDamage());
}
public abstract String getClassName();
@Override
public void defend() {
// TODO
}
@Override
public void takeDamage(int damage) {
hp -= damage - armor.getDefense();
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
public void takeDamage(int amount)
{
if (invisible)
{
System.out.println(Colors.PURPLE + "Attack dodged due to invisibility!" + Colors.RESET);
invisible = false;
return;
}
if (defending)
{
amount /= 2;
defending = false;
}
health -= amount;
if (health < 0)
health = 0;
System.out.println(Colors.RED + name + " took " + amount + " damage!" + Colors.RESET);
}
public void restore()
{
health = maxHealth;
mana = maxMana;
}
public void gainXP(int amount)
{
xp += amount;
System.out.println(Colors.YELLOW + "You gained " + amount + " XP!" + Colors.RESET);
if (xp >= level * 50)
levelUp();
}
public void levelUp()
{
level++;
maxHealth += 10;
maxMana += 10;
damage += 3;
health = maxHealth;
mana = maxMana;
System.out.println(Colors.GREEN + "LEVEL UP! You are now level " + level + Colors.RESET);
}
public boolean hasAllKeys()
{
return keys.contains("Goblin") && keys.contains("Skeleton") && keys.contains("Vampire");
}
public void addKey(String key)
{
keys.add(key);
System.out.println(Colors.YELLOW + "You obtained the " + key + " Key!" + Colors.RESET);
}
public boolean hasKey(String key)
{
return keys.contains(key);
}
@Override
public void fillMana(int mana) {
mp += mana;
if (mp > maxMP) {
mp = maxMP;
}
}
public String getName() {
public String getName()
{
return name;
}
public int getHp() {
return hp;
@Override
public int getHealth()
{
return health;
}
@Override
public int getMaxHP() {
return maxHP;
}
public int getMp() {
return mp;
public int getMaxHealth()
{
return maxHealth;
}
@Override
public int getMaxMP() {
return maxMP;
public boolean isAlive()
{
return health > 0;
}
public Weapon getWeapon() {
return weapon;
public int getMana()
{
return mana;
}
public Armor getArmor() {
return armor;
public int getMaxMana()
{
return maxMana;
}
}
@@ -0,0 +1,77 @@
package org.project.entity.players;
import org.project.entity.enemies.Enemy;
import org.project.utilities.Colors;
public class Wizard extends Player
{
public Wizard(String name)
{
super(name, 140, 80, 14);
}
@Override
public String getClassName()
{
return "Wizard";
}
@Override
public void lightAttack(Enemy enemy)
{
enemy.takeDamage(damage);
}
@Override
public void heavyAttack(Enemy enemy)
{
if (mana < 10) return;
mana -= 10;
enemy.takeDamage(damage + 12);
}
@Override
public void defend()
{
if (mana < 8) return;
mana -= 8;
defending = true;
System.out.println("🔮 Wizard raised magical shield!");
}
@Override
public void heal()
{
if (mana < 12) return;
mana -= 12;
health += 25;
if (health > maxHealth)
health = maxHealth;
System.out.println(Colors.GREEN + "Wizard healed!" + Colors.RESET);
}
@Override
public void specialAbility(Enemy enemy)
{
if (mana < 20) return;
mana -= 20;
enemy.takeDamage(damage + 25);
health += 15;
if (health > maxHealth)
health = maxHealth;
System.out.println(Colors.PURPLE + "🔥 Arcane Blast activated!" + Colors.RESET);
}
}
@@ -0,0 +1,197 @@
package org.project.game;
import org.project.entity.enemies.*;
import org.project.entity.players.Assassin;
import org.project.entity.players.Knight;
import org.project.entity.players.Player;
import org.project.entity.players.Wizard;
import org.project.location.Location;
import org.project.utilities.Colors;
import java.util.*;
public class Game {
private final Scanner scanner = new Scanner(System.in);
private final Random random = new Random();
private Player player;
private final Location[] locations = {
new Location("Mordor", new Goblin()),
new Location("Ancient Bones", new Skeleton()),
new Location("Mystic Falls", new Vampire())
};
public void start()
{
System.out.println("=== JAVA KNIGHT ⚔️ ===");
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Choose your class:");
System.out.println("1. Knight");
System.out.println("2. Wizard");
System.out.println("3. Assassin");
int choice = scanner.nextInt();
switch (choice)
{
case 2:
player = new Wizard(name);
break;
case 3:
player = new Assassin(name);
break;
default:
player = new Knight(name);
}
gameLoop();
}
private void gameLoop()
{
while (player.isAlive())
{
System.out.println("\nChoose a location:");
for (int i = 0; i < locations.length; i++)
System.out.println((i + 1) + ". " + locations[i].getName());
int locChoice = scanner.nextInt();
Location location = locations[locChoice - 1];
Enemy enemy = location.spawnEnemy();
System.out.println("\n📍 Location: " + location.getName());
System.out.println("Enemy appeared: " + enemy.getName());
System.out.println("\n1. Fight");
System.out.println("2. Move");
if (player.hasAllKeys())
System.out.println("3. Go to Castle");
int choice = scanner.nextInt();
if (choice == 1)
{
battle(enemy);
if (!player.isAlive())
{
System.out.println(Colors.RED + "GAME OVER!" + Colors.RESET);
return;
}
}
else if (choice == 2)
{
System.out.println("You moved away.");
}
else if (choice == 3 && player.hasAllKeys())
{
battle(new Dragon());
if (player.isAlive())
{
System.out.println(Colors.GREEN +
"🐉 Dragon defeated! Peace restored to Javanest!" +
Colors.RESET);
}
else
{
System.out.println(Colors.RED + "GAME OVER!" + Colors.RESET);
}
return;
}
}
}
private void battle(Enemy enemy)
{
System.out.println("\n⚔️ Battle Started!");
while (player.isAlive() && enemy.isAlive()) {
System.out.println("\n[" + player.getName() + " - "
+ player.getHealth() + "/" + player.getMaxHealth()
+ " HP | "
+ player.getMana() + "/" + player.getMaxMana()
+ " Mana]");
System.out.println("[" + enemy.getName() + " - "
+ enemy.getHealth() + "/" + enemy.getMaxHealth()
+ " HP]");
System.out.println("\n1.Light Attack");
System.out.println("2.Heavy Attack");
System.out.println("3.Defend");
System.out.println("4.Heal");
System.out.println("5.Special Ability");
int choice = scanner.nextInt();
switch (choice) {
case 1:
player.lightAttack(enemy);
break;
case 2:
player.heavyAttack(enemy);
break;
case 3:
player.defend();
break;
case 4:
player.heal();
break;
case 5:
player.specialAbility(enemy);
break;
}
if (!enemy.isAlive())
break;
if (enemy.isStunned())
{
System.out.println(Colors.YELLOW + enemy.getName() + " is stunned!" + Colors.RESET);
enemy.setStunned(false);
continue;
}
enemy.attack(player);
}
if (player.isAlive())
{
System.out.println(Colors.GREEN + enemy.getName() + " defeated!" + Colors.RESET);
player.gainXP(enemy.getXpReward());
dropKey(enemy);
player.restore();
System.out.println(Colors.BLUE + "HP and Mana restored!" + Colors.RESET);
}
}
private void dropKey(Enemy enemy)
{
if (enemy instanceof Dragon)
return;
int chance = random.nextInt(100);
if (chance < 20 && !player.hasKey(enemy.getName()))
player.addKey(enemy.getName());
}
}
@@ -1,11 +1,14 @@
package org.project.item;
import org.project.entity.Entity;
public class Item
{
private String name;
public interface Item {
void use(Entity target);
public Item(String name) {
this.name = name;
}
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
public String getName() {
return name;
}
}
@@ -1,42 +0,0 @@
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 boolean isBroke;
public Armor(int defense, int durability) {
this.defense = defense;
this.durability = durability;
}
public void checkBreak() {
if (durability <= 0) {
isBroke = true;
defense = 0;
}
}
// TODO: (BONUS) UPDATE THE REPAIR METHOD
public void repair() {
isBroke = false;
defense = maxDefense;
durability = maxDurability;
}
public int getDefense() {
return defense;
}
public int getDurability() {
return durability;
}
public boolean isBroke() {
return isBroke;
}
}
@@ -1,6 +0,0 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public class KnightArmor {
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
}
@@ -1,16 +0,0 @@
package org.project.item.consumables;
import org.project.entity.Entity;
// TODO: UPDATE IMPLEMENTATION
public class Flask {
/*
THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
*/
// TODO: UPDATE USE METHOD
@Override
public void use(Entity target) {
target.heal(target.getMaxHP() / 10);
}
}
@@ -1,26 +0,0 @@
package org.project.item.weapons;
import org.project.entity.Entity;
import java.util.ArrayList;
// TODO: UPDATE IMPLEMENTATION
public class Sword {
/*
THIS IS AN EXAMPLE OF A WEAPON DESIGN.
*/
int abilityCharge;
public Sword() {
// TODO: DESIGN SWORD'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
}
// TODO: (BONUS) UPDATE THE UNIQUE ABILITY
public void uniqueAbility(ArrayList<Entity> targets) {
abilityCharge += 2;
for (Entity target : targets) {
target.takeDamage(getDamage());
}
}
}
@@ -1,35 +0,0 @@
package org.project.item.weapons;
import org.project.entity.Entity;
// TODO: UPDATE IMPLEMENTATION
public abstract class Weapon {
private int damage;
private int manaCost;
/*
TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES
*/
public Weapon(int damage, int manaCost) {
this.damage = damage;
this.manaCost = manaCost;
}
@Override
public void use(Entity target) {
target.takeDamage(damage);
}
public int getDamage() {
return damage;
}
public int getManaCost() {
return manaCost;
}
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
@@ -2,27 +2,21 @@ package org.project.location;
import org.project.entity.enemies.Enemy;
import java.util.ArrayList;
public class Location {
private String name;
private Enemy enemy;
private ArrayList<Enemy> enemies;
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 ArrayList<Enemy> getEnemies() {
return enemies;
public Enemy spawnEnemy() {
return enemy;
}
}
@@ -0,0 +1,11 @@
package org.project.utilities;
public class Colors
{
public static final String RESET = "\u001B[0m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String BLUE = "\u001B[34m";
public static final String YELLOW = "\u001B[33m";
public static final String PURPLE = "\u001B[35m";
}