Skip to content

Instantly share code, notes, and snippets.

@mbutler
Created October 10, 2024 04:40
Show Gist options
  • Save mbutler/bf2720590b7472a302aa6a296ef099c0 to your computer and use it in GitHub Desktop.
Save mbutler/bf2720590b7472a302aa6a296ef099c0 to your computer and use it in GitHub Desktop.
classic 70s Star Trek BASIC game in JS
// Star Trek Game in JavaScript
// Original BASIC version by Mike Mayfield, converted to JavaScript
"use strict";
// Constants
const GALAXY_SIZE = 8;
const SECTOR_SIZE = 8;
const MAX_DOCK_STARS = 9;
const COMMANDS = ["NAV", "SRS", "LRS", "PHA", "TOR", "SHE", "DAM", "COM", "XXX"];
// Global Variables
let galaxy = [];
let quadrantNames = [];
let devices = [];
let commandFunctions = {};
let gameState = {};
// Initialize the game
function initializeGame() {
setupQuadrantNames();
setupDevices();
setupGalaxy();
setupEnterprise();
printIntro();
mainGameLoop();
}
// Setup functions
function setupQuadrantNames() {
quadrantNames = [
["ANTARES", "RIGEL", "PROCYON", "VEGA", "CANOPUS", "ALTAIR", "SAGITTARIUS", "POLLUX"],
["SIRIUS", "DENEB", "CAPELLA", "BETELGEUSE", "ALDEBARAN", "REGULUS", "ARCTURUS", "SPICA"],
];
}
function setupDevices() {
devices = [
"WARP ENGINES",
"SHORT RANGE SENSORS",
"LONG RANGE SENSORS",
"PHASER CONTROL",
"PHOTON TUBES",
"DAMAGE CONTROL",
"SHIELD CONTROL",
"LIBRARY-COMPUTER",
];
}
function setupGalaxy() {
for (let x = 0; x < GALAXY_SIZE; x++) {
galaxy[x] = [];
for (let y = 0; y < GALAXY_SIZE; y++) {
let klingons = 0;
let starbases = 0;
let stars = getRandomInt(1, 8);
let random = Math.random();
if (random > 0.98) {
klingons = 3;
} else if (random > 0.95) {
klingons = 2;
} else if (random > 0.80) {
klingons = 1;
}
if (Math.random() > 0.96) {
starbases = 1;
}
galaxy[x][y] = {
klingons: klingons,
starbases: starbases,
stars: stars,
};
}
}
}
function setupEnterprise() {
gameState = {
stardate: getRandomInt(2000, 2200),
timeRemaining: 25 + getRandomInt(0, 10),
initialStardate: 0,
totalKlingons: 0,
klingonsDestroyed: 0,
starbasesDestroyed: 0,
energy: 3000,
torpedoes: 10,
shields: 0,
quadrantX: getRandomInt(0, GALAXY_SIZE - 1),
quadrantY: getRandomInt(0, GALAXY_SIZE - 1),
sectorX: getRandomInt(0, SECTOR_SIZE - 1),
sectorY: getRandomInt(0, SECTOR_SIZE - 1),
docked: false,
damage: new Array(8).fill(0),
galaxyMap: [],
shipCondition: "GREEN",
destroyed: false,
resigned: false,
};
gameState.initialStardate = gameState.stardate;
// Count total Klingons and Starbases
for (let x = 0; x < GALAXY_SIZE; x++) {
for (let y = 0; y < GALAXY_SIZE; y++) {
gameState.totalKlingons += galaxy[x][y].klingons;
if (galaxy[x][y].starbases > 0) {
gameState.starbases = (gameState.starbases || 0) + 1;
}
}
}
// Ensure at least one starbase exists
if (!gameState.starbases) {
galaxy[gameState.quadrantX][gameState.quadrantY].starbases = 1;
gameState.starbases = 1;
}
}
// Utility functions
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function printIntro() {
console.clear();
console.log(" ,------*------,");
console.log(" ,------------- '--- ------'");
console.log(" '-------- --' / /");
console.log(" ,---' '-------/ /--,");
console.log(" '----------------'");
console.log("");
console.log(" THE USS ENTERPRISE --- NCC-1701");
console.log("");
console.log("YOUR ORDERS ARE AS FOLLOWS:");
console.log(` DESTROY THE ${gameState.totalKlingons} KLINGON WARSHIPS WHICH HAVE INVADED`);
console.log(` THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS`);
console.log(` ON STARDATE ${gameState.stardate + gameState.timeRemaining} THIS GIVES YOU ${gameState.timeRemaining} DAYS.`);
console.log(
` THERE ${gameState.starbases === 1 ? "IS" : "ARE"} ${gameState.starbases} STARBASE${
gameState.starbases === 1 ? "" : "S"
} IN THE GALAXY FOR RESUPPLYING YOUR SHIP`
);
console.log("");
}
// Main Game Loop
function mainGameLoop() {
while (!gameState.destroyed && !gameState.resigned && gameState.timeRemaining > 0) {
enterQuadrant();
commandLoop();
if (gameState.totalKlingons <= 0) {
victory();
break;
}
if (gameState.destroyed) {
defeat();
break;
}
if (gameState.resigned) {
resignation();
break;
}
if (gameState.timeRemaining <= 0) {
outOfTime();
break;
}
}
}
// Entering a Quadrant
function enterQuadrant() {
let quadrant = galaxy[gameState.quadrantX][gameState.quadrantY];
console.log(`Now entering ${getQuadrantName(gameState.quadrantX, gameState.quadrantY)} Quadrant...`);
console.log("");
gameState.klingonsInQuadrant = quadrant.klingons;
gameState.starbasesInQuadrant = quadrant.starbases;
gameState.starsInQuadrant = quadrant.stars;
gameState.sectorMap = createSectorMap();
if (gameState.klingonsInQuadrant > 0) {
console.log("COMBAT AREA CONDITION RED");
if (gameState.shields < 200) {
console.log(" SHIELDS DANGEROUSLY LOW");
}
}
if (gameState.docked) {
gameState.docked = false;
console.log("Leaving starbase...");
}
shortRangeScan();
}
// Create Sector Map
function createSectorMap() {
let map = Array.from({ length: SECTOR_SIZE }, () => Array(SECTOR_SIZE).fill(" "));
// Place Enterprise
map[gameState.sectorX][gameState.sectorY] = "<E>";
// Place Stars
for (let i = 0; i < gameState.starsInQuadrant; i++) {
let [x, y] = getRandomEmptySector(map);
map[x][y] = " * ";
}
// Place Klingons
gameState.klingonPositions = [];
for (let i = 0; i < gameState.klingonsInQuadrant; i++) {
let [x, y] = getRandomEmptySector(map);
map[x][y] = "+K+";
gameState.klingonPositions.push({
x: x,
y: y,
energy: 300 + getRandomInt(0, 200),
});
}
// Place Starbases
if (gameState.starbasesInQuadrant > 0) {
let [x, y] = getRandomEmptySector(map);
map[x][y] = ">!<";
gameState.starbasePosition = { x: x, y: y };
}
return map;
}
function getRandomEmptySector(map) {
let x, y;
do {
x = getRandomInt(0, SECTOR_SIZE - 1);
y = getRandomInt(0, SECTOR_SIZE - 1);
} while (map[x][y] !== " ");
return [x, y];
}
// Command Loop
function commandLoop() {
let command = "";
while (!gameState.destroyed && !gameState.resigned) {
if (gameState.klingonsInQuadrant > 0) {
klingonAttack();
if (gameState.destroyed) {
break;
}
}
if (gameState.energy <= 0) {
console.log("You have run out of energy!");
gameState.destroyed = true;
break;
}
command = promptCommand();
executeCommand(command);
if (command === "NAV" || command === "XXX") {
break;
}
}
}
// Prompt Command
function promptCommand() {
let input = prompt("Command? ").toUpperCase();
while (!COMMANDS.includes(input)) {
console.log("Enter one of the following:");
console.log(" NAV (TO SET COURSE)");
console.log(" SRS (FOR SHORT RANGE SENSOR SCAN)");
console.log(" LRS (FOR LONG RANGE SENSOR SCAN)");
console.log(" PHA (TO FIRE PHASERS)");
console.log(" TOR (TO FIRE PHOTON TORPEDOES)");
console.log(" SHE (TO RAISE OR LOWER SHIELDS)");
console.log(" DAM (FOR DAMAGE CONTROL REPORTS)");
console.log(" COM (TO CALL ON LIBRARY-COMPUTER)");
console.log(" XXX (TO RESIGN YOUR COMMAND)");
input = prompt("Command? ").toUpperCase();
}
return input;
}
// Execute Command
function executeCommand(command) {
switch (command) {
case "NAV":
navigate();
break;
case "SRS":
shortRangeScan();
break;
case "LRS":
longRangeScan();
break;
case "PHA":
firePhasers();
break;
case "TOR":
fireTorpedoes();
break;
case "SHE":
shieldControl();
break;
case "DAM":
damageReport();
break;
case "COM":
libraryComputer();
break;
case "XXX":
gameState.resigned = true;
break;
default:
console.log("Invalid command.");
}
}
// Navigation
function navigate() {
let course = parseFloat(prompt("Course (1-9)? "));
if (course === 9) course = 1;
if (course < 1 || course >= 9) {
console.log(" Lt. Sulu reports, 'Incorrect course data, sir!'");
return;
}
let warp = parseFloat(prompt("Warp Factor (0-8)? "));
if (warp <= 0 || warp > 8) {
console.log(" Chief Engineer Scott reports 'The engines won't take warp " + warp + "!'");
return;
}
let distance = Math.round(warp * 8);
if (gameState.energy - distance < 0) {
console.log("Engineering reports 'Insufficient energy available for maneuvering at warp " + warp + "!'");
return;
}
moveEnterprise(course, distance);
}
function moveEnterprise(course, distance) {
let direction = getDirectionVector(course);
for (let i = 0; i < distance; i++) {
let newX = gameState.sectorX + direction.dx;
let newY = gameState.sectorY + direction.dy;
if (newX < 0 || newX >= SECTOR_SIZE || newY < 0 || newY >= SECTOR_SIZE) {
// Move to new Quadrant
gameState.quadrantX += Math.sign(direction.dx);
gameState.quadrantY += Math.sign(direction.dy);
if (gameState.quadrantX < 0) gameState.quadrantX = 0;
if (gameState.quadrantX >= GALAXY_SIZE) gameState.quadrantX = GALAXY_SIZE - 1;
if (gameState.quadrantY < 0) gameState.quadrantY = 0;
if (gameState.quadrantY >= GALAXY_SIZE) gameState.quadrantY = GALAXY_SIZE - 1;
gameState.sectorX = (newX + SECTOR_SIZE) % SECTOR_SIZE;
gameState.sectorY = (newY + SECTOR_SIZE) % SECTOR_SIZE;
gameState.energy -= distance;
gameState.timeRemaining--;
enterQuadrant();
return;
}
if (gameState.sectorMap[newX][newY] === " ") {
gameState.sectorMap[gameState.sectorX][gameState.sectorY] = " ";
gameState.sectorX = newX;
gameState.sectorY = newY;
gameState.sectorMap[gameState.sectorX][gameState.sectorY] = "<E>";
} else {
console.log("Warp engines shut down at sector " + (gameState.sectorX + 1) + "," + (gameState.sectorY + 1) + " due to bad navigation.");
break;
}
}
gameState.energy -= distance;
gameState.timeRemaining--;
shortRangeScan();
}
function getDirectionVector(course) {
const angles = [0, 45, 90, 135, 180, 225, 270, 315];
let angle = angles[Math.floor(course) - 1];
let rad = (angle * Math.PI) / 180;
let dx = Math.round(Math.sin(rad));
let dy = Math.round(Math.cos(rad));
return { dx: dx, dy: dy };
}
// Short Range Scan
function shortRangeScan() {
console.log("Short Range Sensor Scan for Quadrant " + (gameState.quadrantX + 1) + "," + (gameState.quadrantY + 1));
console.log("---------------------------------");
for (let y = 0; y < SECTOR_SIZE; y++) {
let row = "";
for (let x = 0; x < SECTOR_SIZE; x++) {
row += gameState.sectorMap[x][y];
}
console.log(row);
}
console.log("---------------------------------");
console.log("Stardate: " + gameState.stardate);
console.log("Condition: " + gameState.shipCondition);
console.log("Quadrant: " + (gameState.quadrantX + 1) + "," + (gameState.quadrantY + 1));
console.log("Sector: " + (gameState.sectorX + 1) + "," + (gameState.sectorY + 1));
console.log("Photon Torpedoes: " + gameState.torpedoes);
console.log("Total Energy: " + (gameState.energy + gameState.shields));
console.log("Shields: " + gameState.shields);
console.log("Klingons Remaining:" + gameState.totalKlingons);
}
// Long Range Scan
function longRangeScan() {
console.log("Long Range Scan for Quadrant " + (gameState.quadrantX + 1) + "," + (gameState.quadrantY + 1));
console.log("-------------------");
for (let x = gameState.quadrantX - 1; x <= gameState.quadrantX + 1; x++) {
let row = ": ";
for (let y = gameState.quadrantY - 1; y <= gameState.quadrantY + 1; y++) {
if (x >= 0 && x < GALAXY_SIZE && y >= 0 && y < GALAXY_SIZE) {
let q = galaxy[x][y];
row +=
" " +
String(q.klingons * 100 + q.starbases * 10 + q.stars).padStart(3, "0") +
" ";
} else {
row += " *** ";
}
}
console.log(row + ":");
}
console.log("-------------------");
}
// Fire Phasers
function firePhasers() {
if (gameState.klingonsInQuadrant <= 0) {
console.log("Science Officer Spock reports, 'Sensors show no enemy ships in this quadrant.'");
return;
}
console.log("Phasers locked on target; Energy available = " + gameState.energy + " units");
let energyToFire = parseFloat(prompt("Number of units to fire? "));
if (energyToFire <= 0 || energyToFire > gameState.energy) {
console.log("Invalid amount of energy.");
return;
}
gameState.energy -= energyToFire;
let totalDamage = energyToFire;
let damagePerKlingon = totalDamage / gameState.klingonsInQuadrant;
for (let i = 0; i < gameState.klingonPositions.length; i++) {
let klingon = gameState.klingonPositions[i];
if (klingon.energy > 0) {
let distance = Math.sqrt(
Math.pow(klingon.x - gameState.sectorX, 2) + Math.pow(klingon.y - gameState.sectorY, 2)
);
let damage = damagePerKlingon / distance;
klingon.energy -= damage;
if (klingon.energy <= 0) {
console.log("*** Klingon destroyed at sector " + (klingon.x + 1) + "," + (klingon.y + 1) + " ***");
gameState.sectorMap[klingon.x][klingon.y] = " ";
gameState.klingonsInQuadrant--;
gameState.totalKlingons--;
gameState.klingonPositions.splice(i, 1);
i--;
if (gameState.totalKlingons <= 0) {
victory();
return;
}
} else {
console.log(
damage.toFixed(2) +
" unit hit on Klingon at sector " +
(klingon.x + 1) +
"," +
(klingon.y + 1) +
" (Remaining energy: " +
klingon.energy.toFixed(2) +
")"
);
}
}
}
}
// Fire Torpedoes
function fireTorpedoes() {
if (gameState.torpedoes <= 0) {
console.log("All photon torpedoes expended");
return;
}
let course = parseFloat(prompt("Photon torpedo course (1-9)? "));
if (course === 9) course = 1;
if (course < 1 || course >= 9) {
console.log("Ensign Chekov reports, 'Incorrect course data, sir!'");
return;
}
gameState.torpedoes--;
gameState.energy -= 2;
let direction = getDirectionVector(course);
let x = gameState.sectorX;
let y = gameState.sectorY;
console.log("Torpedo track:");
while (true) {
x += direction.dx;
y += direction.dy;
if (x < 0 || x >= SECTOR_SIZE || y < 0 || y >= SECTOR_SIZE) {
console.log("Torpedo missed");
break;
}
console.log(" " + (x + 1) + "," + (y + 1));
let object = gameState.sectorMap[x][y];
if (object === " * ") {
console.log("Star at " + (x + 1) + "," + (y + 1) + " absorbed torpedo energy.");
break;
} else if (object === "+K+") {
console.log("*** Klingon destroyed ***");
gameState.sectorMap[x][y] = " ";
gameState.klingonsInQuadrant--;
gameState.totalKlingons--;
removeKlingonAtPosition(x, y);
if (gameState.totalKlingons <= 0) {
victory();
return;
}
break;
} else if (object === ">!<") {
console.log("*** Starbase destroyed ***");
gameState.starbasesInQuadrant--;
gameState.starbases--;
gameState.sectorMap[x][y] = " ";
if (gameState.starbases <= 0) {
console.log("That does it, Captain!! You are hereby relieved of command and sent to the nearest starbase for trial!");
gameState.destroyed = true;
}
break;
}
}
}
function removeKlingonAtPosition(x, y) {
for (let i = 0; i < gameState.klingonPositions.length; i++) {
if (gameState.klingonPositions[i].x === x && gameState.klingonPositions[i].y === y) {
gameState.klingonPositions.splice(i, 1);
return;
}
}
}
// Shield Control
function shieldControl() {
console.log("Energy available = " + (gameState.energy + gameState.shields));
let shieldLevel = parseFloat(prompt("Number of units to shields? "));
if (shieldLevel < 0 || shieldLevel > gameState.energy + gameState.shields) {
console.log("Shield control reports 'This is not the Federation treasury.'");
return;
}
gameState.energy += gameState.shields - shieldLevel;
gameState.shields = shieldLevel;
console.log("Deflector control room report:");
console.log(" 'Shields now at " + gameState.shields + " units per your command.'");
}
// Damage Report
function damageReport() {
console.log("Device State of Repair");
for (let i = 0; i < devices.length; i++) {
console.log(
devices[i].padEnd(25, " ") + (gameState.damage[i] >= 0 ? gameState.damage[i].toFixed(2) : "INOPERABLE")
);
}
}
// Library Computer
function libraryComputer() {
console.log("Functions available from library-computer:");
console.log(" 0 = Cumulative Galactic Record");
console.log(" 1 = Status Report");
console.log(" 2 = Photon Torpedo Data");
console.log(" 3 = Starbase Nav Data");
console.log(" 4 = Direction/Distance Calculator");
console.log(" 5 = Galaxy 'Region Name' Map");
let func = parseInt(prompt("Computer active and awaiting command? "));
switch (func) {
case 0:
cumulativeGalacticRecord();
break;
case 1:
statusReport();
break;
case 2:
photonTorpedoData();
break;
case 3:
starbaseNavData();
break;
case 4:
directionDistanceCalculator();
break;
case 5:
galaxyRegionNameMap();
break;
default:
console.log("Invalid function.");
}
}
function cumulativeGalacticRecord() {
console.log("Computer record of galaxy for quadrant " + (gameState.quadrantX + 1) + "," + (gameState.quadrantY + 1));
console.log(" 1 2 3 4 5 6 7 8");
console.log(" ----- ----- ----- ----- ----- ----- ----- -----");
for (let y = 0; y < GALAXY_SIZE; y++) {
let row = (y + 1).toString();
for (let x = 0; x < GALAXY_SIZE; x++) {
let q = galaxy[x][y];
row += " ";
row += String(q.klingons * 100 + q.starbases * 10 + q.stars).padStart(3, "0");
}
console.log(row);
}
console.log(" ----- ----- ----- ----- ----- ----- ----- -----");
}
function statusReport() {
console.log(" Status Report:");
console.log("Klingons left: " + gameState.totalKlingons);
console.log("Mission must be completed in " + gameState.timeRemaining + " stardates");
if (gameState.starbases > 0) {
console.log("The Federation is maintaining " + gameState.starbases + " starbase(s) in the galaxy");
} else {
console.log("Your stupidity has left you on your own in the galaxy -- you have no starbases left!");
}
}
function photonTorpedoData() {
if (gameState.klingonsInQuadrant <= 0) {
console.log("Science Officer Spock reports, 'Sensors show no enemy ships in this quadrant.'");
return;
}
console.log("From Enterprise to Klingon Battle Cruiser(s):");
for (let klingon of gameState.klingonPositions) {
directionDistanceCalculatorCustom(
gameState.sectorX,
gameState.sectorY,
klingon.x,
klingon.y,
"Klingon at sector " + (klingon.x + 1) + "," + (klingon.y + 1)
);
}
}
function starbaseNavData() {
if (gameState.starbasesInQuadrant <= 0) {
console.log("Mr. Spock reports, 'Sensors show no starbases in this quadrant.'");
return;
}
console.log("From Enterprise to Starbase:");
directionDistanceCalculatorCustom(
gameState.sectorX,
gameState.sectorY,
gameState.starbasePosition.x,
gameState.starbasePosition.y,
"Starbase at sector " + (gameState.starbasePosition.x + 1) + "," + (gameState.starbasePosition.y + 1)
);
}
function directionDistanceCalculator() {
let x1 = parseInt(prompt("Enter initial coordinates X1 (1-8): ")) - 1;
let y1 = parseInt(prompt("Enter initial coordinates Y1 (1-8): ")) - 1;
let x2 = parseInt(prompt("Enter final coordinates X2 (1-8): ")) - 1;
let y2 = parseInt(prompt("Enter final coordinates Y2 (1-8): ")) - 1;
directionDistanceCalculatorCustom(x1, y1, x2, y2, "Coordinates");
}
function directionDistanceCalculatorCustom(x1, y1, x2, y2, label) {
let dx = x2 - x1;
let dy = y2 - y1;
let distance = Math.sqrt(dx * dx + dy * dy);
let angle = (Math.atan2(dy, dx) * 180) / Math.PI;
if (angle < 0) angle += 360;
let direction = Math.round(angle / 45) + 1;
if (direction > 8) direction = 1;
console.log(label);
console.log("Direction = " + direction);
console.log("Distance = " + distance.toFixed(2));
}
function galaxyRegionNameMap() {
console.log(" The Galaxy");
console.log(" 1 2 3 4 5 6 7 8");
console.log(" ----- ----- ----- ----- ----- ----- ----- -----");
for (let y = 0; y < GALAXY_SIZE; y++) {
let row = (y + 1).toString();
for (let x = 0; x < GALAXY_SIZE; x++) {
let name = getQuadrantName(x, y).padEnd(5, " ").substring(0, 5);
row += " " + name;
}
console.log(row);
}
console.log(" ----- ----- ----- ----- ----- ----- ----- -----");
}
function getQuadrantName(x, y) {
let row = y < 4 ? 0 : 1;
let col = x;
return quadrantNames[row][col];
}
// Klingon Attack
function klingonAttack() {
for (let klingon of gameState.klingonPositions) {
if (klingon.energy > 0) {
let distance = Math.sqrt(
Math.pow(klingon.x - gameState.sectorX, 2) + Math.pow(klingon.y - gameState.sectorY, 2)
);
let damage = (klingon.energy / distance) * (2 + Math.random());
if (gameState.shields >= damage) {
gameState.shields -= damage;
console.log(
damage.toFixed(2) +
" unit hit on Enterprise from sector " +
(klingon.x + 1) +
"," +
(klingon.y + 1)
);
console.log(" <Shields down to " + gameState.shields.toFixed(2) + " units>");
} else {
console.log(
"*** Shields gone *** " +
damage.toFixed(2) +
" unit hit on Enterprise from sector " +
(klingon.x + 1) +
"," +
(klingon.y + 1)
);
gameState.destroyed = true;
break;
}
}
}
}
// Victory
function victory() {
console.log("Congratulations, Captain! The last Klingon battle cruiser menacing the Federation has been destroyed.");
let rating = (1000 * Math.pow(gameState.initialKlingons / (gameState.stardate - gameState.initialStardate), 2)).toFixed(
2
);
console.log("Your efficiency rating is " + rating);
}
// Defeat
function defeat() {
console.log("The Enterprise has been destroyed. The Federation will be conquered.");
}
// Resignation
function resignation() {
console.log("You have resigned your command.");
}
// Out of Time
function outOfTime() {
console.log("It is stardate " + gameState.stardate);
console.log("There were " + gameState.totalKlingons + " Klingon battle cruisers left at the end of your mission.");
console.log("The Federation is in need of a new starship commander for a similar mission.");
}
// Instructions for "Super Star Trek" Game
// Original BASIC code translated to JavaScript
"use strict";
// Function to simulate BASIC's PRINT statements with formatting
function print(text = "", tab = 0) {
if (tab > 0) {
console.log(" ".repeat(tab) + text);
} else {
console.log(text);
}
}
// Function to simulate BASIC's INPUT statement
function input(promptText) {
// For simplicity, we use prompt() for user input
return prompt(promptText);
}
// Main function to display the instructions
function displayInstructions() {
// Clear the console (simulating multiple newlines)
console.clear();
for (let i = 1; i <= 12; i++) {
print();
}
// Display the title with formatting
print("*************************************", 10);
print("* *", 10);
print("* *", 10);
print("* * * SUPER STAR TREK * * *", 10);
print("* *", 10);
print("* *", 10);
print("*************************************", 10);
for (let i = 1; i <= 8; i++) {
print();
}
// Ask the user if they need instructions
let needInstructions = input("Do you need instructions (Y/N)? ").toUpperCase();
if (needInstructions === "N") {
return;
}
print();
// Display the instructions
print(" Instructions for 'Super Star Trek'");
print();
print("1. When you see 'COMMAND ?' printed, enter one of the legal");
print(" commands (NAV, SRS, LRS, PHA, TOR, SHE, DAM, COM, or XXX).");
print("2. If you should type in an illegal command, you'll get a short");
print(" list of the legal commands printed out.");
print("3. Some commands require you to enter data (for example, the");
print(" 'NAV' command comes back with 'COURSE (1-9)?'.) If you");
print(" type in illegal data (like negative numbers), that command");
print(" will be aborted");
print();
print(" The galaxy is divided into an 8 x 8 quadrant grid,");
print("and each quadrant is further divided into an 8 x 8 sector grid.");
print();
print(" You will be assigned a starting point somewhere in the");
print("galaxy to begin a tour of duty as commander of the starship");
print("'Enterprise'; your mission: to seek and destroy the fleet of");
print("Klingon warships which are menacing the United Federation of");
print("Planets.");
print();
print(" You have the following commands available to you as captain");
print("of the starship Enterprise:");
print();
print("'NAV' Command = Warp Engine Control --");
print(" Course is in a circular numerical 4 3 2");
print(" vector arrangement as shown . . .");
print(" Integer and real values may be ...");
print(" used. (Thus, course 1.5 is half- 5 ---*--- 1");
print(" way between 1 and 2) ...");
print(" . . .");
print(" Values may approach 9.0, which 6 7 8");
print(" itself is equivalent to 1.0");
print(" COURSE");
print(" One warp factor is the size of");
print(" one quadrant. Therefore, to get");
print(" from quadrant 6,5 to 5,5, you would");
print(" use course 3, warp factor 1.");
print();
print("'SRS' Command = Short Range Sensor Scan");
print(" Shows you a scan of your present quadrant.");
print();
print(" Symbology on your sensor screen is as follows:");
print(" <*> = Your starship's position");
print(" +K+ = Klingon battle cruiser");
print(" >!< = Federation starbase (Refuel/Repair/Re-Arm here!)");
print(" * = Star");
print();
print(" A condensed 'Status Report' will also be presented.");
print();
print("'LRS' Command = Long Range Sensor Scan");
print(" Shows conditions in space for one quadrant on each side");
print(" of the Enterprise (which is in the middle of the scan).");
print(" The scan is coded in the form '###', where the units digit");
print(" is the number of stars, the tens digit is the number of");
print(" starbases, and the hundreds digit is the number of");
print(" Klingons.");
print();
print(" Example - 207 = 2 Klingons, no starbases, & 7 stars.");
print();
print("'PHA' Command = Phaser Control.");
print(" Allows you to destroy the Klingon battle cruisers by");
print(" zapping them with suitably large units of energy to");
print(" deplete their shield power. (Remember, Klingons have");
print(" phasers too!)");
print();
print("'TOR' Command = Photon Torpedo Control");
print(" Torpedo course is the same as used in Warp Engine Control.");
print(" If you hit the Klingon vessel, he is destroyed and");
print(" cannot fire back at you. If you miss, you are subject to");
print(" his phaser fire. In either case, you are also subject to");
print(" the phaser fire of all other Klingons in the quadrant.");
print();
print(" The Library-Computer ('COM' command) has an option to");
print(" compute torpedo trajectory for you (Option 2).");
print();
print("'SHE' Command = Shield Control");
print(" Defines the number of energy units to be assigned to the");
print(" shields. Energy is taken from total ship's energy. Note");
print(" that the status display total energy includes shield energy.");
print();
print("'DAM' Command = Damage Control Report");
print(" Gives the state of repair of all devices. Where a negative");
print(" 'state of repair' shows that the device is temporarily");
print(" damaged.");
print();
print("'COM' Command = Library-Computer");
print(" The Library-Computer contains six options:");
print(" Option 0 = Cumulative Galactic Record");
print(" This option shows computer memory of the results of all");
print(" previous short and long range sensor scans.");
print(" Option 1 = Status Report");
print(" This option shows the number of Klingons, Stardates,");
print(" and Starbases remaining in the game.");
print(" Option 2 = Photon Torpedo Data");
print(" Which gives directions and distance from the Enterprise");
print(" to all Klingons in your quadrant.");
print(" Option 3 = Starbase Nav Data");
print(" This option gives direction and distance to any");
print(" starbase within your quadrant.");
print(" Option 4 = Direction/Distance Calculator");
print(" This option allows you to enter coordinates for");
print(" direction/distance calculations.");
print(" Option 5 = Galactic 'Region Name' Map");
print(" This option prints the names of the sixteen major");
print(" galactic regions referred to in the game.");
}
// Call the function to display instructions
displayInstructions();
// Note: In a real game, the code would proceed to the main game logic here.
// Start the game
initializeGame();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment