Risk Board Game Simulator

Risk Board Game Simulator

Battlefield

Last Roll Results

Battle Log

Roll # Att. Armies Def. Armies Att. Dice Def. Dice Att. Rolls Def. Rolls Att. Loss Def. Loss New Att. Armies New Def. Armies

Attacker rolled: ${attRolls.join(', ')}

Defender rolled: ${defRolls.join(', ')}

Casualties: Attacker -${attLosses}, Defender -${defLosses}

`; } /** * Adds a battle result to the log model and re-renders the table. */ function rbgsLogBattle(initial, result, newAtt, newDef) { rollCounter++; const logEntry = { roll: rollCounter, attArmies: initial.attArmies, defArmies: initial.defArmies, attDice: initial.attDiceCount, defDice: initial.defDiceCount, attRolls: result.attRolls.join(', '), defRolls: result.defRolls.join(', '), attLoss: result.attLosses, defLoss: result.defLosses, newAtt: newAtt, newDef: newDef }; battleLog.push(logEntry); rbgsRenderLogTable(); } /** * Renders the `battleLog` model into the log table. */ function rbgsRenderLogTable() { logTbody.innerHTML = ''; // Show latest first [...battleLog].reverse().forEach(log => { const row = logTbody.insertRow(); row.innerHTML = ` ${log.roll} ${log.attArmies} ${log.defArmies} ${log.attDice} ${log.defDice} ${log.attRolls} ${log.defRolls} ${log.attLoss} ${log.defLoss} ${log.newAtt} ${log.newDef} `; }); } /** * Clears the log model and table. */ function rbgsClearLog() { if (confirm("Are you sure you want to clear the entire battle log?")) { battleLog = []; rollCounter = 0; rbgsRenderLogTable(); } } // --- PDF Download Function --- async function rbgsDownloadPDF() { if (!logTable || !window.jspdf || !window.html2canvas) { console.error("PDF generation libraries or log table not found."); alert("Error: PDF generation failed."); return; } if (battleLog.length === 0) { alert("Log is empty. Nothing to download."); return; } const { jsPDF } = window.jspdf; try { // Use html2canvas to capture the styled table const canvas = await html2canvas(logTable, { scale: 2, // Higher quality useCORS: true, logging: false }); const imgData = canvas.toDataURL('image/png'); // 3. Create PDF const imgWidth = canvas.width; const imgHeight = canvas.height; // Use landscape if table is wide const orientation = imgWidth > imgHeight ? 'l' : 'p'; const doc = new jsPDF(orientation, 'mm', 'a4'); const pdfWidth = doc.internal.pageSize.getWidth(); const pdfHeight = doc.internal.pageSize.getHeight(); const margin = 10; const effectiveWidth = pdfWidth - (margin * 2); const effectiveHeight = (imgHeight * effectiveWidth) / imgWidth; let heightLeft = effectiveHeight; let position = margin; doc.setFontSize(18); doc.text("Risk Battle Simulator Log", margin, position); position += 10; heightLeft -= 10; // Add first page doc.addImage(imgData, 'PNG', margin, position, effectiveWidth, effectiveHeight); heightLeft -= (pdfHeight - margin - position); // Add new pages if content overflows while (heightLeft > 0) { position = heightLeft - effectiveHeight - margin; doc.addPage(); doc.addImage(imgData, 'PNG', margin, position, effectiveWidth, effectiveHeight); heightLeft -= (pdfHeight - margin * 2); } doc.save('Risk_Battle_Log.pdf'); } catch (error) { console.error("Error generating PDF: ", error); alert("An error occurred while generating the PDF."); } } // --- Event Listeners --- // Null checks for robust event binding if (nextBtn) nextBtn.addEventListener('click', rbgsNextTab); if (prevBtn) prevBtn.addEventListener('click', rbgsPrevTab); if (attArmiesInput) attArmiesInput.addEventListener('input', rbgsUpdateDiceOptions); if (defArmiesInput) defArmiesInput.addEventListener('input', rbgsUpdateDiceOptions); if (rollBtn) rollBtn.addEventListener('click', rbgsHandleRollOnce); if (blitzBtn) blitzBtn.addEventListener('click', rbgsHandleBlitz); if (clearLogBtn) clearLogBtn.addEventListener('click', rbgsClearLog); if (pdfDownloadBtn) pdfDownloadBtn.addEventListener('click', rbgsDownloadPDF); // --- Initialization --- function rbgsInit() { rbgsUpdateDiceOptions(); rbgsUpdateNavButtons(); } rbgsInit(); }); // End of DOMContentLoaded