mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-26 04:41:52 -08:00
updated implementation with proper OO design, provided link to video
This commit is contained in:
331
84_Super_Star_Trek/java/Enterprise.java
Normal file
331
84_Super_Star_Trek/java/Enterprise.java
Normal file
@@ -0,0 +1,331 @@
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* The starship Enterprise.
|
||||
*/
|
||||
public class Enterprise {
|
||||
|
||||
public static final int COORD_X = 0;
|
||||
public static final int COORD_Y = 1;
|
||||
|
||||
// devices
|
||||
static final int DEVICE_WARP_ENGINES = 1;
|
||||
static final int DEVICE_SHORT_RANGE_SENSORS = 2;
|
||||
static final int DEVICE_LONG_RANGE_SENSORS = 3;
|
||||
static final int DEVICE_PHASER_CONTROL = 4;
|
||||
static final int DEVICE_PHOTON_TUBES = 5;
|
||||
static final int DEVICE_DAMAGE_CONTROL = 6;
|
||||
static final int DEVICE_SHIELD_CONTROL = 7;
|
||||
static final int DEVICE_LIBRARY_COMPUTER = 8;
|
||||
final double[] deviceStatus = new double[9]; // 8 device damage stats
|
||||
|
||||
// position
|
||||
final int[][] cardinalDirections = new int[10][3]; // 9x2 vectors in cardinal directions
|
||||
int quadrantX;
|
||||
int quadrantY;
|
||||
int sectorX;
|
||||
int sectorY;
|
||||
|
||||
// ship status
|
||||
boolean docked = false;
|
||||
int energy = 3000;
|
||||
int torpedoes = 10;
|
||||
int shields = 0;
|
||||
double repairCost;
|
||||
|
||||
final int initialEnergy = energy;
|
||||
final int initialTorpedoes = torpedoes;
|
||||
|
||||
public Enterprise() {
|
||||
// random initial position
|
||||
this.setQuadrant(new int[]{ Util.fnr(), Util.fnr() });
|
||||
this.setSector(new int[]{ Util.fnr(), Util.fnr() });
|
||||
// init cardinal directions
|
||||
IntStream.range(1, 9).forEach(i -> {
|
||||
cardinalDirections[i][1] = 0;
|
||||
cardinalDirections[i][2] = 0;
|
||||
});
|
||||
cardinalDirections[3][1] = -1;
|
||||
cardinalDirections[2][1] = -1;
|
||||
cardinalDirections[4][1] = -1;
|
||||
cardinalDirections[4][2] = -1;
|
||||
cardinalDirections[5][2] = -1;
|
||||
cardinalDirections[6][2] = -1;
|
||||
cardinalDirections[1][2] = 1;
|
||||
cardinalDirections[2][2] = 1;
|
||||
cardinalDirections[6][1] = 1;
|
||||
cardinalDirections[7][1] = 1;
|
||||
cardinalDirections[8][1] = 1;
|
||||
cardinalDirections[8][2] = 1;
|
||||
cardinalDirections[9][2] = 1;
|
||||
// init devices
|
||||
IntStream.range(1, 8).forEach(i -> deviceStatus[i] = 0);
|
||||
}
|
||||
|
||||
public int getShields() {
|
||||
return shields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enterprise is hit by enemies.
|
||||
* @param hits the number of hit points
|
||||
*/
|
||||
public void sufferHitPoints(int hits) {
|
||||
this.shields = shields - hits;
|
||||
}
|
||||
|
||||
public int getEnergy() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
public void replenishSupplies() {
|
||||
this.energy = this.initialEnergy;
|
||||
this.torpedoes = this.initialTorpedoes;
|
||||
}
|
||||
|
||||
public void decreaseEnergy(final double amount) {
|
||||
this.energy -= amount;
|
||||
}
|
||||
|
||||
public void decreaseTorpedoes(final int amount) {
|
||||
torpedoes -= amount;
|
||||
}
|
||||
|
||||
public void dropShields() {
|
||||
this.shields = 0;
|
||||
}
|
||||
|
||||
public int getTotalEnergy() {
|
||||
return (shields + energy);
|
||||
}
|
||||
|
||||
public int getInitialEnergy() {
|
||||
return initialEnergy;
|
||||
}
|
||||
|
||||
public int getTorpedoes() {
|
||||
return torpedoes;
|
||||
}
|
||||
|
||||
public double[] getDeviceStatus() {
|
||||
return deviceStatus;
|
||||
}
|
||||
|
||||
public int[][] getCardinalDirections() {
|
||||
return cardinalDirections;
|
||||
}
|
||||
|
||||
public void setDeviceStatus(final int device, final double status) {
|
||||
this.deviceStatus[device] = status;
|
||||
}
|
||||
|
||||
public boolean isDocked() {
|
||||
return docked;
|
||||
}
|
||||
|
||||
public void setDocked(boolean docked) {
|
||||
this.docked = docked;
|
||||
}
|
||||
|
||||
public int[] getQuadrant() {
|
||||
return new int[] {quadrantX, quadrantY};
|
||||
}
|
||||
|
||||
public void setQuadrant(final int[] quadrant) {
|
||||
this.quadrantX = quadrant[COORD_X];
|
||||
this.quadrantY = quadrant[COORD_Y];
|
||||
}
|
||||
|
||||
public int[] getSector() {
|
||||
return new int[] {sectorX, sectorY};
|
||||
}
|
||||
|
||||
public void setSector(final int[] sector) {
|
||||
this.sectorX = sector[COORD_X];
|
||||
this.sectorY = sector[COORD_Y];
|
||||
}
|
||||
|
||||
public int[] moveShip(final float course, final int n, final String quadrantMap, final double stardate, final double initialStardate, final int missionDuration, final GameCallback callback) {
|
||||
int ic1 = Util.toInt(course);
|
||||
float x1 = cardinalDirections[ic1][1] + (cardinalDirections[ic1 + 1][1] - cardinalDirections[ic1][1]) * (course - ic1);
|
||||
float x = sectorX;
|
||||
float y = sectorY;
|
||||
float x2 = cardinalDirections[ic1][2] + (cardinalDirections[ic1 + 1][2] - cardinalDirections[ic1][2]) * (course - ic1);
|
||||
final int initialQuadrantX = quadrantX;
|
||||
final int initialQuadrantY = quadrantY;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
sectorX += x1;
|
||||
sectorY += x2;
|
||||
if (sectorX < 1 || sectorX >= 9 || sectorY < 1 || sectorY >= 9) {
|
||||
// exceeded quadrant limits
|
||||
x = 8 * quadrantX + x + n * x1;
|
||||
y = 8 * quadrantY + y + n * x2;
|
||||
quadrantX = Util.toInt(x / 8);
|
||||
quadrantY = Util.toInt(y / 8);
|
||||
sectorX = Util.toInt(x - quadrantX * 8);
|
||||
sectorY = Util.toInt(y - quadrantY * 8);
|
||||
if (sectorX == 0) {
|
||||
quadrantX = quadrantX - 1;
|
||||
sectorX = 8;
|
||||
}
|
||||
if (sectorY == 0) {
|
||||
quadrantY = quadrantY - 1;
|
||||
sectorY = 8;
|
||||
}
|
||||
boolean hitEdge = false;
|
||||
if (quadrantX < 1) {
|
||||
hitEdge = true;
|
||||
quadrantX = 1;
|
||||
sectorX = 1;
|
||||
}
|
||||
if (quadrantX > 8) {
|
||||
hitEdge = true;
|
||||
quadrantX = 8;
|
||||
sectorX = 8;
|
||||
}
|
||||
if (quadrantY < 1) {
|
||||
hitEdge = true;
|
||||
quadrantY = 8;
|
||||
sectorY = 8;
|
||||
}
|
||||
if (quadrantY > 8) {
|
||||
hitEdge = true;
|
||||
quadrantY = 8;
|
||||
sectorY = 8;
|
||||
}
|
||||
if (hitEdge) {
|
||||
Util.println("LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:");
|
||||
Util.println(" 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER");
|
||||
Util.println(" IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'");
|
||||
Util.println("CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN");
|
||||
Util.println(" AT SECTOR " + sectorX + "," + sectorY + " OF QUADRANT " + quadrantX + "," + quadrantY + ".'");
|
||||
if (stardate > initialStardate + missionDuration) callback.endGameFail(false);
|
||||
}
|
||||
if (8 * quadrantX + quadrantY == 8 * initialQuadrantX + initialQuadrantY) {
|
||||
break;
|
||||
}
|
||||
callback.incrementStardate(1);
|
||||
maneuverEnergySR(n);
|
||||
callback.enterNewQuadrant();
|
||||
return this.getSector();
|
||||
} else {
|
||||
int S8 = Util.toInt(sectorX) * 24 + Util.toInt(sectorY) * 3 - 26; // S8 = pos
|
||||
if (!(" ".equals(Util.midStr(quadrantMap, S8, 2)))) {
|
||||
sectorX = Util.toInt(sectorX - x1);
|
||||
sectorY = Util.toInt(sectorY - x2);
|
||||
Util.println("WARP ENGINES SHUT DOWN AT ");
|
||||
Util.println("SECTOR " + sectorX + "," + sectorY + " DUE TO BAD NAVIGATION");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sectorX = Util.toInt(sectorX);
|
||||
sectorY = Util.toInt(sectorY);
|
||||
return this.getSector();
|
||||
}
|
||||
|
||||
void randomRepairCost() {
|
||||
repairCost = .5 * Util.random();
|
||||
}
|
||||
|
||||
public void repairDamagedDevices(final float warp) {
|
||||
// repair damaged devices and print damage report
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
if (deviceStatus[i] < 0) {
|
||||
deviceStatus[i] += Math.min(warp, 1);
|
||||
if ((deviceStatus[i] > -.1) && (deviceStatus[i] < 0)) {
|
||||
deviceStatus[i] = -.1;
|
||||
break;
|
||||
} else if (deviceStatus[i] >= 0) {
|
||||
Util.println("DAMAGE CONTROL REPORT: ");
|
||||
Util.println(Util.tab(8) + printDeviceName(i) + " REPAIR COMPLETED.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void maneuverEnergySR(final int N) {
|
||||
energy = energy - N - 10;
|
||||
if (energy >= 0) return;
|
||||
Util.println("SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER.");
|
||||
shields = shields + energy;
|
||||
energy = 0;
|
||||
if (shields <= 0) shields = 0;
|
||||
}
|
||||
|
||||
void shieldControl() {
|
||||
if (deviceStatus[DEVICE_SHIELD_CONTROL] < 0) {
|
||||
Util.println("SHIELD CONTROL INOPERABLE");
|
||||
return;
|
||||
}
|
||||
Util.println("ENERGY AVAILABLE = " + (energy + shields));
|
||||
int energyToShields = Util.toInt(Util.inputFloat("NUMBER OF UNITS TO SHIELDS"));
|
||||
if (energyToShields < 0 || shields == energyToShields) {
|
||||
Util.println("<SHIELDS UNCHANGED>");
|
||||
return;
|
||||
}
|
||||
if (energyToShields > energy + energyToShields) {
|
||||
Util.println("SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'");
|
||||
Util.println("<SHIELDS UNCHANGED>");
|
||||
return;
|
||||
}
|
||||
energy = energy + shields - energyToShields;
|
||||
shields = energyToShields;
|
||||
Util.println("DEFLECTOR CONTROL ROOM REPORT:");
|
||||
Util.println(" 'SHIELDS NOW AT " + Util.toInt(shields) + " UNITS PER YOUR COMMAND.'");
|
||||
}
|
||||
|
||||
void damageControl(GameCallback callback) {
|
||||
if (deviceStatus[DEVICE_DAMAGE_CONTROL] < 0) {
|
||||
Util.println("DAMAGE CONTROL REPORT NOT AVAILABLE");
|
||||
} else {
|
||||
Util.println("\nDEVICE STATE OF REPAIR");
|
||||
for (int deviceNr = 1; deviceNr <= 8; deviceNr++) {
|
||||
Util.print(printDeviceName(deviceNr) + Util.leftStr(GalaxyMap.QUADRANT_ROW, 25 - Util.strlen(printDeviceName(deviceNr))) + " " + Util.toInt(deviceStatus[deviceNr] * 100) * .01 + "\n");
|
||||
}
|
||||
}
|
||||
if (!docked) return;
|
||||
|
||||
double deltaToRepair = 0;
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
if (deviceStatus[i] < 0) deltaToRepair += .1;
|
||||
}
|
||||
if (deltaToRepair > 0) {
|
||||
deltaToRepair += repairCost;
|
||||
if (deltaToRepair >= 1) deltaToRepair = .9;
|
||||
Util.println("TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;");
|
||||
Util.println("ESTIMATED TIME TO REPAIR:'" + .01 * Util.toInt(100 * deltaToRepair) + " STARDATES");
|
||||
final String reply = Util.inputStr("WILL YOU AUTHORIZE THE REPAIR ORDER (Y/N)");
|
||||
if ("Y".equals(reply)) {
|
||||
for (int deviceNr = 1; deviceNr <= 8; deviceNr++) {
|
||||
if (deviceStatus[deviceNr] < 0) deviceStatus[deviceNr] = 0;
|
||||
}
|
||||
callback.incrementStardate(deltaToRepair + .1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String printDeviceName(final int deviceNumber) { // 8790
|
||||
// PRINTS DEVICE NAME
|
||||
switch (deviceNumber) {
|
||||
case DEVICE_WARP_ENGINES:
|
||||
return "WARP ENGINES";
|
||||
case DEVICE_SHORT_RANGE_SENSORS:
|
||||
return "SHORT RANGE SENSORS";
|
||||
case DEVICE_LONG_RANGE_SENSORS:
|
||||
return "LONG RANGE SENSORS";
|
||||
case DEVICE_PHASER_CONTROL:
|
||||
return "PHASER CONTROL";
|
||||
case DEVICE_PHOTON_TUBES:
|
||||
return "PHOTON TUBES";
|
||||
case DEVICE_DAMAGE_CONTROL:
|
||||
return "DAMAGE CONTROL";
|
||||
case DEVICE_SHIELD_CONTROL:
|
||||
return "SHIELD CONTROL";
|
||||
case DEVICE_LIBRARY_COMPUTER:
|
||||
return "LIBRARY-COMPUTER";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user