MM60

A Gift from Cash Guy Starts Your Financial Journey! Invest it Well and Good Luck!

Market Dashboard!

Q1 ROLL UP NEXT
Net Worth: $2000
Early Investor Time
Make A Trade Below Or Trigger Next Price Phase
DOGECAR
SPACE
Yearly Chart
Portfolio
DOGECAR
$500
Shares: 0
Value: $0
SPACE
$1000
Shares: 0
Value: $0
CASH
$2000
Loan Management
Loan Balance: $0
Total Interest Paid: $0
Paycheck Roll
'); // Apply specific class based on type notification.className = ''; if (type === 'bond-purchase') { notification.classList.add('notification-bond-purchase'); } else if (type === 'paycheck') { notification.classList.add('notification-paycheck'); } notification.style.display = 'block'; const duration = message.includes('
') ? 4000 : 2000; // Shorter duration setTimeout(() => { notification.style.display = 'none'; gameState.notifications = []; }, duration); // Notifications stay on screen shorter } // Initialize Trade Inputs function initTradeInputs() { const tradeAmounts = []; for (let i = 0; i <= 10; i++) { tradeAmounts.push(i); } for (let i = 10; i <= 100; i += 10) { tradeAmounts.push(i); } ['dogecar', 'space'].forEach((asset) => { const select = document.getElementById(`${asset}-trade`); select.innerHTML = ''; // Clear existing options tradeAmounts.forEach((amount) => { const option = document.createElement('option'); option.value = amount; option.textContent = amount; select.appendChild(option); }); select.value = 0; }); } // Update Asset Information function updateAssetInfo(asset) { document.getElementById(`${asset}-current-price`).textContent = `$${gameState[asset].currentPrice}`; document.getElementById(`${asset}-shares`).textContent = gameState[asset].shares; document.getElementById(`${asset}-position`).textContent = `$${gameState[asset].positionValue}`; document.getElementById(`${asset}-price-change`).innerHTML = gameState[asset].priceChangeText || ''; } // Updating Price Change Indicators function updatePriceChangeIndicators(asset) { const assetData = gameState[asset]; const previousPrice = assetData.previousPrice !== undefined ? assetData.previousPrice : assetData.currentPrice; const priceChange = assetData.currentPrice - previousPrice; // Update previousPrice for next calculation assetData.previousPrice = assetData.currentPrice; // Determine direction and color let arrow = ''; let color = ''; if (priceChange > 0) { arrow = '▲'; color = 'green'; } else if (priceChange < 0) { arrow = '▼'; color = 'red'; } else { arrow = ''; color = 'yellow'; } // Handle same price if (priceChange === 0) { assetData.priceChangeText = `0`; } else { assetData.priceChangeText = `${arrow} $${Math.abs(priceChange)}`; } // Store last price movement for price update area if (priceChange !== 0) { assetData.lastPriceMovement = `${arrow} ${Math.abs(priceChange)}`; } else { assetData.lastPriceMovement = ''; } // Update price history for chart assetData.priceHistory.push(assetData.currentPrice); updateAssetInfo(asset); } // Update Quarter Display function updateQuarterDisplay() { const quarterDisplay = document.getElementById('quarter-display'); const rollEarningsArea = document.getElementById('roll-earnings-area'); if (gameState.phase === 'roll') { quarterDisplay.innerHTML = `Q${gameState.currentQuarter} Roll Up Next`; rollEarningsArea.className = 'roll-town'; rollEarningsArea.innerHTML = `
Roll Town!
It's the Middle of the Quarter
DOGECAR
SPACE
`;
} else {
quarterDisplay.innerHTML = `Q${gameState.currentQuarter} Earnings Up Next`;
rollEarningsArea.className = 'earnings-time';
rollEarningsArea.innerHTML = `
Quarterly Results Out
Companies Report Earnings Results
DOGECAR
SPACE
`;
}
// Move stock movement calculation to the roll and earnings area
['dogecar', 'space'].forEach((asset) => {
const movement = gameState[asset].lastPriceMovement;
document.getElementById(`${asset}-price-movement`).innerHTML = movement || '';
});
}
// Handle Next Price Phase Button
document.getElementById('next-price-phase-btn').addEventListener('click', function () {
if (gameState.phase === 'roll') {
performRollPhase();
} else if (gameState.phase === 'earnings') {
performEarningsPhase();
}
});
// Perform Roll Phase
function performRollPhase() {
clearRollEarningsArea();
document.getElementById('next-price-phase-btn').disabled = true;
rollForAsset('dogecar', () => {
setTimeout(() => {
rollForAsset('space', () => {
document.getElementById('next-price-phase-btn').disabled = false;
advanceGamePhase();
updateQuarterDisplay();
updatePriceChart();
});
}, 1000);
});
}
// Perform Earnings Phase
function performEarningsPhase() {
clearRollEarningsArea();
document.getElementById('next-price-phase-btn').disabled = true;
revealEarnings('dogecar', () => {
setTimeout(() => {
revealEarnings('space', () => {
document.getElementById('next-price-phase-btn').disabled = false;
advanceGamePhase();
updateQuarterDisplay();
applyLoanInterest(0.10); // 10% interest
updateNetWorth();
updatePriceChart();
// Show Paycheck button after Q1 Earnings and after Q2 and Q3 Earnings
if (gameState.currentQuarter === 1 || gameState.currentQuarter === 2 || gameState.currentQuarter === 3) {
if (gameState.phase === 'earnings') {
document.getElementById('paycheck-section').style.display = 'block';
}
} else {
document.getElementById('paycheck-section').style.display = 'none';
}
});
}, 2000);
});
}
// Roll for a Specific Asset
function rollForAsset(asset, callback) {
const dieOutcomes = asset === 'dogecar' ? ['News Bomb', 'News Bomb', '▲$200', '▲$100', '▼$100', '▼$200'] :
['News Bomb', 'News Bomb', '▲$300', '▲$200', '▼$200', '▼$300'];
const randomIndex = Math.floor(Math.random() * dieOutcomes.length);
const outcomeText = dieOutcomes[randomIndex];
if (outcomeText === 'News Bomb') {
displayNewsBombDie(asset, () => {
setTimeout(() => {
triggerNewsBomb(asset, callback);
}, 1000); // Display dice for 1 second
});
} else {
const priceChange = parseInt(outcomeText.replace('▲$', '').replace('▼$', '')) * (outcomeText.includes('▼') ? -1 : 1);
gameState[asset].currentPrice += priceChange;
if (gameState[asset].currentPrice < 0) gameState[asset].currentPrice = 0;
gameState[asset].previousPositionValue = gameState[asset].positionValue;
gameState[asset].positionValue = gameState[asset].currentPrice * gameState[asset].shares;
updateAssetInfo(asset);
updatePriceChangeIndicators(asset);
displayRollResult(asset, outcomeText);
if (gameState[asset].currentPrice === 0) {
handleStockZero(asset);
}
handleStockSplit(asset);
updateNetWorth();
callback();
}
}
// Display News Bomb Die
function displayNewsBombDie(asset, callback) {
const dieImg = document.getElementById(`${asset}-die`);
dieImg.src = `https://cdn.shopify.com/s/files/1/0845/5110/6858/files/${capitalize(asset)}_Die_News_Bomb.png?v=1730005575`;
dieImg.style.display = 'block';
dieImg.style.filter = 'drop-shadow(0 0 10px #fff)';
const newsBombImg = document.getElementById(`${asset}-newsbomb`);
newsBombImg.style.display = 'none'; // Hide news bomb image during die display
setTimeout(() => {
dieImg.src = '';
dieImg.style.display = 'none';
callback();
}, 1000); // Display die for 1 second
}
// Trigger News Bomb
function triggerNewsBomb(asset, callback) {
const newsValue = getRandomNewsValue(asset);
const upDown = newsValue > 0 ? 'Up' : 'Down';
const absValue = Math.abs(newsValue);
const newsBombImgUrl = `https://cdn.shopify.com/s/files/1/0845/5110/6858/files/${capitalize(asset)}_News_${upDown}_${absValue}.png?v=1729904195`;
displayNewsBombResult(asset, newsBombImgUrl);
gameState[asset].currentPrice += newsValue;
if (gameState[asset].currentPrice < 0) gameState[asset].currentPrice = 0;
gameState[asset].previousPositionValue = gameState[asset].positionValue;
gameState[asset].positionValue = gameState[asset].currentPrice * gameState[asset].shares;
updateAssetInfo(asset);
updatePriceChangeIndicators(asset);
if (gameState[asset].currentPrice === 0) {
handleStockZero(asset);
}
handleStockSplit(asset);
updateNetWorth();
callback();
}
// Get Random News Value
function getRandomNewsValue(asset) {
const availableNewsBombs = newsBombs[asset].filter(value => !gameState[asset].usedNewsBombs.includes(value));
if (availableNewsBombs.length === 0) {
gameState[asset].usedNewsBombs = [];
return getRandomNewsValue(asset);
}
const randomIndex = Math.floor(Math.random() * availableNewsBombs.length);
const newsValue = availableNewsBombs[randomIndex];
gameState[asset].usedNewsBombs.push(newsValue);
return newsValue;
}
// Display News Bomb Result
function displayNewsBombResult(asset, newsBombImgUrl) {
const newsBombImg = document.getElementById(`${asset}-newsbomb`);
newsBombImg.src = newsBombImgUrl;
newsBombImg.style.display = 'block';
const dieImg = document.getElementById(`${asset}-die`);
dieImg.src = '';
dieImg.style.display = 'none';
newsBombImg.style.filter = 'drop-shadow(0 0 10px #fff)';
}
// Display Roll Result
function displayRollResult(asset, outcome) {
const newsBombImg = document.getElementById(`${asset}-newsbomb`);
newsBombImg.src = '';
newsBombImg.style.display = 'none';
const dieImg = document.getElementById(`${asset}-die`);
const [symbol, value] = outcome.split('$');
const upDown = symbol === '▲' ? 'Up' : 'Down';
const imgUrl = `https://cdn.shopify.com/s/files/1/0845/5110/6858/files/${capitalize(asset)}_${upDown}_${value}.png?v=1730005575`;
dieImg.src = imgUrl;
dieImg.style.display = 'block';
dieImg.style.filter = 'drop-shadow(0 0 10px #fff)';
setTimeout(() => {
dieImg.src = '';
dieImg.style.display = 'none';
}, 1000); // Hide die after 1 second
}
// Capitalize Word
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
}
// Handle Stock Going to $0
function handleStockZero(asset) {
const lostShares = gameState[asset].shares;
const hadShares = lostShares !== 0;
// Player loses all shares and short shares
gameState[asset].shares = 0;
gameState[asset].positionValue = 0;
// Decrease IPO price by $100
gameState[asset].lastIPOPrice -= 100;
if (gameState[asset].lastIPOPrice < 100) {
gameState[asset].lastIPOPrice = 100; // Minimum IPO price
}
gameState[asset].currentPrice = gameState[asset].lastIPOPrice;
gameState[asset].previousPrice = gameState[asset].currentPrice;
updateAssetInfo(asset);
updatePriceChangeIndicators(asset);
if (hadShares) {
// Notification with Jazzy Dimecat
showNotification(`
You lost ${lostShares} shares of ${capitalize(asset)}! Jazzy Dimecat has re-IPO'd ${capitalize(asset)} at $${gameState[asset].currentPrice}.`, 'stock-zero'); } else { // Notification without losing shares showNotification(`${capitalize(asset)} has been re-IPO'd at $${gameState[asset].currentPrice}.`, 'stock-zero'); } } // Handle Stock Splits function handleStockSplit(asset) { const splitPrice = asset === 'dogecar' ? 1000 : asset === 'space' ? 2000 : Infinity; if (gameState[asset].currentPrice >= splitPrice) { let dividendPerShare = 0; const preSplitPrice = gameState[asset].currentPrice; // Check if price ends with odd $100 const hundredsPlace = Math.floor(preSplitPrice / 100) % 10; if (hundredsPlace % 2 === 1) { dividendPerShare = 100; } // Pay dividend if (dividendPerShare > 0) { const totalDividend = dividendPerShare * gameState[asset].shares; const totalShortDividend = dividendPerShare * Math.abs(gameState[asset].shares < 0 ? gameState[asset].shares : 0); gameState.cashBalance += totalDividend; gameState.cashBalance -= totalShortDividend; // Notification for dividend showNotification(`

You received a dividend of $${totalDividend} from ${capitalize(asset)}.`, 'dividend'); if (totalShortDividend > 0) { showNotification(`

You paid a dividend of $${totalShortDividend} on your short position of ${capitalize(asset)}.`, 'dividend'); } } // Double shares gameState[asset].shares *= 2; // Adjust price: divide by 2 and round down to nearest $100 let newPrice = Math.floor(preSplitPrice / 2 / 100) * 100; gameState[asset].currentPrice = newPrice; gameState[asset].positionValue = gameState[asset].shares * gameState[asset].currentPrice; updateAssetInfo(asset); updatePriceChangeIndicators(asset); // Notification with image showNotification(`

${capitalize(asset)} has split! Your shares have doubled and price halved.`, 'stock-split'); } } // Reveal Earnings for a Specific Asset function revealEarnings(asset, callback) { const earningsValue = getRandomEarningsValue(asset); const upDown = earningsValue > 0 ? 'Up' : 'Down'; const absValue = Math.abs(earningsValue); const earningsImgUrl = `https://cdn.shopify.com/s/files/1/0845/5110/6858/files/${capitalize(asset)}_Earnings_${upDown}_${absValue}.png?v=1730005575`; displayEarningsResult(asset, earningsImgUrl); // Adjust price gameState[asset].currentPrice += earningsValue; if (gameState[asset].currentPrice < 0) gameState[asset].currentPrice = 0; // Update position value gameState[asset].previousPositionValue = gameState[asset].positionValue; gameState[asset].positionValue = gameState[asset].currentPrice * gameState[asset].shares; updateAssetInfo(asset); updatePriceChangeIndicators(asset); // Handle stock going to $0 if (gameState[asset].currentPrice === 0) { handleStockZero(asset); } // Handle stock splits handleStockSplit(asset); updateNetWorth(); callback(); } // Get Random Earnings Value function getRandomEarningsValue(asset) { const availableEarnings = earningsCards[asset].filter(value => !gameState[asset].usedEarnings.includes(value)); if (availableEarnings.length === 0) { gameState[asset].usedEarnings = []; return getRandomEarningsValue(asset); } const randomIndex = Math.floor(Math.random() * availableEarnings.length); const earningsValue = availableEarnings[randomIndex]; gameState[asset].usedEarnings.push(earningsValue); return earningsValue; } // Display Earnings Result function displayEarningsResult(asset, earningsImgUrl) { const newsBombImg = document.getElementById(`${asset}-newsbomb`); newsBombImg.src = earningsImgUrl; newsBombImg.style.display = 'block'; const dieImg = document.getElementById(`${asset}-die`); dieImg.src = ''; dieImg.style.display = 'none'; newsBombImg.style.filter = 'drop-shadow(0 0 10px #fff)'; } // Clear Roll and Earnings Area function clearRollEarningsArea() { ['dogecar', 'space'].forEach(asset => { const newsBombImg = document.getElementById(`${asset}-newsbomb`); newsBombImg.src = ''; newsBombImg.style.display = 'none'; const dieImg = document.getElementById(`${asset}-die`); dieImg.src = ''; dieImg.style.display = 'none'; }); } // Advance Game Phase function advanceGamePhase() { if (gameState.phase === 'roll') { gameState.phase = 'earnings'; // Add phase label for the chart gameState.pricePhases.push(`Q${gameState.currentQuarter} Roll`); } else { gameState.phase = 'roll'; gameState.currentQuarter += 1; updateShortLimits(); updateLoanCap(); // Add phase label for the chart gameState.pricePhases.push(`Q${gameState.currentQuarter - 1} Earnings`); } // Show Paycheck button after Q1 Earnings and after Q2 and Q3 Earnings if (gameState.currentQuarter === 1 || gameState.currentQuarter === 2 || gameState.currentQuarter === 3) { if (gameState.phase === 'earnings') { document.getElementById('paycheck-section').style.display = 'block'; } } else { document.getElementById('paycheck-section').style.display = 'none'; } } // Handle Trade Buttons document.querySelectorAll('.buy-button').forEach((button) => { button.addEventListener('click', function () { const asset = this.dataset.asset; const tradeAmount = parseInt(document.getElementById(`${asset}-trade`).value); executeTrade(asset, tradeAmount); }); }); document.querySelectorAll('.sell-button').forEach((button) => { button.addEventListener('click', function () { const asset = this.dataset.asset; const tradeAmount = parseInt(document.getElementById(`${asset}-trade`).value); executeTrade(asset, -tradeAmount); }); }); // All In and Cash Out Buttons document.querySelectorAll('.all-in-button').forEach(button => { button.addEventListener('click', function () { const asset = this.dataset.asset; // Buy maximum shares of the selected asset buyMaxShares(asset); }); }); document.querySelectorAll('.cash-out-button').forEach(button => { button.addEventListener('click', function () { const asset = this.dataset.asset; sellAllShares(asset); }); }); // Max Buy and Max Sell Buttons document.querySelectorAll('.max-buy-button').forEach(button => { button.addEventListener('click', function () { const asset = this.dataset.asset; buyMaxShares(asset); }); }); document.querySelectorAll('.max-sell-button').forEach(button => { button.addEventListener('click', function () { const asset = this.dataset.asset; sellMaxShares(asset); }); }); // Sell Max Shares Function function sellMaxShares(asset) { const assetData = gameState[asset]; const currentShares = gameState[asset].shares; const maxShort = gameState[asset].shortLimit; let sellAmount = 0; if (currentShares > 0) { sellAmount = currentShares; } else if (currentShares < 0) { sellAmount = Math.abs(currentShares); } const proceeds = sellAmount * gameState[asset].currentPrice; gameState.cashBalance += proceeds; gameState[asset].shares += sellAmount > 0 ? -sellAmount : sellAmount; gameState[asset].positionValue = gameState[asset].shares * gameState[asset].currentPrice; updateAssetInfo(asset); document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); } // Sell All Shares Function function sellAllShares(asset) { const assetData = gameState[asset]; const sellAmount = assetData.shares; if (sellAmount === 0) { showNotification(`No shares to sell for ${capitalize(asset)}.`, 'trade-error'); return; } const proceeds = sellAmount * gameState[asset].currentPrice; gameState.cashBalance += proceeds; gameState[asset].shares = 0; gameState[asset].positionValue = 0; updateAssetInfo(asset); document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); } // Buy Max Shares Function function buyMaxShares(asset) { const assetData = gameState[asset]; const maxShares = Math.floor(gameState.cashBalance / assetData.currentPrice); if (maxShares > 0) { gameState[asset].shares += maxShares; gameState.cashBalance -= maxShares * assetData.currentPrice; gameState[asset].positionValue = gameState[asset].shares * gameState[asset].currentPrice; updateAssetInfo(asset); document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); } else { showNotification('Insufficient cash to buy any shares.', 'trade-error'); } } // Execute Trade Function with Short Selling function executeTrade(asset, amount) { const assetData = gameState[asset]; const cost = assetData.currentPrice * amount; // Check if the player has enough cash (only if buying) if (amount > 0 && gameState.cashBalance - cost < -gameState.loanBalance) { // Allow negative cash only due to loan interest showNotification('Insufficient cash to make this purchase.', 'trade-error'); return; } // Check short selling limits const potentialShares = assetData.shares + amount; if (potentialShares < -gameState[asset].shortLimit) { showNotification(`You cannot short more than ${gameState[asset].shortLimit} shares of ${capitalize(asset)}.`, 'trade-error'); return; } // Update shares and cash balance gameState[asset].shares += amount; gameState.cashBalance -= cost; // Update position value gameState[asset].positionValue = gameState[asset].shares * gameState[asset].currentPrice; // Update UI updateAssetInfo(asset); document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); } // Loan Management function applyLoanInterest(rate) { if (gameState.loanBalance > 0) { const interest = Math.round(gameState.loanBalance * rate); gameState.totalInterestPaid += interest; gameState.loanBalance += interest; gameState.cashBalance -= interest; // Deduct directly from cash gameState.lastInterestCharged = interest; document.getElementById('loan-balance').textContent = gameState.loanBalance; document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; document.getElementById('total-interest-paid').textContent = `Total Interest Paid: $${gameState.totalInterestPaid}`; updateNetWorth(); updateCashBalance(); } else { gameState.lastInterestCharged = 0; } } document.getElementById('take-loan').addEventListener('click', function () { const loanAmount = parseInt(document.getElementById('loan-amount').value); if (isNaN(loanAmount) || loanAmount < 1000 || loanAmount > 20000) { showNotification(`Please enter a valid loan amount between $1000 and $20000.`, 'loan-error'); return; } if (gameState.loanBalance + loanAmount > gameState.loanCap) { showNotification(`

You cannot take out more than your loan cap of $${gameState.loanCap}.`, 'loan-error'); return; } gameState.loanBalance += loanAmount; gameState.cashBalance += loanAmount; document.getElementById('loan-balance').textContent = gameState.loanBalance; document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); showNotification(`You have taken a loan of $${loanAmount}.`, 'loan'); }); document.getElementById('repay-loan').addEventListener('click', function () { const repayAmount = parseInt(document.getElementById('loan-amount').value); if (isNaN(repayAmount) || repayAmount < 1000 || repayAmount > 20000) { showNotification(`Please enter a valid repayment amount between $1000 and $20000.`, 'loan-error'); return; } if (repayAmount > gameState.loanBalance) { showNotification(`You cannot repay more than your loan balance.`, 'loan-error'); return; } if (repayAmount > gameState.cashBalance) { showNotification(`Insufficient cash to repay the loan.`, 'loan-error'); return; } gameState.loanBalance -= repayAmount; gameState.cashBalance -= repayAmount; document.getElementById('loan-balance').textContent = gameState.loanBalance; document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); showNotification(`You have repaid $${repayAmount} of your loan.`, 'loan'); }); // Max Loan and Max Pay Buttons document.getElementById('max-loan').addEventListener('click', function () { const availableLoan = gameState.loanCap - gameState.loanBalance; if (availableLoan <= 0) { showNotification(`

You have reached your loan cap of $${gameState.loanCap}.`, 'loan-error'); return; } gameState.loanBalance += availableLoan; gameState.cashBalance += availableLoan; document.getElementById('loan-balance').textContent = gameState.loanBalance; document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); showNotification(`You have taken a loan of $${availableLoan}.`, 'loan'); }); document.getElementById('max-pay').addEventListener('click', function () { const repayAmount = Math.min(gameState.loanBalance, gameState.cashBalance); if (repayAmount <= 0) { showNotification(`No loan to repay or insufficient cash.`, 'loan-error'); return; } gameState.loanBalance -= repayAmount; gameState.cashBalance -= repayAmount; document.getElementById('loan-balance').textContent = gameState.loanBalance; document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateNetWorth(); showNotification(`You have repaid $${repayAmount} of your loan.`, 'loan'); }); // Paycheck Roll Section document.getElementById('roll-paycheck-btn').addEventListener('click', function () { let multiplier = 1; let rollOutcome = rollPaycheckDie(); while (rollOutcome === '2X') { multiplier *= 2; showNotification(`You rolled 2X! Your multiplier is now ${multiplier}X. Rolling again...`, 'paycheck'); rollOutcome = rollPaycheckDie(); } let paycheckAmount = parseInt(rollOutcome) * multiplier; gameState.cashBalance += paycheckAmount; document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; showNotification(`

You received a paycheck of $${paycheckAmount}!`, 'paycheck'); updateNetWorth(); // Disable the button after use this.disabled = true; }); function rollPaycheckDie() { const outcomes = ['400', '500', '600', '700', '800', '900', '1000', '2X']; const randomIndex = Math.floor(Math.random() * outcomes.length); return outcomes[randomIndex]; } // Event Listeners for Initial Screens document.getElementById('start-game-btn').addEventListener('click', function () { document.getElementById('splash-screen').style.opacity = '0'; setTimeout(function () { document.getElementById('splash-screen').style.display = 'none'; showWelcomeScreen(); }, 500); }); function showWelcomeScreen() { document.getElementById('welcome-screen').style.display = 'flex'; setTimeout(function () { document.getElementById('speech-bubble').style.transform = 'scale(1)'; }, 1000); } document.getElementById('collect-button').addEventListener('click', function () { document.getElementById('welcome-screen').style.opacity = '0'; setTimeout(function () { document.getElementById('welcome-screen').style.display = 'none'; showGameDashboard(); }, 500); }); function showGameDashboard() { document.getElementById('game-dashboard').style.display = 'flex'; initGame(); } // Initialize the game function initGame() { initTradeInputs(); updateShortLimits(); updateLoanCap(); ['dogecar', 'space'].forEach((asset) => { gameState[asset].previousPositionValue = gameState[asset].positionValue; updateAssetInfo(asset); updatePriceChangeIndicators(asset); }); document.getElementById('cash-balance').textContent = `$${gameState.cashBalance}`; updateQuarterDisplay(); document.getElementById('loan-balance').textContent = gameState.loanBalance; document.getElementById('total-interest-paid').textContent = `Total Interest Paid: $${gameState.totalInterestPaid}`; // Hide paycheck section initially; it will be shown after Q1 Earnings document.getElementById('paycheck-section').style.display = 'none'; // Initialize Price Chart initPriceChart(); } // Initialize Price Chart let priceChart; function initPriceChart() { const ctx = document.getElementById('price-chart').getContext('2d'); priceChart = new Chart(ctx, { type: 'line', data: { labels: gameState.pricePhases, datasets: [ { label: 'Dogecar', data: gameState.dogecar.priceHistory, borderColor: '#ffa9c9', backgroundColor: 'rgba(255, 169, 201, 0.2)', borderWidth: 3, pointRadius: 5, pointBackgroundColor: '#ffa9c9', tension: 0, // Straight lines }, { label: 'Space', data: gameState.space.priceHistory, borderColor: '#bb66d0', backgroundColor: 'rgba(187, 102, 208, 0.2)', borderWidth: 3, pointRadius: 5, pointBackgroundColor: '#bb66d0', tension: 0, // Straight lines }, ], }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { suggestedMin: 0, suggestedMax: 2000, ticks: { stepSize: 200, color: '#fff', }, grid: { color: '#444', }, }, x: { ticks: { color: '#fff', }, grid: { color: '#444', }, }, }, plugins: { legend: { labels: { color: '#fff', }, }, }, }, }); } // Update Price Chart function updatePriceChart() { priceChart.data.labels = gameState.pricePhases; priceChart.data.datasets[0].data = gameState.dogecar.priceHistory; priceChart.data.datasets[1].data = gameState.space.priceHistory; priceChart.update(); } // Include Chart.js library const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/chart.js'; document.head.appendChild(script); script.onload = function () { initPriceChart(); }; // Ensure the paycheck button appears only after Q1 and Q2 Earnings function checkPaycheckAvailability() { if (gameState.currentQuarter === 1 || gameState.currentQuarter === 2 || gameState.currentQuarter === 3) { document.getElementById('paycheck-section').style.display = 'block'; } else { document.getElementById('paycheck-section').style.display = 'none'; } } // Ensure that loan interest is deducted correctly and cash can go negative only due to loan interest function updateCashBalance() { // This function can be used to ensure cash balance doesn't go negative except for loan interest if (gameState.cashBalance < 0 && gameState.loanBalance <= 0) { gameState.cashBalance = 0; showNotification('Your cash balance cannot go negative.', 'trade-error'); } } // Handle Cash Balance Corrections function handleCashBalance() { if (gameState.cashBalance < 0) { // Only allow negative cash if it's due to loan interest if (gameState.loanBalance > 0) { // Already handled in applyLoanInterest } else { gameState.cashBalance = 0; showNotification('Your cash balance cannot go negative.', 'trade-error'); } } } // Final Cash Balance Correction after net worth update function updateNetWorth() { const { cashBalance, loanBalance, dogecar, space } = gameState; const totalAssets = dogecar.positionValue + space.positionValue; gameState.netWorth = cashBalance + totalAssets - loanBalance; let netWorthChange = dogecar.positionValue + space.positionValue - dogecar.previousPositionValue - space.previousPositionValue - gameState.lastInterestCharged; netWorthChange = Math.round(netWorthChange / 100) * 100; // Round to nearest $100 const netWorthChangeElement = document.getElementById('net-worth-change'); if (netWorthChange > 0) { netWorthChangeElement.innerHTML = `▲ $${netWorthChange}`; } else if (netWorthChange < 0) { netWorthChangeElement.innerHTML = `▼ $${Math.abs(netWorthChange)}`; } else { netWorthChangeElement.innerHTML = `$0`; } document.getElementById('net-worth').textContent = `Net Worth: $${gameState.netWorth}`; gameState.previousNetWorth = gameState.netWorth; handleCashBalance(); }