This project demonstrates clean inheritance, polymorphism, and collections in Java by modeling two concrete Trooper types that share a common abstract base. A small driver (AStarWar) wires up a few instances, groups them by unit, and runs a randomized combat loop to exercise the API. A JUnit test suite validates key behaviors.
For sample I/O and additional details, see: https://www.rsiddiq.com/software-design.html
Trooper-Maker/
├─ app/
├─ src/
│ ├─ main/java/
│ │ ├─ AStarWar.java
│ │ ├─ RebelTrooper.java
│ │ ├─ StormTrooper.java
│ │ └─ Trooper.java
│ └─ test/java/
│ └─ TrooperTest.java
└─ build.gradle
├─ gradle/
├─ gradlew
├─ settings.gradle
├─ gradlew.bat
Notes
- Source files are in the default package (no
packageline). - Gradle’s sample
application.mainClassoften points totrooper.maker.App—update it toAStarWar(see below).
The model centers on an abstract base Trooper with encapsulated identity (unit, number) and shared behavior. Two concrete types, RebelTrooper and StormTrooper, specialize marching speed via a modifier and encode asymmetric attack rules. The driver AStarWar wires instances, groups them by unit, and runs a randomized combat loop. A JUnit 5 test class validates grouping, marching math, and counters.
-
Trooper(abstract)- Fields:
unit(String),number(int),trooperKind(String),marchSpeed(double, default 5.0),marchModifier(double). - Core API:
double march(double duration)— abstract; implemented by subclasses.static void addToUnit(Map<String,List<Trooper>> units, Trooper t)— group byunitkey.boolean attack(Trooper target, int roll)— prints contextual messages and returns hit/miss per rules.String toString()—"<unit><number>: "; subclasses prepend a display name and append kind.
- Equality:
equalsandhashCodeinclude all fields for value‑style semantics.
- Fields:
-
RebelTrooper- Constructor:
(String unit, int number, String name); sets kind to"pilot"andmarchModifier = 0.75. march(duration):marchSpeed * duration * marchModifier.toString():"<name> (" + super.toString() + "pilot)".
- Constructor:
-
StormTrooper- Constructor:
(String unit, int number); sets kind to"StormTrooper"andmarchModifier = 1.10. march(duration):marchSpeed * duration * marchModifier.toString():"<name>(" + super.toString() + "StormTrooper)".
- Constructor:
-
AStarWar(driver)- Creates two rebels and two stormtroopers, prints soldier counts, adjusts a speed, groups by unit, and runs a nested loop that calls
marchandattackwith random rolls (1..20) to produce a trace of hits/misses.
- Creates two rebels and two stormtroopers, prints soldier counts, adjusts a speed, groups by unit, and runs a nested loop that calls
-
TrooperTest(JUnit 5)- Verifies grouping by unit, marching computations, and static soldier counters for each subclass.
- Self‑target or roll = 1 → always self‑hit (special log lines).
- StormTrooper attacking…
- RebelTrooper → hit iff
roll > 10androlleven. - StormTrooper → “No treason in the ranks!” → miss.
- Other → “Acceptable Collateral Damage!” → hit iff
roll > 10orrolleven.
- RebelTrooper → hit iff
- RebelTrooper attacking…
- RebelTrooper → “Imperial Spy!” → miss.
- StormTrooper → “…against the imperial scum.” → hit iff
roll > 5orrollodd. - Other → “Rebels target an innocent bystander” → hit iff
roll >= 18androlleven.
- Java 17+ (works on 8+, but 17 LTS recommended)
- (Optional) JUnit 5 if you want to run tests
From app/src/main/java:
# Compile
javac *.java
# Run the demo (random output each run)
java AStarWarThe Gradle Wrapper is included at the repo root, so no local Gradle install is needed.
Run all commands from the repo root with -p app to target the app module.
# Build
./gradlew -p app build
# Run
./gradlew -p app runOn Windows (PowerShell or CMD):
gradlew -p app build
gradlew -p app runEnsure app/build.gradle contains:
plugins {
id 'application'
}
application {
// Entry point matches the actual driver class
mainClass = 'AStarWar'
}
java {
toolchain {
// Works on 17+; adjust if you prefer 21
languageVersion = JavaLanguageVersion.of(17)
}
}
tasks.test {
useJUnitPlatform()
}If you have JUnit 5 jars on your classpath:
# Compile tests (adjust path to your junit-platform-console-standalone jar)
javac -cp .:junit-platform-console-standalone.jar *.java
# Execute tests
java -jar junit-platform-console-standalone.jar -cp . --scan-classpath- Encapsulation:
unitandnumberare private with standard getters/setters. - Extensibility: New Trooper types can override
marchand specializeattackviainstanceofbranches or a future double‑dispatch refactor. - Collections:
addToUnitsafely initializes per‑unit lists and appends troopers. - Logging:
toString()formats ensure consistent, readable console output.
Rebel troopers: 2
Stormtroopers: 2
Luke(red5: ) a pilot
Luke(red5: ) a pilot Marched 38.0 meters
...
(tk421: ) a StormTrooper rolled a 6
No treason in the ranks!
Miss!
Exact numbers vary because rolls are randomized.
For sample I/O traces and additional information, visit the project page:
https://www.rsiddiq.com/software-design.html
- This repository is presented as a professional showcase of software design, collections usage, and lightweight simulation behavior in Java.
- Class and message names are for thematic clarity; the design focuses on readable APIs and testable logic.