Files
basic-computer-games/84_Super_Star_Trek/java/Enterprise.java
2022-03-24 18:58:47 +01:00

332 lines
12 KiB
Java

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 "";
}
}