Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,12 @@ jobs:
java-version: "17"
cache: maven

- name: Run unit tests
run: mvn -B test
- name: Run tests with coverage
run: mvn -B verify

- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: jacoco-coverage-report
path: target/site/jacoco
if-no-files-found: error
221 changes: 106 additions & 115 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,158 +1,149 @@
# SC2002 Turn-Based Combat Arena
<img width="1178" height="702" alt="CleanShot 2026-04-19 at 12 20 13@2x" src="https://github.com/user-attachments/assets/b4bc118f-9e32-4ebf-86cd-7d107b017eb7" />
<h1 align="center">SC2002 Turn-Based Combat Arena</h1>

<p align="center">
<strong>Java 17 combat game with a tested battle engine, native CLI flow, and a 2D Swing arena.</strong>
</p>

<p align="center">
<a href="https://github.com/liang799/SC2002-Project/actions/workflows/unit-tests.yml">
<img alt="Tests" src="https://img.shields.io/github/actions/workflow/status/liang799/SC2002-Project/unit-tests.yml?branch=main&label=tests&logo=githubactions&logoColor=white">
</a>
<a href="#quality-gates">
<img alt="Line coverage" src="https://img.shields.io/badge/line%20coverage-53.9%25-yellow">
</a>
<a href="https://github.com/liang799/SC2002-Project/blob/main/LICENSE">
<img alt="License: GPL-3.0" src="https://img.shields.io/github/license/liang799/SC2002-Project?label=license">
</a>
<a href="https://github.com/liang799/SC2002-Project/issues">
<img alt="GitHub issues" src="https://img.shields.io/github/issues/liang799/SC2002-Project?label=issues">
</a>
<a href="https://github.com/liang799/SC2002-Project/stargazers">
<img alt="GitHub stars" src="https://img.shields.io/github/stars/liang799/SC2002-Project?style=flat&label=stars">
</a>
<a href="https://github.com/liang799/SC2002-Project/network/members">
<img alt="GitHub forks" src="https://img.shields.io/github/forks/liang799/SC2002-Project?style=flat&label=forks">
</a>
<img alt="Java 17" src="https://img.shields.io/badge/Java-17-007396?logo=openjdk&logoColor=white">
<img alt="Maven" src="https://img.shields.io/badge/build-Maven-C71A36?logo=apachemaven&logoColor=white">
</p>

<p align="center">
<img width="1178" height="702" alt="2D Swing battle arena screenshot" src="https://github.com/user-attachments/assets/b4bc118f-9e32-4ebf-86cd-7d107b017eb7" />
</p>

## Recruiter Snapshot

| Signal | Evidence |
| --- | --- |
| Object-oriented design | Strategy, Factory, Observer, and composition-heavy domain modeling |
| Product surface | CLI gameplay plus an interactive Swing GUI with targeting, items, special skills, and animated feedback |
| Quality bar | 151 automated JUnit 5 tests across unit, integration, and end-to-end flows |
| Delivery discipline | Maven build, GitHub Actions CI, JaCoCo reports, packaged CLI/GUI jars, and tag-based releases |
| Maintainability | Clear boundaries between domain, engine, reporting, setup, CLI, and GUI layers |

## About
This repository contains a Java turn-based combat game built for the SC2002 assignment. The production code now includes both CLI and 2D Swing GUI front ends, with the battle domain, actions, engine, reporting, and UI boundaries kept separate so the system is easier to explain, test, and extend.

## Current Scope

The current implementation includes:

- `Warrior` and `Wizard` as playable classes
- `Goblin` and `Wolf` as enemy types
- `BasicAttack`, `Defend`, and class-specific special skills
- item support for `Potion`, `Smoke Bomb`, and `Power Stone`
- status-effect support for `Arcane Power`, `Defend`, `Strength Boost`, `Smoke Bomb`, and `Stun`
- Easy, Medium, and Hard setup support
- custom wave configuration support
- backup enemy spawn handling
- scripted Appendix A scenario support for Easy Warrior, Medium Warrior, and Medium Wizard
- native CLI gameplay with player class, item, difficulty, and custom wave selection
- 2D Swing GUI gameplay with an arena background, player movement, enemy targeting, action hotkeys, HP bars, paced dialogue playback, and animated battle feedback
- live battle-event display during gameplay
- structured battle-event reporting for testing and formatting
- verifier coverage for Easy checkpoints, Appendix A scenarios, and the custom battle-flow validation scenario

This repository contains a Java turn-based combat game built for the SC2002 assignment. The project treats a compact game brief as a maintainable software system: battle rules live in the domain and engine layers, user interaction is handled at the boundaries, and automated tests lock down core gameplay behavior.

## Gameplay

- Play as a `Warrior` or `Wizard`
- Fight `Goblin` and `Wolf` enemy waves across Easy, Medium, and Hard setups
- Use `Basic Attack`, `Defend`, class-specific special skills, `Potion`, `Smoke Bomb`, and `Power Stone`
- Apply status effects including `Arcane Power`, `Defend`, `Strength Boost`, `Smoke Bomb`, and `Stun`
- Configure custom waves with backup enemy spawn handling
- Run scripted Appendix A scenarios for Easy Warrior, Medium Warrior, and Medium Wizard
- Choose between native CLI gameplay and a 2D Swing GUI battle arena

## Architecture

The project is organized into the following source packages:

- `bootstrap`
- composition root that wires factories, actions, and registry creation
- `domain`
- combatants, stats, inventory, value objects, and special-skill state
- `domain.status`
- status-effect abstractions, concrete effects, outcome records, and the registry that applies them
- `actions`
- battle action strategies such as basic attacks, defend, item usage, and special-skill execution
- `engine`
- battle orchestration, setup/configuration, turn ordering, player decisions, waves, and event streaming
- `report`
- structured battle events, summaries, and status-effect note mapping
- `ui`
- CLI boundary classes, prompts, transcript formatting, and demo entry points
- `ui.gui`
- MVC Swing GUI entry point
- `ui.gui.view`
- Swing panels and the `BattleView` contract for the arena, setup form, battle menu, and post-game choices
- `ui.gui.controller`
- battle-flow orchestration and the bridge from Swing input into the blocking engine decision API
- `ui.gui.model`
- small GUI session state and player-turn command records
- `ui.gui.command`
- battle-menu command resolution into engine `PlayerDecision` objects
- `ui.gui.playback`
- paced event narration and dialogue formatting
- `ui.gui.setup`
- setup/replay launch requests
- `ui.gui.util`
- Swing threading helpers
- `test`
- executable verifier classes for scenario validation

The class diagram reflects several intentional design patterns in the code:

- Strategy
- `BattleAction`, `StatusEffect`, `TurnOrderStrategy`, and `PlayerDecisionProvider` vary behavior behind interfaces
- Factory
- `CombatantFactory`, `SpecialSkillFactory`, and `StatusEffectRegistryFactory` centralize object creation
- Observer
- `BattleEventListener` streams battle events to CLI and GUI consumers
- Composition-heavy domain model
- `Combatant` owns `Inventory`, `HitPoints`, `CombatStats`, and `StatusEffectRegistry`
- `PlayerCharacter` owns `SpecialSkill`

## Running The Game

Compile everything:

```powershell
$files = Get-ChildItem -Recurse -File src/main/java,src/test/java | ForEach-Object { $_.FullName }
javac -d out $files
```
| Package | Responsibility |
| --- | --- |
| `bootstrap` | Composition root for factories, actions, and status-effect registry creation |
| `domain` | Combatants, stats, inventory, value objects, and special-skill state |
| `domain.status` | Status-effect abstractions, concrete effects, outcomes, and registry logic |
| `actions` | Battle action strategies for attacks, defense, items, and special skills |
| `engine` | Battle orchestration, setup, turn ordering, decisions, waves, and event streaming |
| `report` | Structured battle events, combatant summaries, and status-effect reporting |
| `ui` | CLI entry points, prompts, transcript formatting, and demo runners |
| `ui.gui` | Swing MVC entry point, controller, command resolution, playback, setup, and views |
| `test` | Unit, integration, and end-to-end validation helpers and scenarios |

Run the native CLI game:
## Design Patterns

```powershell
java -cp out sc2002.turnbased.ui.TurnBasedArenaCli
```
- Strategy: `BattleAction`, `StatusEffect`, `TurnOrderStrategy`, and `PlayerDecisionProvider` vary behavior behind stable interfaces
- Factory: `CombatantFactory`, `SpecialSkillFactory`, and `StatusEffectRegistryFactory` centralize object creation
- Observer: `BattleEventListener` streams battle events to CLI and GUI consumers
- Composition-heavy domain model: `Combatant` owns inventory, hit points, combat stats, and status effects, while `PlayerCharacter` owns its special skill

Run the Swing GUI:
## Run Locally

```powershell
java -cp out sc2002.turnbased.ui.gui.TurnBasedArenaGui
```
Requires Java 17 and Maven.

Or build and run the packaged 2D GUI jar:
Build the project:

```bash
mvn -DskipTests package
java -jar target/turnbased-arena-1.0-SNAPSHOT-gui.jar
```

2D GUI controls:
Run the packaged CLI:

- Move the player with `WASD` or the arrow keys
- Click an enemy to target it, or cycle targets with `Q` and `E`
- Use the `1` to `4` battle menu: `Fight` opens attacks, `Bag` opens items, `Defend` resolves immediately, and `Target` opens target cycling
- Press `Esc` to return to the main battle menu from a submenu
```bash
java -jar target/turnbased-arena-1.0-SNAPSHOT-cli.jar
```

Run the scripted Appendix demo:
Run the packaged 2D GUI:

```powershell
java -cp out sc2002.turnbased.ui.EasyRoundsDemo
```bash
java -jar target/turnbased-arena-1.0-SNAPSHOT-gui.jar
```

## Validation

Run the automated test suite with:
Run the scripted Appendix demo after compiling:

```bash
mvn test
java -cp target/classes sc2002.turnbased.ui.EasyRoundsDemo
```

The test pyramid is organized as:
## GUI Controls

- Move with `WASD` or the arrow keys
- Click an enemy to target it, or cycle targets with `Q` and `E`
- Use `1` to `4` to navigate battle actions: `Fight`, `Bag`, `Defend`, and `Target`
- Press `Esc` to return from a submenu to the main battle menu

## Quality Gates

| Command | Purpose |
| --- | --- |
| `mvn test` | Runs the automated JUnit 5 test suite |
| `mvn verify` | Runs tests, builds jars, and generates JaCoCo coverage reports |

- `unit`
- focused domain and value-object tests
- `integration`
- deterministic engine and scenario-script coverage
- `e2e`
- full battle-flow validation across setup, engine, decisions, and reporting
Current JaCoCo line coverage from the latest local verification run is **53.9%** (`1,714 / 3,178` lines).

Coverage reports are generated at:

- `target/site/jacoco/index.html`
- `target/site/jacoco/jacoco.xml`

GitHub Actions uploads the HTML report as the `jacoco-coverage-report` artifact on test workflow runs.

## Documentation

The maintained UML source of truth is the PlantUML class diagram:

- `uml-diagrams/plantuml_class_diagram.puml`

<!-- BEGIN GENERATED UML CLASS DIAGRAMS -->
Full-resolution PlantUML outputs are also included:
Full-resolution PlantUML outputs are included:

- [Class diagram PNG](docs/uml-diagrams/imgs/plantuml_class_diagram.png)
- [Class diagram SVG](docs/uml-diagrams/imgs/plantuml_class_diagram.svg)
<!-- END GENERATED UML CLASS DIAGRAMS -->

Legacy Mermaid diagrams have been moved to an outdated folder and are no longer maintained:

- `outdated/mermaid/README.md`
- `outdated/mermaid/mermaid_class_diagram.md`
- `outdated/mermaid/mermaid_sequence_diagram.md`

## Build Output
## License

Compiled output is ignored through `.gitignore`:

```text
out/
```
This project is licensed under the GNU General Public License v3.0. See [LICENSE](LICENSE) for details.
21 changes: 21 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.12.2</junit.version>
<jacoco.version>0.8.14</jacoco.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -41,6 +42,26 @@
<useModulePath>false</useModulePath>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand Down
Loading