trade-wars / index.html
twdooley's picture
Add 2 files
2859f67 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trade Wars: The Tariff Game</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
<style>
@keyframes float {
0% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
100% { transform: translateY(0px); }
}
.floating { animation: float 3s ease-in-out infinite; }
.pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.progress-bar {
transition: width 0.5s ease-in-out;
}
.fade-in { animation: fadeIn 0.5s ease-in; }
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
</style>
</head>
<body class="bg-gradient-to-b from-blue-50 to-blue-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="text-center mb-8 fade-in">
<h1 class="text-4xl font-bold text-blue-800 mb-2">Trade Wars</h1>
<p class="text-xl text-blue-600">See how tariffs affect your economy</p>
</header>
<!-- Game Container -->
<div class="max-w-4xl mx-auto bg-white rounded-xl shadow-lg overflow-hidden fade-in">
<!-- Game State Display -->
<div class="p-6 bg-blue-700 text-white">
<div class="flex justify-between items-center mb-4">
<div>
<h2 class="text-2xl font-bold">Year: <span id="year">1</span></h2>
<p class="text-blue-200">Set your tariff policies</p>
</div>
<div class="text-right">
<h3 class="text-xl">Wealth: $<span id="wealth">1000</span></h3>
<div class="h-2 bg-blue-400 rounded-full mt-1">
<div id="wealth-bar" class="h-full bg-yellow-300 rounded-full progress-bar" style="width: 100%"></div>
</div>
</div>
</div>
</div>
<!-- Main Game Area -->
<div class="grid md:grid-cols-3 gap-6 p-6">
<!-- Left Panel - Goods Available -->
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="text-lg font-semibold text-blue-800 mb-3 border-b pb-2">Available Goods</h3>
<div id="goods-container">
<!-- Goods will be inserted here by JavaScript -->
</div>
</div>
<!-- Center Panel - Market -->
<div class="flex flex-col">
<div class="flex-grow bg-gray-100 p-4 rounded-lg mb-4">
<h3 class="text-lg font-semibold text-blue-800 mb-3 border-b pb-2">Market Activity</h3>
<div id="market-log" class="h-64 overflow-y-auto space-y-2 text-sm">
<p class="text-gray-500 italic">Welcome to the market! Adjust tariffs and see how trade responds.</p>
</div>
</div>
<button id="next-year-btn" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition transform hover:scale-105">
Next Year <i class="fas fa-arrow-right ml-1"></i>
</button>
</div>
<!-- Right Panel - Tariff Controls -->
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="text-lg font-semibold text-blue-800 mb-3 border-b pb-2">Tariff Controls</h3>
<div id="tariff-controls">
<!-- Tariff sliders will be inserted here by JavaScript -->
</div>
<div class="mt-6 p-3 bg-yellow-50 border border-yellow-200 rounded">
<h4 class="font-medium text-yellow-800 mb-1">Total Tax Revenue:</h4>
<p class="text-xl font-bold text-yellow-600">$<span id="tax-revenue">0</span></p>
</div>
<div class="mt-4 p-3 bg-red-50 border border-red-200 rounded">
<h4 class="font-medium text-red-800 mb-1">Consumer Cost:</h4>
<p class="text-xl font-bold text-red-600">+$<span id="consumer-cost">0</span></p>
</div>
</div>
</div>
</div>
<!-- Tutorial/Explainer -->
<div id="tutorial" class="mt-8 max-w-4xl mx-auto bg-white rounded-xl shadow-lg overflow-hidden fade-in p-6">
<h2 class="text-2xl font-bold text-blue-800 mb-4">How Tariffs Affect Trade</h2>
<div class="grid md:grid-cols-3 gap-4">
<div class="p-4 border border-blue-200 rounded-lg">
<h3 class="font-bold text-blue-700 mb-2">What are tariffs?</h3>
<p class="text-gray-700">Tariffs are taxes on imported goods, meant to protect domestic industries and generate government revenue.</p>
</div>
<div class="p-4 border border-blue-200 rounded-lg">
<h3 class="font-bold text-blue-700 mb-2">Short-term effects</h3>
<p class="text-gray-700">The government collects revenue from tariffs, but consumers pay higher prices for imported goods.</p>
</div>
<div class="p-4 border border-blue-200 rounded-lg">
<h3 class="font-bold text-blue-700 mb-2">Long-term effects</h3>
<p class="text-gray-700">High tariffs reduce trade volume, leading to less variety, higher prices, and potentially trade wars.</p>
</div>
</div>
<button id="hide-tutorial-btn" class="mt-4 text-blue-600 hover:text-blue-800 font-medium">Got it! Hide this panel</button>
</div>
<!-- Results Modal (hidden initially) -->
<div id="results-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
<div class="bg-white rounded-xl p-8 max-w-md w-full mx-4">
<h2 id="results-title" class="text-2xl font-bold text-center mb-4"></h2>
<p id="results-content" class="text-gray-700 mb-6"></p>
<div class="flex justify-center">
<button id="play-again-btn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-lg">
Play Again
</button>
</div>
</div>
</div>
</div>
<script>
// Game state
const game = {
year: 1,
wealth: 1000,
maxWealth: 1000,
tradeVolume: 100,
goods: [
{ id: 1, name: "Electronics", basePrice: 300, importAmount: 30, tariff: 0, emoji: "📱" },
{ id: 2, name: "Clothing", basePrice: 100, importAmount: 50, tariff: 0, emoji: "👕" },
{ id: 3, name: "Automobiles", basePrice: 500, importAmount: 10, tariff: 0, emoji: "🚗" },
{ id: 4, name: "Food", basePrice: 50, importAmount: 80, tariff: 0, emoji: "🍎" }
],
messages: [],
totalTaxRevenue: 0,
totalConsumerCost: 0,
gameEnded: false
};
// DOM elements
const elements = {
year: document.getElementById('year'),
wealth: document.getElementById('wealth'),
wealthBar: document.getElementById('wealth-bar'),
goodsContainer: document.getElementById('goods-container'),
marketLog: document.getElementById('market-log'),
nextYearBtn: document.getElementById('next-year-btn'),
tariffControls: document.getElementById('tariff-controls'),
taxRevenue: document.getElementById('tax-revenue'),
consumerCost: document.getElementById('consumer-cost'),
tutorial: document.getElementById('tutorial'),
hideTutorialBtn: document.getElementById('hide-tutorial-btn'),
resultsModal: document.getElementById('results-modal'),
resultsTitle: document.getElementById('results-title'),
resultsContent: document.getElementById('results-content'),
playAgainBtn: document.getElementById('play-again-btn')
};
// Initialize the game
function initGame() {
renderGoods();
renderTariffControls();
updateStats();
logMessage("Welcome to Trade Wars! Adjust tariffs and see how your economy performs over 10 years.");
// Event listeners
elements.nextYearBtn.addEventListener('click', nextYear);
elements.hideTutorialBtn.addEventListener('click', () => {
elements.tutorial.classList.add('hidden');
});
elements.playAgainBtn.addEventListener('click', resetGame);
}
// Render available goods
function renderGoods() {
elements.goodsContainer.innerHTML = '';
game.goods.forEach(good => {
const priceWithTariff = Math.round(good.basePrice * (1 + good.tariff/100));
const affectedImports = Math.round(good.importAmount * (100 - good.tariff) / 100);
const goodElement = document.createElement('div');
goodElement.className = 'mb-4 p-3 bg-white rounded border border-blue-200';
goodElement.innerHTML = `
<div class="flex justify-between items-start mb-2">
<div>
<span class="text-2xl mb-1 block">${good.emoji}</span>
<h4 class="font-semibold text-blue-700">${good.name}</h4>
</div>
<div class="text-right">
<span class="text-sm text-gray-600">Imports: ${affectedImports}</span>
</div>
</div>
<div class="text-sm">
<div class="flex justify-between mb-1">
<span>Base price:</span>
<span>$${good.basePrice}</span>
</div>
<div class="flex justify-between mb-1">
<span>Tariff (${good.tariff}%):</span>
<span>+$${priceWithTariff - good.basePrice}</span>
</div>
<div class="flex justify-between font-medium">
<span>Final price:</span>
<span class="text-blue-800">$${priceWithTariff}</span>
</div>
</div>
`;
elements.goodsContainer.appendChild(goodElement);
});
}
// Render tariff controls
function renderTariffControls() {
elements.tariffControls.innerHTML = '';
game.goods.forEach(good => {
const controlElement = document.createElement('div');
controlElement.className = 'mb-4';
controlElement.innerHTML = `
<label for="tariff-${good.id}" class="block text-sm font-medium text-gray-700 mb-1">${good.emoji} ${good.name} Tariff</label>
<div class="flex items-center">
<input type="range" id="tariff-${good.id}" min="0" max="100" value="${good.tariff}"
class="w-full h-2 bg-blue-200 rounded-lg appearance-none cursor-pointer"
oninput="updateTariff(${good.id}, this.value)">
<span class="ml-2 text-sm font-medium text-blue-700 w-8">${good.tariff}%</span>
</div>
`;
elements.tariffControls.appendChild(controlElement);
});
}
// Update tariff for a good
function updateTariff(goodId, value) {
const good = game.goods.find(g => g.id === goodId);
good.tariff = parseInt(value);
document.querySelector(`#tariff-${goodId} + span`).textContent = `${value}%`;
renderGoods();
}
// Update game stats
function updateStats() {
elements.year.textContent = game.year;
elements.wealth.textContent = game.wealth;
elements.wealthBar.style.width = `${(game.wealth / game.maxWealth) * 100}%`;
// Calculate tax revenue and consumer costs
game.totalTaxRevenue = 0;
game.totalConsumerCost = 0;
game.goods.forEach(good => {
const affectedImports = Math.round(good.importAmount * (100 - good.tariff) / 100);
game.totalTaxRevenue += Math.round(affectedImports * good.basePrice * (good.tariff / 100));
game.totalConsumerCost += Math.round(affectedImports * (good.basePrice * (good.tariff / 100)));
});
elements.taxRevenue.textContent = game.totalTaxRevenue;
elements.consumerCost.textContent = game.totalConsumerCost;
}
// Log message to market log
function logMessage(message, isImportant = false) {
const messageElement = document.createElement('p');
messageElement.className = isImportant ? 'font-medium text-blue-700' : 'text-gray-700';
messageElement.textContent = message;
elements.marketLog.appendChild(messageElement);
elements.marketLog.scrollTop = elements.marketLog.scrollHeight;
}
// Advance to next year
function nextYear() {
if (game.gameEnded) return;
game.year++;
// Calculate wealth change (affected by trade volume and consumer costs)
const tradePenalty = Math.max(0, game.totalTaxRevenue * 0.3 - 50);
const wealthChange = Math.round(200 - tradePenalty - (game.totalConsumerCost * 0.1));
game.wealth = Math.max(0, game.wealth + wealthChange);
// Adjust trade volume based on total tariffs
const totalTariffs = game.goods.reduce((sum, good) => sum + good.tariff, 0);
const avgTariff = totalTariffs / game.goods.length;
game.tradeVolume = Math.max(10, 100 - avgTariff);
// Log events
logMessage(`--- Year ${game.year} ---`);
logMessage(`Applied tariffs generated $${game.totalTaxRevenue} in tax revenue.`);
logMessage(`Total consumer costs increased by $${game.totalConsumerCost}.`);
logMessage(`Your wealth ${wealthChange >= 0 ? 'increased' : 'decreased'} by $${Math.abs(wealthChange)}.`);
if (avgTariff > 60) {
logMessage("High tariffs are causing trade partners to retaliate!", true);
logMessage("Other countries have imposed tariffs on your exports too.", true);
} else if (avgTariff > 30) {
logMessage("Moderate tariffs are reducing trade volume.", true);
}
if (game.year === 5) {
logMessage("Halfway there! Notice how your tariff decisions are affecting your economy.", true);
}
// Update everything
updateStats();
renderGoods();
// Check for game end
if (game.year >= 10 || game.wealth <= 0) {
endGame();
}
}
// End the game and show results
function endGame() {
game.gameEnded = true;
const totalTariffs = game.goods.reduce((sum, good) => sum + good.tariff, 0);
const avgTariff = totalTariffs / game.goods.length;
elements.resultsTitle.textContent = game.wealth > 500 ?
"Great Economic Management!" :
game.wealth > 100 ?
"Mediocre Economic Results" :
"Economic Collapse";
if (avgTariff > 70) {
elements.resultsContent.innerHTML = `
<p>Your high tariff strategy (average ${Math.round(avgTariff)}%) significantly reduced trade and harmed your economy.</p>
<p class="mt-2">While you collected $${game.totalTaxRevenue} in tariffs, consumer costs skyrocketed and trade volume dropped to ${game.tradeVolume}% of normal.</p>
<p class="mt-4 font-medium">Excessive tariffs often lead to trade wars and economic stagnation.</p>
`;
} else if (avgTariff > 30) {
elements.resultsContent.innerHTML = `
<p>Your moderate tariff strategy (average ${Math.round(avgTariff)}%) balanced revenue collection with consumer costs.</p>
<p class="mt-2">You collected $${game.totalTaxRevenue} in tariffs but trade volume was affected (${game.tradeVolume}% of normal).</p>
<p class="mt-4 font-medium">Moderate tariffs can generate revenue but still impact economic efficiency.</p>
`;
} else {
elements.resultsContent.innerHTML = `
<p>Your low tariff strategy (average ${Math.round(avgTariff)}%) maximized trade and economic growth.</p>
<p class="mt-2">While you only collected $${game.totalTaxRevenue} in tariffs, trade flourished at ${game.tradeVolume}% of capacity.</p>
<p class="mt-4 font-medium">Free trade generally creates the most wealth but provides little direct government revenue.</p>
`;
}
if (game.wealth <= 0) {
elements.resultsContent.innerHTML += `
<p class="mt-4 text-red-600 font-bold">Your wealth reached $0! Excessive tariffs strangled your economy.</p>
`;
}
elements.resultsModal.classList.remove('hidden');
}
// Reset the game
function resetGame() {
elements.resultsModal.classList.add('hidden');
elements.tutorial.classList.remove('hidden');
elements.marketLog.innerHTML = '<p class="text-gray-500 italic">Welcome to the market! Adjust tariffs and see how trade responds.</p>';
// Reset game state
game.year = 1;
game.wealth = 1000;
game.tradeVolume = 100;
game.totalTaxRevenue = 0;
game.totalConsumerCost = 0;
game.gameEnded = false;
game.goods.forEach(good => good.tariff = 0);
// Update UI
updateStats();
renderGoods();
renderTariffControls();
}
// Start the game
initGame();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=twdooley/trade-wars" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
</html>