top of page

<!DOCTYPE html>
<html>
<head>
   <title>Transatlantic Simulator</title>
   <style>
       @import url('https://fonts.googleapis.com/css2?family=Parisienne&display=swap');

       body {
           font-family: 'Parisienne', cursive;
           background-color: darkblue;
           color: gold;
       }

       table {
           border-collapse: collapse;
           width: 100%;
       }

       table, th, td {
           border: 1px solid lightblue;
           padding: 8px;
       }

       th {
           text-align: left;
           background-color: #f2f2f2;
       }

       tr:hover {
           background-color: #f5f5f5;
       }
   </style>
</head>
<body>
   <h1>Transatlantic Simulator</h1>
   <p>Date: <span id="date">January 1880</span></p>
   <p>Money: <span id="money">10M</span></p>
   <button id="nextMonthButton">Next month</button>
   <button id="resetButton">Reset game</button>
   <img id="yearImage" src="">
   <p>Start with 10M of money. You can build transatlantic ships and choose the length and details.</p>
   <p>Base cost: The cost of a ship depends on its length and the number of details. Each detail costs 1M.</p>

   <!-- Add a form to create a new ship -->
   <h2>Create a new ship</h2>
   <form id="newShipForm">
       <label for="shipName">Ship name:</label>
       <input type="text" id="shipName" name="shipName"><br><br>
       <label for="shipLength">Ship length:</label>
       <input type="number" id="shipLength" name="shipLength"><br><br>
       <label for="shipDetails">Number of details:</label>
       <input type="number" id="shipDetails" name="shipDetails"><br><br>
       <input type="submit" value="Create ship">
       <label for="shipStage">Ship stage:</label>
       <select id="shipStage" name="shipStage">
           <option value="1">Stage 1</option>
           <option value="2">Stage 2</option>
           <option value="3">Stage 3</option>
           <option value="4">Stage 4</option>
           <option value="5">Stage 5</option>
           <option value="6">Stage 6</option>
           <option value="7">Stage 7</option>
       </select><br><br>

   </form>

   <!-- Add a table to display the ships -->
   <h2>Ships</h2>
   <table id="shipsTable">
       <tr>
           <th>Name</th>
           <th>Length</th>
           <th>Details</th>
           <th>Popularity</th>
           <th>Profit</th>
           <th>Maintenance cost</th>
           <th>Look</th>
           <th></th>
       </tr>
   </table>

   <h2>Buy a ship</h2>
   <form id="buyShipForm">
       <label for="buyShipLength">Ship length:</label>
       <input type="number" id="buyShipLength" name="buyShipLength"><br><br>
       <label for="buyShipDetails">Number of details:</label>
       <input type="number" id="buyShipDetails" name="buyShipDetails"><br><br>
       <label for="buyShipStage">Ship stage:</label>
       <select id="buyShipStage" name="buyShipStage">
           <option value="1">Stage 1</option>
           <option value="2">Stage 2</option>
           <option value="3">Stage 3</option>
           <option value="4">Stage 4</option>
           <option value="5">Stage 5</option>
           <option value="6">Stage 6</option>
           <option value="7">Stage 7</option>
       </select><br><br>
       <input type="submit" value="Buy ship">
   </form>


<script>
// Add your JavaScript code here
let money = 10000000;
let ships = [];
let date = new Date(1880, 0);
let maxStageUnlocked = 1;
let shipsDatabase = [
   {
       name: "Titanic",
       length: 269,
       details: 11,
       stage: 3,
       year: 1912
   },
   ...
];


// Constants to control the game balance
const costPerMeter = 50000;
const costPerDetail = 1000000;
const basePopularity = 0;
const popularityPerMeter = 0.01;
const popularityPerDetail = 0.5;
const popularityLossPerMonth = 0.1;
const profitPerPopularityPoint = 100000;
const maintenanceCostPerMeter = 1000;
const maintenanceCostIncreasePerMonth = 100;

// Load the game state from local storage
function loadGameState() {
   let savedMoney = localStorage.getItem("money");
   if (savedMoney) {
     money = parseInt(savedMoney);
   }
   let savedShips = localStorage.getItem("ships");
   if (savedShips) {
     ships = JSON.parse(savedShips);
   }
   let savedDate = localStorage.getItem("date");
   if (savedDate) {
     date = new Date(savedDate);
   }
}

// Save the game state to local storage
function saveGameState() {
   localStorage.setItem("money", money);
   localStorage.setItem("ships", JSON.stringify(ships));
   localStorage.setItem("date", date.toISOString());
}

// Update the date display
function updateDateDisplay() {
   let monthNames = ["January", "February", "March", "April", "May", "June",
     "July", "August", "September", "October", "November", "December"
   ];
   let monthName = monthNames[date.getMonth()];
   let year = date.getFullYear();
   document.getElementById("date").innerHTML = monthName + " " + year;
}

// Update the money display
function updateMoneyDisplay() {
   document.getElementById("money").innerHTML = money;
}

// Calculate the cost of a ship
function calculateShipCost(length, details) {
   let cost = length * costPerMeter + details * costPerDetail;
   return cost;
}

// Calculate the popularity of a ship
function calculateShipPopularity(length, details, age) {
   let popularity = basePopularity + length * popularityPerMeter + details * popularityPerDetail - age * popularityLossPerMonth;
   return popularity;
}

// Calculate the profit of a ship
function calculateShipProfit(popularity) {
   let profit = popularity * profitPerPopularityPoint;
   return profit;
}

// Calculate the maintenance cost of a ship
function calculateMaintenanceCost(length, age) {
   let maintenanceCost = length * maintenanceCostPerMeter + age * maintenanceCostIncreasePerMonth;
   return maintenanceCost;
}

function addShip(name, length, details, stage) {
   if (stage > maxStageUnlocked) {
       alert("You haven't unlocked this stage yet.");
       return;
   }
   let stageCost = 0;
   if (stage == 2) {
       stageCost = 5000000;
   } else if (stage == 3) {
       stageCost = 10000000;
   } else if (stage == 4) {
       stageCost = 20000000;
   } else if (stage == 5) {
       stageCost = 40000000;
   } else if (stage == 6) {
       stageCost = 80000000;
   } else if (stage == 7) {
       stageCost = 160000000;
   }
   let cost = calculateShipCost(length, details) + stageCost;
   if (money >= cost) {
     money -= cost;
     let age = 0;
     let popularity = calculateShipPopularity(length, details, age);
     let profit = calculateShipProfit(popularity);
     let maintenanceCost = calculateMaintenanceCost(length, age);
     let yearCreated = date.getFullYear();
     ships.push({
       name: name,
       length: length,
       details: details,
       age: age,
       popularity: popularity,
       profit: profit,
       maintenanceCost: maintenanceCost,
       yearCreated: yearCreated,
       sold: false,
       stage: stage
     });
     updateShipsTable();
     updateMoneyDisplay();
     playSound("horn.mp3");
   } else {
     alert("You don't have enough money to build this ship.");
   }
}
// Scrap a ship
function scrapShip(index) {
   ships.splice(index, 1);
   updateShipsTable();
   playSound("destroy.mp3");
}

function updateShipsTable() {
   let table = document.getElementById("shipsTable");
   // Remove all rows except the header row
   for (let i = table.rows.length - 1; i > 0; i--) {
     table.deleteRow(i);
   }
   // Add a row for each ship
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     let row = table.insertRow(-1);
     row.insertCell(0).innerHTML = ship.name;
     row.insertCell(1).innerHTML = ship.length;
     row.insertCell(2).innerHTML = ship.details;
     row.insertCell(3).innerHTML = ship.popularity.toFixed(1);
     row.insertCell(4).innerHTML = ship.profit;
     row.insertCell(5).innerHTML = ship.maintenanceCost;
     
     // Add a cell to display the stage of the ship
     row.insertCell(6).innerHTML = "Stage " + ship.stage;
     
     let cell = row.insertCell(7);
     let button = document.createElement("button");
     button.innerHTML = "Scrap";
     button.onclick = function() {
       scrapShip(i);
     };
     cell.appendChild(button);

     cell = row.insertCell(8);
     button = document.createElement("button");
     button.innerHTML = "Sell";
     button.onclick = function() {
       sellShip(i);
     };
     cell.appendChild(button);
   }
}
// Handle the form submission
document.getElementById("newShipForm").onsubmit = function(event) {
   event.preventDefault();
   let name = document.getElementById("shipName").value;
   let length = document.getElementById("shipLength").value;
   let details = document.getElementById("shipDetails").value;
   addShip(name, length, details);
};

// Handle the next month button click
document.getElementById("nextMonthButton").onclick = function() {
   // Advance to the next month
   date.setMonth(date.getMonth() + 1);
   updateDateDisplay();

   // Update the game state for the next month
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     money += ship.profit - ship.maintenanceCost;
     ship.age += 1;
     ship.popularity = calculateShipPopularity(ship.length, ship.details, ship.age);
     ship.profit = calculateShipProfit(ship.popularity);
     ship.maintenanceCost = calculateMaintenanceCost(ship.length, ship.age);
     
     // TODO: Add code to handle random events such as a ship sinking
   }
   
   updateShipsTable();
   updateMoneyDisplay();
};

// Play a sound
function playSound(filename) {
   let audio = new Audio(filename);
   audio.play();
}

// Handle the next month button click
document.getElementById("nextMonthButton").onclick = function() {
   // Advance to the next month
   date.setMonth(date.getMonth() + 1);
   updateDateDisplay();
   updateYearImage();

   // Update the game state for the next month
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     money += ship.profit - ship.maintenanceCost;
   }
   updateMoneyDisplay();

   // Randomly sink a ship with a 5% probability
   if (Math.random() < 0.05 && ships.length > 0) {
       let index = Math.floor(Math.random() * ships.length);
       let ship = ships[index];
       alert("Oh no! The ship " + ship.name + " has sunk!");
       ships.splice(index, 1);
       updateShipsTable();
   }
};


// Load the game state and update the displays
loadGameState();
updateDateDisplay();
updateMoneyDisplay();
updateShipsTable();

// Update the year image
function updateYearImage() {
   let year = date.getFullYear();
   let imageSrc = "";
   if (year >= 2000) {
       imageSrc = "etap7.png";
   } else if (year >= 1970) {
       imageSrc = "etap6.png";
   } else if (year >= 1936) {
       imageSrc = "etap5.png";
   } else if (year >= 1923) {
       imageSrc = "etap4.png";
   } else if (year >= 1910) {
       imageSrc = "etap3.png";
   } else if (year >= 1896) {
       imageSrc = "etap2.png";
   } else if (year >= 1880) {
       imageSrc = "etap1.png";
   }
   document.getElementById("yearImage").src = imageSrc;
}

// Handle the next month button click
document.getElementById("nextMonthButton").onclick = function() {
   // Advance to the next month
   date.setMonth(date.getMonth() + 1);
   updateDateDisplay();
   updateYearImage();

   // Update the game state for the next month
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     money += ship.profit - ship.maintenanceCost;
     // TODO: Add code to handle random events such as a ship sinking
   }
   updateMoneyDisplay();
};


// Reset the game state
function resetGameState() {
   money = 10000000;
   ships = [];
   date = new Date(1880, 0);
   
   // Remove the saved game state from local storage
   localStorage.removeItem("money");
   localStorage.removeItem("ships");
   localStorage.removeItem("date");
   
   // Update the displays
   updateDateDisplay();
   updateMoneyDisplay();
   updateShipsTable();
}


// Save the game state every 30 seconds
setInterval(saveGameState, 30000);

// Handle the reset button click
document.getElementById("resetButton").onclick = function() {
  if (confirm("Are you sure you want to reset the game? This will delete your saved game.")) {
    resetGameState();
  }
};


// Play background music
playSound("song.mp3");

function unlockNextStage() {
   if (maxStageUnlocked >= 7) {
       alert("You have already unlocked all stages.");
       return;
   }
   let cost = (maxStageUnlocked + 1) * 10000000;
   if (money >= cost) {
       money -= cost;
       maxStageUnlocked += 1;
       updateMoneyDisplay();
       alert("You unlocked stage " + maxStageUnlocked + ".");
   } else {
       alert("You don't have enough money to unlock the next stage.");
   }
}

function sellShip(index) {
   let ship = ships[index];
   if (ship.sold) {
       alert("This ship has already been sold.");
       return;
   }
   let cost = calculateShipCost(ship.length, ship.details);
   let sellPrice = cost / 2;
   if (Math.random() < 0.5) {
       money += sellPrice;
       updateMoneyDisplay();
       ship.sold = true;
       updateShipsTable();
       alert("You sold the ship for " + sellPrice + ".");
   } else {
       alert("No one wants to buy this ship.");
   }
}

function buyShip(length, details, stage) {
   let ship = shipsDatabase.find(function(ship) {
       return ship.length == length && ship.details == details && ship.stage == stage && ship.year <= date.getFullYear();
   });
   if (ship) {
       let cost = calculateShipCost(length, details) / 2;
       if (Math.random() < 0.5) {
           if (money >= cost) {
               money -= cost;
               ships.push({
                   name: ship.name,
                   length: length,
                   details: details,
                   age: 0,
                   popularity: calculateShipPopularity(length, details, 0),
                   profit: calculateShipProfit(calculateShipPopularity(length, details, 0)),
                   maintenanceCost: calculateMaintenanceCost(length, 0),
                   yearCreated: date.getFullYear(),
                   sold: false,
                   stage: stage
               });
               updateShipsTable();
               updateMoneyDisplay();
               alert("You bought the " + ship.name + " for " + cost + ".");
           } else {
               alert("You don't have enough money to buy this ship.");
           }
       } else {
           alert("The seller doesn't want to sell you this ship.");
       }
   } else {
       alert("There is no ship with these characteristics for sale.");
   }
}


</script>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
   <title>Transatlantic Simulator</title>
   <style>
       @import url('https://fonts.googleapis.com/css2?family=Parisienne&display=swap');

       body {
           font-family: 'Parisienne', cursive;
           background-color: darkblue;
           color: gold;
       }

       table {
           border-collapse: collapse;
           width: 100%;
       }

       table, th, td {
           border: 1px solid lightblue;
           padding: 8px;
       }

       th {
           text-align: left;
           background-color: #f2f2f2;
       }

       tr:hover {
           background-color: #f5f5f5;
       }
   </style>
</head>
<body>
   <h1>Transatlantic Simulator</h1>
   <p>Date: <span id="date">January 1880</span></p>
   <p>Money: <span id="money">10M</span></p>
   <button id="nextMonthButton">Next month</button>
   <button id="resetButton">Reset game</button>
   <img id="yearImage" src="">
   <p>Start with 10M of money. You can build transatlantic ships and choose the length and details.</p>
   <p>Base cost: The cost of a ship depends on its length and the number of details. Each detail costs 1M.</p>

   <!-- Add a form to create a new ship -->
   <h2>Create a new ship</h2>
   <form id="newShipForm">
       <label for="shipName">Ship name:</label>
       <input type="text" id="shipName" name="shipName"><br><br>
       <label for="shipLength">Ship length:</label>
       <input type="number" id="shipLength" name="shipLength"><br><br>
       <label for="shipDetails">Number of details:</label>
       <input type="number" id="shipDetails" name="shipDetails"><br><br>
       <input type="submit" value="Create ship">
   </form>

   <!-- Add a table to display the ships -->
   <h2>Ships</h2>
   <table id="shipsTable">
       <tr>
           <th>Name</th>
           <th>Length</th>
           <th>Details</th>
           <th>Popularity</th>
           <th>Profit</th>
           <th>Maintenance cost</th>
           <th>Look</th>
           <th></th>
       </tr>
   </table>

<script>
// Add your JavaScript code here
let money = 10000000;
let ships = [];
let date = new Date(1880, 0);

// Constants to control the game balance
const costPerMeter = 50000;
const costPerDetail = 1000000;
const basePopularity = 0;
const popularityPerMeter = 0.01;
const popularityPerDetail = 0.5;
const popularityLossPerMonth = 0.1;
const profitPerPopularityPoint = 100000;
const maintenanceCostPerMeter = 1000;
const maintenanceCostIncreasePerMonth = 100;

// Load the game state from local storage
function loadGameState() {
   let savedMoney = localStorage.getItem("money");
   if (savedMoney) {
     money = parseInt(savedMoney);
   }
   let savedShips = localStorage.getItem("ships");
   if (savedShips) {
     ships = JSON.parse(savedShips);
   }
   let savedDate = localStorage.getItem("date");
   if (savedDate) {
     date = new Date(savedDate);
   }
}

// Save the game state to local storage
function saveGameState() {
   localStorage.setItem("money", money);
   localStorage.setItem("ships", JSON.stringify(ships));
   localStorage.setItem("date", date.toISOString());
}

// Update the date display
function updateDateDisplay() {
   let monthNames = ["January", "February", "March", "April", "May", "June",
     "July", "August", "September", "October", "November", "December"
   ];
   let monthName = monthNames[date.getMonth()];
   let year = date.getFullYear();
   document.getElementById("date").innerHTML = monthName + " " + year;
}

// Update the money display
function updateMoneyDisplay() {
   document.getElementById("money").innerHTML = money;
}

// Calculate the cost of a ship
function calculateShipCost(length, details) {
   let cost = length * costPerMeter + details * costPerDetail;
   return cost;
}

// Calculate the popularity of a ship
function calculateShipPopularity(length, details, age) {
   let popularity = basePopularity + length * popularityPerMeter + details * popularityPerDetail - age * popularityLossPerMonth;
   return popularity;
}

// Calculate the profit of a ship
function calculateShipProfit(popularity) {
   let profit = popularity * profitPerPopularityPoint;
   return profit;
}

// Calculate the maintenance cost of a ship
function calculateMaintenanceCost(length, age) {
   let maintenanceCost = length * maintenanceCostPerMeter + age * maintenanceCostIncreasePerMonth;
   return maintenanceCost;
}

// Add a new ship
function addShip(name, length, details) {
   let cost = calculateShipCost(length, details);
   if (money >= cost) {
     money -= cost;
     let age = 0;
     let popularity = calculateShipPopularity(length, details, age);
     let profit = calculateShipProfit(popularity);
     let maintenanceCost = calculateMaintenanceCost(length, age);
     let yearCreated = date.getFullYear();
     ships.push({
       name: name,
       length: length,
       details: details,
       age: age,
       popularity: popularity,
       profit: profit,
       maintenanceCost: maintenanceCost,
       yearCreated: yearCreated
     });
     updateShipsTable();
     updateMoneyDisplay();
     playSound("horn.mp3");
   } else {
     alert("You don't have enough money to build this ship.");
   }
}
// Scrap a ship
function scrapShip(index) {
   ships.splice(index, 1);
   updateShipsTable();
   playSound("destroy.mp3");
}

// Update the ships table
function updateShipsTable() {
   let table = document.getElementById("shipsTable");
   // Remove all rows except the header row
   for (let i = table.rows.length - 1; i > 0; i--) {
     table.deleteRow(i);
   }
   // Add a row for each ship
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     let row = table.insertRow(-1);
     row.insertCell(0).innerHTML = ship.name;
     row.insertCell(1).innerHTML = ship.length;
     row.insertCell(2).innerHTML = ship.details;
     row.insertCell(3).innerHTML = ship.popularity.toFixed(1);
     row.insertCell(4).innerHTML = ship.profit;
     row.insertCell(5).innerHTML = ship.maintenanceCost;
     
     // Add a cell to display the look of the ship
     let look = "";
     if (ship.yearCreated >= 2000) {
         look = "etap7";
     } else if (ship.yearCreated >= 1970) {
         look = "etap6";
     } else if (ship.yearCreated >= 1936) {
         look = "etap5";
     } else if (ship.yearCreated >= 1923) {
         look = "etap4";
     } else if (ship.yearCreated >= 1910) {
         look = "etap3";
     } else if (ship.yearCreated >= 1896) {
         look = "etap2";
     } else if (ship.yearCreated >= 1880) {
         look = "etap1";
     }
     row.insertCell(6).innerHTML = look;
     
     let cell = row.insertCell(7);
     let button = document.createElement("button");
     button.innerHTML = "Scrap";
     button.onclick = function() {
       scrapShip(i);
     };
     cell.appendChild(button);
   }
}
// Handle the form submission
document.getElementById("newShipForm").onsubmit = function(event) {
   event.preventDefault();
   let name = document.getElementById("shipName").value;
   let length = document.getElementById("shipLength").value;
   let details = document.getElementById("shipDetails").value;
   addShip(name, length, details);
};

// Handle the next month button click
document.getElementById("nextMonthButton").onclick = function() {
   // Advance to the next month
   date.setMonth(date.getMonth() + 1);
   updateDateDisplay();

   // Update the game state for the next month
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     money += ship.profit - ship.maintenanceCost;
     ship.age += 1;
     ship.popularity = calculateShipPopularity(ship.length, ship.details, ship.age);
     ship.profit = calculateShipProfit(ship.popularity);
     ship.maintenanceCost = calculateMaintenanceCost(ship.length, ship.age);
     
     // TODO: Add code to handle random events such as a ship sinking
   }
   
   updateShipsTable();
   updateMoneyDisplay();
};

// Play a sound
function playSound(filename) {
   let audio = new Audio(filename);
   audio.play();
}

// Handle the next month button click
document.getElementById("nextMonthButton").onclick = function() {
   // Advance to the next month
   date.setMonth(date.getMonth() + 1);
   updateDateDisplay();
   updateYearImage();

   // Update the game state for the next month
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     money += ship.profit - ship.maintenanceCost;
   }
   updateMoneyDisplay();

   // Randomly sink a ship with a 5% probability
   if (Math.random() < 0.05 && ships.length > 0) {
       let index = Math.floor(Math.random() * ships.length);
       let ship = ships[index];
       alert("Oh no! The ship " + ship.name + " has sunk!");
       ships.splice(index, 1);
       updateShipsTable();
   }
};


// Load the game state and update the displays
loadGameState();
updateDateDisplay();
updateMoneyDisplay();
updateShipsTable();

// Update the year image
function updateYearImage() {
   let year = date.getFullYear();
   let imageSrc = "";
   if (year >= 2000) {
       imageSrc = "etap7.png";
   } else if (year >= 1970) {
       imageSrc = "etap6.png";
   } else if (year >= 1936) {
       imageSrc = "etap5.png";
   } else if (year >= 1923) {
       imageSrc = "etap4.png";
   } else if (year >= 1910) {
       imageSrc = "etap3.png";
   } else if (year >= 1896) {
       imageSrc = "etap2.png";
   } else if (year >= 1880) {
       imageSrc = "etap1.png";
   }
   document.getElementById("yearImage").src = imageSrc;
}

// Handle the next month button click
document.getElementById("nextMonthButton").onclick = function() {
   // Advance to the next month
   date.setMonth(date.getMonth() + 1);
   updateDateDisplay();
   updateYearImage();

   // Update the game state for the next month
   for (let i = 0; i < ships.length; i++) {
     let ship = ships[i];
     money += ship.profit - ship.maintenanceCost;
     // TODO: Add code to handle random events such as a ship sinking
   }
   updateMoneyDisplay();
};


// Reset the game state
function resetGameState() {
   money = 10000000;
   ships = [];
   date = new Date(1880, 0);
   
   // Remove the saved game state from local storage
   localStorage.removeItem("money");
   localStorage.removeItem("ships");
   localStorage.removeItem("date");
   
   // Update the displays
   updateDateDisplay();
   updateMoneyDisplay();
   updateShipsTable();
}


// Save the game state every 30 seconds
setInterval(saveGameState, 30000);

// Handle the reset button click
document.getElementById("resetButton").onclick = function() {
  if (confirm("Are you sure you want to reset the game? This will delete your saved game.")) {
    resetGameState();
  }
};


// Play background music
playSound("song.mp3");

</script>
</body>
</html>

bottom of page