# Java Knight ⚔️

A turn-based, roguelike-inspired RPG that runs entirely in the terminal, written
in Java for the fourth Advanced Programming assignment.

> *For centuries, the land of Javanest lived in peace, until a magical Dragon
> plunged it into darkness, cursing its people into monsters and scattering the
> three keys to its lair among them. Battle the cursed creatures, recover the
> Goblin, Skeleton and Vampire keys, grow strong, and slay the Dragon to break
> the curse and restore peace to Javanest!*

---

## Table of Contents
1. [How to Compile & Run](#how-to-compile--run)
2. [How to Play](#how-to-play)
3. [Classes, Enemies & Stats](#classes-enemies--stats)
4. [Project Structure](#project-structure)
5. [OOP Principles Used](#oop-principles-used)
6. [Bonus Features](#bonus-features)

---

## How to Compile & Run

The project is a standard Maven project. You need **JDK 21+** installed.

### Using Maven (recommended)
```bash
cd Java-Knight
mvn compile
mvn exec:java -Dexec.mainClass=org.project.Main
```

### Using plain `javac` / `java`
```bash
cd Java-Knight
# compile every source file into the target/classes folder
find src/main/java -name "*.java" > sources.txt
javac -d target/classes @sources.txt

# run it
java -cp target/classes org.project.Main
```

> The game uses ANSI colour codes, so run it in a real terminal (macOS Terminal,
> Linux shell, Windows Terminal) for the intended colourful output.

---

## How to Play

1. **Name your hero** and **pick a class** (Knight, Wizard, or Assassin).
2. You wander into a random **location** and a random standard enemy appears.
   For each encounter you choose:
   - **1. Fight** – enter turn-based combat.
   - **2. Move** – skip this enemy and travel somewhere new.
   - **3. Visit the Merchant** – spend coins on potions, a weapon, or repairs.
   - **4. Go to the Castle** – *only appears once you hold all 3 keys* – fight
     the Dragon.
3. **Combat is turn-based.** On your turn you pick one of five actions. Only
   **Light Attack** is free; the rest cost Mana/Stamina, and the class
   **Special** costs the most. If you run out of Mana, you can still Light
   Attack.

   | # | Action        | Cost      | Effect |
   |---|---------------|-----------|--------|
   | 1 | Light Attack  | 0         | Moderate damage |
   | 2 | Heavy Attack  | 8         | Double damage |
   | 3 | Defend        | 6         | Blocks ~75% of the next hit |
   | 4 | Heal          | 12        | Restores 40% of max HP |
   | 5 | Special       | 15        | Unique class ultimate |
   | 6 | Use Item      | –         | Drink a potion from your inventory |

4. **Winning a fight** grants **XP** (scaled to the enemy's power), **coins**,
   and a chance to drop that species' **key**. Your HP and Mana are then fully
   restored.
5. **Leveling up** automatically raises your Max HP, Max Mana and base damage.
6. Collect **all 3 keys**, go to the Castle, and defeat the **Dragon** to win.
   Dying at any point is **Game Over**.

---

## Classes, Enemies & Stats

### Player Classes
Each class has deliberately different starting stats, so they play differently.

| Class      | HP | Mana | Base Dmg | Weapon      | Special ability |
|------------|----|------|----------|-------------|-----------------|
| **Knight** ⚔️  | 50 | 40 | **8 (highest)** | Iron Sword | **Shield Bash** – heavy damage + stuns the enemy (skips its next turn) |
| **Wizard** 🧙  | **65 (highest)** | 45 | 5 | Oak Staff | **Arcane Blast** – heavy damage AND heals the caster |
| **Assassin** 🗡️ | 45 | **55 (highest)** | 6 | Twin Dagger | **Vanish** – dodges the next attack + guarantees a crit on the next strike |

### Enemies
| Enemy      | HP  | Ability | Key |
|------------|-----|---------|-----|
| **Goblin** 👹   | 30  | 40% chance to land a **critical hit** (double damage) | Goblin Key |
| **Skeleton** ☠️ | 40  | **Resurrects once** per battle at 50% HP | Skeleton Key |
| **Vampire** 🦇  | 48  | **Lifesteal** – heals for 50% of the damage it deals | Vampire Key |
| **Dragon** 🐉   | 160 | **True damage** – fiery breath ignores armor *and* the Defend stance | — |

Standard enemies each have a **25% chance** to drop their key, and only **one key
per species** can ever drop (once you have the Goblin Key, no other Goblin will
drop one).

---

## Project Structure

```
org.project
├── Main.java                 // entry point – builds the world, starts the game
├── Game.java                 // the game controller / main loop
├── Merchant.java             // bonus shop system
├── entity
│   ├── Entity.java           // interface every combatant implements
│   ├── players
│   │   ├── ICombatActions.java   // interface: the 5 required actions
│   │   ├── Player.java           // abstract base for all heroes
│   │   ├── Knight.java / Wizard.java / Assassin.java
│   └── enemies
│       ├── Enemy.java            // abstract base for all monsters
│       ├── KeyType.java          // enum of the three keys
│       ├── Goblin.java / Skeleton.java / Vampire.java / Dragon.java
├── item
│   ├── Item.java             // interface for anything ownable/sellable
│   ├── weapons  (Weapon abstract → Sword, Dagger, Staff, GreatAxe)
│   ├── armors   (Armor abstract  → KnightArmor, LeatherArmor, Robe)
│   └── consumables (Consumable abstract → Flask, ManaPotion)
├── location
│   └── Location.java         // a place that spawns random enemies
└── util
    ├── ConsoleColors.java    // ANSI colour helpers
    └── Dice.java             // random-number helpers
```

---

## OOP Principles Used

This project was designed around the seven principles the assignment asks for:

- **Encapsulation** – all fields are `private`/`protected` with getters. HP, Mana
  and XP can only be changed through methods like `takeDamage`, `heal` and
  `gainXP`, which enforce their own rules (clamping to max, capping at zero,
  leveling up).

- **Inheritance** – shared logic lives in abstract base classes so it isn't
  duplicated. `Player` holds the HP/Mana bars, leveling, inventory and four of
  the five actions; `Knight`, `Wizard` and `Assassin` only add what's unique.
  Same idea for `Enemy` → its four monster subclasses, and for
  `Weapon`/`Armor`/`Consumable` → their concrete items.

- **Interfaces** – `Entity` is the contract every combatant obeys, which is what
  lets the combat loop treat a Knight and a Dragon identically. `ICombatActions`
  guarantees every player class implements exactly the five required actions.
  `Item` unifies weapons, armor and consumables so the merchant can sell any of
  them.

- **Abstract classes** – `Player`, `Enemy`, `Weapon`, `Armor` and `Consumable`
  are all abstract: they provide shared state/behaviour but can't be instantiated
  on their own, forcing subclasses to fill in the specifics (e.g.
  `Player.specialAbility` is abstract).

- **Polymorphism** – the whole game loop is polymorphic. `Game` only ever calls
  `Player`/`Enemy`/`Entity` methods; the correct `specialAbility`, `attack` or
  `takeDamage` runs depending on the real object. Each enemy overrides `attack`
  to add its signature move.

- **Overriding** – subclasses override base behaviour, e.g. `Skeleton` overrides
  `takeDamage` to resurrect, `Vampire`/`Goblin`/`Dragon` override `attack`, and
  every player class overrides `specialAbility`.

- **Overloading** – `takeDamage(int)` vs `takeDamage(int, boolean)` in `Player`.
  The second, overloaded version ignores defenses and is how the Dragon's breath
  bypasses armor and shields. The `Sword` also overloads its constructor.

---

## Bonus Features

- **Coins & Merchant system** – enemies drop coins; the Merchant sells Health
  Flasks, Mana Potions, a stronger **Great Axe**, and can **repair** armor.
- **Inventory & consumables** – potions can be bought, stored and used mid-combat
  (action 6).
- **Durable armor** – armor loses durability as it absorbs hits and eventually
  breaks, until repaired at the merchant.
- **Colourful narrative console** – ANSI colours (red for damage, blue for mana,
  green for healing) make the combat log easy to read.

---

*Born of God and Void. You shall seal the blinding light that plagues their
dreams. You are the Vessel. You are the Java Knight.*
