Spaces:
Running
Running
| <html lang="tr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Su Uyumu: Havzanın Eşiği</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| @keyframes ticker { | |
| 0% { transform: translateX(100%); } | |
| 100% { transform: translateX(-100%); } | |
| } | |
| .ticker-item { | |
| display: inline-block; | |
| padding: 0 5rem; | |
| margin-right: 5rem; | |
| animation: ticker 60s linear infinite; | |
| white-space: nowrap; | |
| line-height: 40px; | |
| position: relative; | |
| } | |
| .ticker-item:after { | |
| content: ""; | |
| position: absolute; | |
| right: -2.5rem; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| width: 1rem; | |
| height: 1rem; | |
| background-color: rgba(0,0,0,0.2); | |
| border-radius: 50%; | |
| } | |
| #event-ticker-items { | |
| display: inline-block; | |
| white-space: nowrap; | |
| height: 100%; | |
| } | |
| #event-ticker-content { | |
| overflow: hidden; | |
| position: relative; | |
| height: 40px; | |
| background: rgba(0,0,0,0.05); | |
| border-radius: 4px; | |
| width: 100%; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: #f0f4f8; | |
| } | |
| .card { | |
| background-color: white; | |
| border-radius: 0.75rem; | |
| box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); | |
| transition: all 0.3s ease-in-out; | |
| } | |
| .progress-bar-container { | |
| background-color: #e5e7eb; | |
| border-radius: 9999px; | |
| overflow: hidden; | |
| } | |
| .progress-bar { | |
| height: 100%; | |
| border-radius: 9999px; | |
| transition: width 0.5s ease-in-out, background-color 0.5s ease-in-out; | |
| } | |
| .log-entry { | |
| border-left-width: 4px; | |
| padding-left: 1rem; | |
| } | |
| .log-info { border-color: #3b82f6; } | |
| .log-success { border-color: #22c55e; } | |
| .log-warning { border-color: #f97316; } | |
| .log-danger { border-color: #ef4444; } | |
| .log-event { border-color: #a855f7; } | |
| .log-player { border-color: #14b8a6; } | |
| input[type=range] { | |
| -webkit-appearance: none; appearance: none; width: 100%; height: 8px; | |
| background: #d1d5db; border-radius: 5px; outline: none; opacity: 0.7; | |
| transition: opacity .2s; | |
| } | |
| input[type=range]:hover { opacity: 1; } | |
| input[type=range]::-webkit-slider-thumb { | |
| -webkit-appearance: none; appearance: none; width: 20px; height: 20px; | |
| background: #3b82f6; cursor: pointer; border-radius: 50%; | |
| } | |
| input[type=range]::-moz-range-thumb { | |
| width: 20px; height: 20px; background: #3b82f6; cursor: pointer; border-radius: 50%; | |
| } | |
| .btn-action { | |
| @apply w-full bg-indigo-600 text-white font-bold py-2 px-4 rounded-lg hover:bg-indigo-700 transition-colors duration-300 disabled:opacity-50 disabled:cursor-not-allowed; | |
| } | |
| .btn-action-secondary { | |
| @apply w-full bg-sky-600 text-white font-bold py-2 px-4 rounded-lg hover:bg-sky-700 transition-colors duration-300; | |
| } | |
| .action-card { | |
| @apply flex flex-col items-center justify-center p-3 border rounded-lg text-center transition-all duration-200 ease-in-out cursor-pointer; | |
| @apply bg-gray-50 hover:bg-white hover:shadow-md hover:border-blue-500; | |
| } | |
| .action-card svg { | |
| @apply w-5 h-5 mb-2; | |
| } | |
| .action-card .action-title { | |
| @apply font-semibold text-sm text-gray-800; | |
| } | |
| .action-card .action-desc { | |
| @apply text-xs text-gray-500 mt-1; | |
| } | |
| .investment-card { | |
| @apply w-full flex items-center p-3 border rounded-lg text-left transition-all duration-200 ease-in-out; | |
| @apply bg-gray-50 hover:bg-white hover:shadow-sm hover:border-sky-500 cursor-pointer; | |
| } | |
| .investment-card svg { | |
| @apply w-8 h-8 mr-4 flex-shrink-0; | |
| } | |
| .investment-card .investment-title { | |
| @apply font-semibold text-gray-800 block; | |
| } | |
| .investment-card .investment-desc { | |
| @apply text-xs text-gray-500; | |
| } | |
| .help-content h4 { | |
| @apply text-lg font-bold text-gray-800 mt-4 mb-2; | |
| } | |
| .help-content p { | |
| @apply text-sm text-gray-600 mb-2; | |
| } | |
| .help-content ul { | |
| @apply list-disc list-inside space-y-1 text-sm text-gray-600; | |
| } | |
| .help-content strong { | |
| @apply font-semibold text-gray-700; | |
| } | |
| .river-animation { | |
| position: relative; | |
| overflow: hidden; | |
| height: 60px; | |
| background: linear-gradient(to right, #e0f2fe, #bae6fd); | |
| } | |
| .water-flow { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%233b82f6" fill-opacity="0.2" d="M0,192L48,197.3C96,203,192,213,288,229.3C384,245,480,267,576,250.7C672,235,768,181,864,181.3C960,181,1056,235,1152,234.7C1248,235,1344,181,1392,154.7L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>'); | |
| background-size: cover; | |
| animation: wave 15s linear infinite; | |
| } | |
| @keyframes wave { | |
| 0% { transform: translateX(0); } | |
| 100% { transform: translateX(-50%); } | |
| } | |
| .tooltip { | |
| position: relative; | |
| } | |
| .tooltip .tooltip-text { | |
| visibility: hidden; | |
| width: 200px; | |
| background-color: #333; | |
| color: #fff; | |
| text-align: center; | |
| border-radius: 6px; | |
| padding: 5px; | |
| position: absolute; | |
| z-index: 1; | |
| bottom: 125%; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| } | |
| .tooltip:hover .tooltip-text { | |
| visibility: visible; | |
| opacity: 1; | |
| } | |
| </style> | |
| </head> | |
| <body class="p-4 md:p-8"> | |
| <div class="max-w-7xl mx-auto"> | |
| <header class="text-center mb-8"> | |
| <!-- News Ticker --> | |
| <div id="event-ticker" class="mb-4 bg-gray-100 rounded-lg overflow-hidden"> | |
| <div class="river-animation mb-4 rounded-lg"> | |
| <div class="water-flow"></div> | |
| </div> | |
| <h1 class="text-4xl font-bold text-gray-800">Su Uyumu: Havzanın Eşiği</h1> | |
| <p class="text-lg text-gray-600 mt-2">Gelişmiş Hidropolitik Simülasyon</p> | |
| <div id="event-ticker-content"> | |
| <div id="event-ticker-items"></div> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Simülasyon Ayarları --> | |
| <div id="setup-panel" class="card p-6 mb-8"> | |
| <h2 class="text-2xl font-bold text-gray-800 mb-6">Simülasyon Ayarları</h2> | |
| <div class="mb-8"> | |
| <h3 class="text-xl font-bold text-gray-700 mb-4 border-b pb-2">Genel Ayarlar</h3> | |
| <div id="global-settings" class="grid grid-cols-1 md:grid-cols-3 gap-x-6 gap-y-8"> | |
| <div> | |
| <label for="global-climate" class="block text-sm font-medium text-gray-700 flex items-center"> | |
| <span class="tooltip mr-1"> | |
| <i class="fas fa-info-circle text-blue-500"></i> | |
| <span class="tooltip-text">İklim değişikliğinin havza üzerindeki başlangıç etkisi. Zamanla artacaktır.</span> | |
| </span> | |
| Başlangıç İklim Etkisi: <span id="global-climate-val" class="font-bold ml-1">0.0</span> | |
| </label> | |
| <input type="range" id="global-climate" min="0" max="0.5" step="0.05" value="0.0" class="mt-1"> | |
| </div> | |
| <div> | |
| <label for="global-groundwater" class="block text-sm font-medium text-gray-700 flex items-center"> | |
| <span class="tooltip mr-1"> | |
| <i class="fas fa-info-circle text-blue-500"></i> | |
| <span class="tooltip-text">Havzanın toplam yeraltı suyu kapasitesi (milyar m³). Acil durumlarda kullanılır.</span> | |
| </span> | |
| Yeraltı Suyu Kapasitesi (Milyar m³): <span id="global-groundwater-val" class="font-bold ml-1">200</span> | |
| </label> | |
| <input type="range" id="global-groundwater" min="50" max="500" step="50" value="200" class="mt-1"> | |
| </div> | |
| <div> | |
| <label for="global-weather" class="block text-sm font-medium text-gray-700 flex items-center"> | |
| <span class="tooltip mr-1"> | |
| <i class="fas fa-info-circle text-blue-500"></i> | |
| <span class="tooltip-text">Aşırı hava olaylarının (sel/kuraklık) görülme olasılığı.</span> | |
| </span> | |
| Aşırı Hava Olayı Sıklığı: <span id="global-weather-val" class="font-bold ml-1">8</span>% | |
| </label> | |
| <input type="range" id="global-weather" min="0" max="20" step="1" value="8" class="mt-1"> | |
| </div> | |
| <div> | |
| <label for="max-turns" class="block text-sm font-medium text-gray-700 flex items-center"> | |
| <span class="tooltip mr-1"> | |
| <i class="fas fa-info-circle text-blue-500"></i> | |
| <span class="tooltip-text">Simülasyonun kaç tur süreceği.</span> | |
| </span> | |
| Toplam Tur Sayısı: <span id="max-turns-val" class="font-bold ml-1">100</span> | |
| </label> | |
| <input type="range" id="max-turns" min="50" max="200" step="10" value="100" class="mt-1"> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <h3 class="text-xl font-bold text-gray-700 mb-4 border-b pb-2">Ülke Ayarları</h3> | |
| <div class="mb-6 bg-blue-50 p-4 rounded-lg"> | |
| <h4 class="text-lg font-semibold text-gray-800 mb-2">Aethelgard Kontrolü</h4> | |
| <div class="flex items-center space-x-4"> | |
| <label class="flex items-center"><input type="radio" name="player_control" value="ai" checked class="mr-2"> Yapay Zeka</label> | |
| <label class="flex items-center"><input type="radio" name="player_control" value="user" class="mr-2"> Kullanıcı Kontrolü</label> | |
| </div> | |
| </div> | |
| <div id="state-settings" class="grid grid-cols-1 md:grid-cols-3 gap-x-6 gap-y-8"> | |
| </div> | |
| </div> | |
| <div class="mt-8 flex flex-col sm:flex-row justify-center gap-4"> | |
| <button id="start-sim-btn" class="w-full sm:w-auto bg-green-600 text-white font-bold py-3 px-6 rounded-lg hover:bg-green-700 transition-colors duration-300 flex items-center justify-center"> | |
| <i class="fas fa-play mr-2"></i> Simülasyonu Başlat | |
| </button> | |
| <button id="randomize-btn" class="w-full sm:w-auto bg-gray-600 text-white font-bold py-3 px-6 rounded-lg hover:bg-gray-700 transition-colors duration-300 flex items-center justify-center"> | |
| <i class="fas fa-random mr-2"></i> Rastgele Ayarla | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Simülasyon Çalışma Alanı (Başlangıçta gizli) --> | |
| <div id="simulation-panel" class="hidden"> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8"> | |
| <div class="card p-4 flex items-center"> | |
| <div class="bg-blue-100 p-3 rounded-full mr-4"> | |
| <i class="fas fa-calendar-alt text-blue-600 text-xl"></i> | |
| </div> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">Oyun Turu</p> | |
| <p id="turn-counter" class="text-2xl font-bold text-gray-800">0 / 100</p> | |
| </div> | |
| </div> | |
| <div class="card p-4 flex items-center"> | |
| <div class="bg-green-100 p-3 rounded-full mr-4"> | |
| <i class="fas fa-handshake text-green-600 text-xl"></i> | |
| </div> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">Küresel Güven Endeksi</p> | |
| <p id="trust-index" class="text-2xl font-bold text-gray-800">0.50</p> | |
| </div> | |
| </div> | |
| <div class="card p-4 flex items-center"> | |
| <div class="bg-red-100 p-3 rounded-full mr-4"> | |
| <i class="fas fa-fire text-red-600 text-xl"></i> | |
| </div> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">İklim Değişikliği Etkisi</p> | |
| <p id="climate-severity" class="text-2xl font-bold text-gray-800">0.00</p> | |
| </div> | |
| </div> | |
| </div> | |
| <main class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <div class="lg:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div id="states-container" class="md:col-span-2 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"></div> | |
| </div> | |
| <div class="flex flex-col gap-6"> | |
| <div id="basin-card" class="card p-6"> | |
| <div class="flex justify-between items-start"> | |
| <h2 id="basin-name" class="text-2xl font-bold text-gray-800 mb-4"></h2> | |
| <div class="flex items-center bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm"> | |
| <i class="fas fa-water mr-1"></i> | |
| <span id="basin-water-level"></span>% Su Seviyesi | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-4"> | |
| <div> | |
| <div class="flex justify-between text-sm font-medium text-gray-600"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-leaf mr-1 text-green-500"></i> | |
| Ekosistem Sağlığı | |
| </span> | |
| <span id="ecosystem-health-value"></span> | |
| </div> | |
| <div class="progress-bar-container mt-1 h-3"><div id="ecosystem-health-bar" class="progress-bar"></div></div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between text-sm font-medium text-gray-600"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-tint mr-1 text-blue-500"></i> | |
| Yeraltı Suyu Seviyesi | |
| </span> | |
| <span id="groundwater-level-value"></span> | |
| </div> | |
| <div class="progress-bar-container mt-1 h-3"><div id="groundwater-level-bar" class="progress-bar"></div></div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between text-sm font-medium text-gray-600"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-flask mr-1 text-purple-500"></i> | |
| Tuzluluk | |
| </span> | |
| <span id="salinity-value"></span> | |
| </div> | |
| <div class="progress-bar-container mt-1 h-3"><div id="salinity-bar" class="progress-bar"></div></div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between text-sm font-medium text-gray-600"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-industry mr-1 text-red-500"></i> | |
| Endüstriyel Kirlilik | |
| </span> | |
| <span id="industrial-pollution-value"></span> | |
| </div> | |
| <div class="progress-bar-container mt-1 h-3"><div id="industrial-pollution-bar" class="progress-bar"></div></div> | |
| </div> | |
| <div class="sm:col-span-2"> | |
| <div class="flex justify-between text-sm font-medium text-gray-600"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-tractor mr-1 text-orange-500"></i> | |
| Tarımsal Kirlilik | |
| </span> | |
| <span id="agricultural-pollution-value"></span> | |
| </div> | |
| <div class="progress-bar-container mt-1 h-3"><div id="agricultural-pollution-bar" class="progress-bar"></div></div> | |
| </div> | |
| </div> | |
| <div class="mt-4 border-t pt-4"> | |
| <p class="text-sm font-medium text-gray-600 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2 text-yellow-500"></i> | |
| Havza Su Stresi: <span id="basin-stress" class="font-bold text-lg ml-1"></span> m³/kişi/yıl | |
| </p> | |
| </div> | |
| </div> | |
| <div class="card p-6"> | |
| <h2 class="text-xl font-bold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-gamepad mr-2 text-blue-500"></i> | |
| Oyun Kontrolü | |
| </h2> | |
| <button id="next-turn-btn" class="w-full bg-blue-600 text-white font-bold py-3 px-4 rounded-lg hover:bg-blue-700 transition-colors duration-300 flex items-center justify-center"> | |
| <i class="fas fa-forward mr-2"></i> Sonraki Turu Başlat | |
| </button> | |
| <button id="reset-sim-btn" class="w-full mt-3 bg-gray-600 text-white font-bold py-3 px-4 rounded-lg hover:bg-gray-700 transition-colors duration-300 flex items-center justify-center"> | |
| <i class="fas fa-redo mr-2"></i> Sıfırla ve Yeniden Ayarla | |
| </button> | |
| <div id="game-over-message" class="mt-4 text-center font-bold text-2xl hidden"></div> | |
| </div> | |
| <div id="player-action-panel" class="card p-6 hidden"> | |
| <h2 class="text-xl font-bold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-crown mr-2 text-yellow-500"></i> | |
| Aethelgard'ın Sırası | |
| </h2> | |
| <div data-menu="main-actions"> | |
| <p class="text-sm text-gray-600 mb-4">Bir eylem kategorisi seçin:</p> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <button onclick="showSubMenu('submenu-diplomacy')" class="action-card"> | |
| <i class="fas fa-handshake text-indigo-500"></i> | |
| <span class="action-title">Diplomasi</span> | |
| <span class="action-desc">Komşularla anlaşma yap.</span> | |
| </button> | |
| <button onclick="showSubMenu('submenu-reform')" class="action-card"> | |
| <i class="fas fa-chart-line text-sky-500"></i> | |
| <span class="action-title">Ulusal Yatırım</span> | |
| <span class="action-desc">Ülke kapasitesini artır.</span> | |
| </button> | |
| <button onclick="handlePlayerAction('unilateral')" class="action-card"> | |
| <i class="fas fa-exclamation-triangle text-red-500"></i> | |
| <span class="action-title">Tek Taraflı Eylem</span> | |
| <span class="action-desc">Riskli ama karlı baraj yap.</span> | |
| </button> | |
| <button onclick="handlePlayerAction('wait')" class="action-card"> | |
| <i class="fas fa-hourglass-half text-gray-500"></i> | |
| <span class="action-title">Bekle</span> | |
| <span class="action-desc">Bu tur pas geç.</span> | |
| </button> | |
| </div> | |
| </div> | |
| <div data-menu="submenu-diplomacy" class="hidden mt-4"> | |
| <h3 class="font-semibold mb-3 text-center">Anlaşma Teklif Et</h3> | |
| <div class="space-y-3"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Hedef Ülke</label> | |
| <select id="diplomacy-target" class="w-full p-2 border rounded-md"> | |
| <option value="Baeldor">Baeldor</option> | |
| <option value="Crystalia">Crystalia</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Anlaşma Konusu</label> | |
| <select id="diplomacy-topic" class="w-full p-2 border rounded-md"> | |
| <option value="Su Tahsisi">Su Tahsisi Anlaşması</option> | |
| <option value="Kirlilik Kontrolü">Kirlilik Kontrolü Anlaşması</option> | |
| <option value="Veri Paylaşımı">Veri Paylaşımı Anlaşması</option> | |
| </select> | |
| </div> | |
| <button onclick="handlePlayerAction('diplomacy')" class="btn-action-secondary"> | |
| <i class="fas fa-paper-plane mr-2"></i> Teklif Et | |
| </button> | |
| <button onclick="showSubMenu('main-actions')" class="w-full text-sm mt-4 text-gray-600 hover:underline flex items-center justify-center"> | |
| <i class="fas fa-arrow-left mr-1"></i> Geri | |
| </button> | |
| </div> | |
| </div> | |
| <div data-menu="submenu-reform" class="hidden mt-4"> | |
| <h3 class="font-semibold mb-3 text-center">Ulusal Yatırım Seçenekleri</h3> | |
| <div class="space-y-3"> | |
| <button onclick="handlePlayerAction('reform', {type: 'Modern Sulama Teknikleri'})" class="investment-card"> | |
| <i class="fas fa-tint text-green-500"></i> | |
| <div> | |
| <span class="investment-title">Modern Sulama</span> | |
| <span class="investment-desc">Su kullanımını azaltır, ekonomiyi destekler.</span> | |
| </div> | |
| </button> | |
| <button onclick="handlePlayerAction('reform', {type: 'Su Arıtma Tesisi'})" class="investment-card"> | |
| <i class="fas fa-recycle text-blue-500"></i> | |
| <div> | |
| <span class="investment-title">Su Arıtma Tesisi</span> | |
| <span class="investment-desc">Endüstriyel kirliliği azaltır.</span> | |
| </div> | |
| </button> | |
| <button onclick="handlePlayerAction('reform', {type: 'Teknolojiye Yatırım'})" class="investment-card"> | |
| <i class="fas fa-microchip text-yellow-500"></i> | |
| <div> | |
| <span class="investment-title">Teknolojiye Yatırım</span> | |
| <span class="investment-desc">Gelecek reformların önünü açar.</span> | |
| </div> | |
| </button> | |
| <button onclick="showSubMenu('main-actions')" class="w-full text-sm mt-4 text-gray-600 hover:underline flex items-center justify-center"> | |
| <i class="fas fa-arrow-left mr-1"></i> Geri | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="card p-6 flex-grow"> | |
| <h2 class="text-xl font-bold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-scroll mr-2 text-purple-500"></i> | |
| Detaylı Olay Kaydı | |
| </h2> | |
| <div id="event-log" class="h-96 overflow-y-auto space-y-3 pr-2"></div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| </div> | |
| <!-- Yardım Menüsü Butonu ve Modalı --> | |
| <button id="help-btn" class="fixed bottom-4 right-4 bg-blue-600 text-white w-14 h-14 rounded-full shadow-lg flex items-center justify-center text-2xl font-bold z-50 hover:bg-blue-700 transition-transform transform hover:scale-110"> | |
| <i class="fas fa-question"></i> | |
| </button> | |
| <div id="help-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 hidden z-50"> | |
| <div class="bg-white rounded-lg shadow-xl max-w-3xl w-full max-h-[90vh] flex flex-col"> | |
| <div class="flex justify-between items-center p-4 border-b"> | |
| <h2 class="text-2xl font-bold text-gray-800">Yardım Menüsü</h2> | |
| <button id="close-help-btn" class="text-gray-500 hover:text-gray-800 text-3xl font-bold">×</button> | |
| </div> | |
| <div class="p-6 overflow-y-auto help-content"> | |
| <h4>Simülasyon Genel Bakış</h4> | |
| <p>Bu simülasyon, bir nehir havzasını paylaşan üç ülkenin (Aethelgard, Baeldor, Crystalia) su kaynaklarını yönetme mücadelesini modellemektedir. Amaç, 100 tur boyunca havzayı sürdürülebilir şekilde yönetmek ve çatışmadan kaçınmaktır.</p> | |
| <h4>Oyun Mekanikleri</h4> | |
| <ul> | |
| <li><strong>Tur Sistemi:</strong> Her turda tüm ülkeler sırayla hamle yapar.</li> | |
| <li><strong>İklim Değişikliği:</strong> Her turda etkisi artar ve su kaynaklarını azaltır.</li> | |
| <li><strong>Aşırı Hava Olayları:</strong> Rastgele tetiklenen sel/kuraklık gibi olaylar.</li> | |
| <li><strong>Yeraltı Suyu:</strong> Acil durumlarda kullanılabilen sınırlı kaynak.</li> | |
| </ul> | |
| <h4>Ülke Özellikleri</h4> | |
| <ul> | |
| <li><strong>Aethelgard (Yukarı Havza):</strong> Tek taraflı eylem avantajı, yüksek teknoloji</li> | |
| <li><strong>Baeldor (Orta Havza):</strong> Dengeli özellikler</li> | |
| <li><strong>Crystalia (Aşağı Havza):</strong> Su stresine daha hassas, yüksek nüfus artışı</li> | |
| </ul> | |
| <h4>Kazanma/Kaybetme Koşulları</h4> | |
| <ul> | |
| <li><strong>Zafer:</strong> 100 turu tamamlamak + yüksek güven + sağlıklı ekosistem</li> | |
| <li><strong>Su Savaşı:</strong> Güven endeksi çok düşükse ve su stresi yüksekse</li> | |
| <li><strong>Ekolojik Çöküş:</strong> Ekosistem sağlığı kritik seviyenin altına düşerse</li> | |
| </ul> | |
| <h4>Oyun İpuçları</h4> | |
| <ul> | |
| <li>Tek taraflı eylemler kısa vadeli kazanç sağlar ama uzun vadede risklidir</li> | |
| <li>Teknoloji yatırımları verimliliği artırır</li> | |
| <li>Diplomasi ile komşularla güven inşa edin</li> | |
| <li>Yeraltı suyunu son çare olarak kullanın</li> | |
| </ul> | |
| <h4>Parametrelerin Etkileri</h4> | |
| <ul> | |
| <li><strong>Ekonomi:</strong> Yatırım yapma kapasitesi</li> | |
| <li><strong>Politik İstikrar:</strong> Tek taraflı eylemlerden etkilenme</li> | |
| <li><strong>Teknoloji:</strong> Su verimliliği ve arıtma</li> | |
| <li><strong>Şeffaflık:</strong> Diplomasi başarı şansı</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // --- GLOBAL DEĞİŞKENLER --- | |
| let GLOBAL_TURNS_PASSED = 0; | |
| let MAX_GAME_TURNS = 100; | |
| let CLIMATE_CHANGE_IMPACT_SEVERITY = 0.0; | |
| let EXTREME_WEATHER_CHANCE = 0.08; | |
| const GLOBAL_WATER_STRESS_THRESHOLD = 1000; | |
| let GLOBAL_TRUST_INDEX = 0.5; | |
| let isGameOver = false; | |
| let basin; | |
| let isPlayerTurn = false; | |
| let turnProcessor; | |
| // --- SINIFLAR --- | |
| class RiverBasin { | |
| constructor(name, riparianStates, initialWaterPotential, groundwaterCapacity) { | |
| this.name = name; this.riparianStates = riparianStates; this.water_potential_m3_per_year = initialWaterPotential; | |
| this.current_water_level_pct = 100; this.ecosystem_health = 0.8; this.agreements = []; | |
| this.salinity = 0.1; this.industrial_pollution = 0.1; this.agricultural_pollution = 0.2; | |
| this.groundwater_capacity = groundwaterCapacity; | |
| this.groundwater_level = groundwaterCapacity; | |
| } | |
| apply_climate_change_impact() { | |
| this.water_potential_m3_per_year *= (1 - CLIMATE_CHANGE_IMPACT_SEVERITY * 0.005); | |
| this.current_water_level_pct -= CLIMATE_CHANGE_IMPACT_SEVERITY * 1.5; | |
| if (this.current_water_level_pct < 0) this.current_water_level_pct = 0; | |
| this.salinity += CLIMATE_CHANGE_IMPACT_SEVERITY * 0.005; | |
| this.industrial_pollution += CLIMATE_CHANGE_IMPACT_SEVERITY * 0.002; | |
| this.agricultural_pollution += CLIMATE_CHANGE_IMPACT_SEVERITY * 0.003; | |
| this.ecosystem_health -= (this.industrial_pollution + this.agricultural_pollution) * 0.05; | |
| if (this.ecosystem_health < 0) this.ecosystem_health = 0; | |
| } | |
| calculate_basin_water_stress() { | |
| const total_population_in_basin = this.riparianStates.reduce((sum, state) => sum + state.population, 0); | |
| const total_available_water = this.water_potential_m3_per_year * (this.current_water_level_pct / 100); | |
| return total_population_in_basin > 0 ? total_available_water / total_population_in_basin : 9999; | |
| } | |
| } | |
| class State { | |
| constructor(name, position, params) { | |
| this.name = name; this.position = position; | |
| this.water_use_m3_per_year = params.water_use; | |
| this.economic_development = params.econ; | |
| this.political_stability = params.stability; | |
| this.national_sovereignty_stance = params.sovereignty; | |
| this.agricultural_dependency = params.agri_dep; | |
| this.tech_level = params.tech; | |
| this.data_transparency = params.transparency; | |
| this.population_growth_rate = params.pop_growth; | |
| this.sanction_resistance = params.sanction_res; | |
| this.isPlayerControlled = params.is_player; | |
| this.population = Math.floor(20000000 + Math.random() * 10000000); | |
| this.infrastructure_level = 0.5; this.trust_with_neighbors = {}; | |
| this.diplomacy_skill = 0.4 + Math.random() * 0.3; | |
| } | |
| get_neighbors() { return basin.riparianStates.filter(s => s.name !== this.name); } | |
| update_population() { | |
| this.population *= (1 + this.population_growth_rate + (1 - this.economic_development) * 0.005); | |
| } | |
| calculate_water_stress(water_supply) { | |
| return this.population > 0 ? water_supply / this.population : 9999; | |
| } | |
| update_trust(neighbor_name, change) { | |
| if (this.trust_with_neighbors[neighbor_name] === undefined) this.trust_with_neighbors[neighbor_name] = 0.5; | |
| this.trust_with_neighbors[neighbor_name] = Math.max(0.0, Math.min(1.0, this.trust_with_neighbors[neighbor_name] + change)); | |
| let totalTrust = 0, pairCount = 0; | |
| for (const state of basin.riparianStates) { | |
| for (const neighborName in state.trust_with_neighbors) { | |
| totalTrust += state.trust_with_neighbors[neighborName]; pairCount++; | |
| } | |
| } | |
| GLOBAL_TRUST_INDEX = pairCount > 0 ? totalTrust / pairCount : 0.5; | |
| } | |
| } | |
| class Agreement { | |
| constructor(parties, agreement_type, terms, duration) { | |
| this.parties = parties; this.agreement_type = agreement_type; | |
| this.terms = terms; this.duration = duration; | |
| } | |
| } | |
| // --- OYUN MEKANİKLERİ --- | |
| function logEvent(message, type = 'info') { | |
| // Add to detailed log | |
| const logContainer = document.getElementById('event-log'); | |
| const entry = document.createElement('div'); | |
| entry.className = `log-entry log-${type} mb-2`; | |
| const icon = document.createElement('i'); | |
| icon.className = 'mr-2'; | |
| if (type === 'info') icon.className += 'fas fa-info-circle text-blue-500'; | |
| else if (type === 'success') icon.className += 'fas fa-check-circle text-green-500'; | |
| else if (type === 'warning') icon.className += 'fas fa-exclamation-circle text-yellow-500'; | |
| else if (type === 'danger') icon.className += 'fas fa-times-circle text-red-500'; | |
| else if (type === 'event') icon.className += 'fas fa-bolt text-purple-500'; | |
| else if (type === 'player') icon.className += 'fas fa-user text-teal-500'; | |
| const turnSpan = document.createElement('span'); | |
| turnSpan.className = 'font-bold text-sm'; | |
| turnSpan.textContent = `Tur ${GLOBAL_TURNS_PASSED}: `; | |
| const messageSpan = document.createElement('span'); | |
| messageSpan.className = 'text-sm text-gray-700'; | |
| messageSpan.textContent = message; | |
| entry.appendChild(icon); | |
| entry.appendChild(turnSpan); | |
| entry.appendChild(messageSpan); | |
| logContainer.prepend(entry); | |
| // Add to news ticker | |
| const tickerContainer = document.getElementById('event-ticker-items'); | |
| const tickerItem = document.createElement('div'); | |
| tickerItem.className = `ticker-item log-${type}`; | |
| const tickerIcon = document.createElement('i'); | |
| tickerIcon.className = 'mr-2'; | |
| if (type === 'info') tickerIcon.className += 'fas fa-info-circle text-blue-500'; | |
| else if (type === 'success') tickerIcon.className += 'fas fa-check-circle text-green-500'; | |
| else if (type === 'warning') tickerIcon.className += 'fas fa-exclamation-circle text-yellow-500'; | |
| else if (type === 'danger') tickerIcon.className += 'fas fa-times-circle text-red-500'; | |
| else if (type === 'event') tickerIcon.className += 'fas fa-bolt text-purple-500'; | |
| else if (type === 'player') tickerIcon.className += 'fas fa-user text-teal-500'; | |
| tickerItem.appendChild(tickerIcon); | |
| tickerItem.appendChild(document.createTextNode(message)); | |
| tickerContainer.appendChild(tickerItem); | |
| } | |
| function getRandomChoice(arr) { return arr[Math.floor(Math.random() * arr.length)]; } | |
| function initiate_diplomacy(state1, state2, agreement_type) { | |
| logEvent(`${state1.name} ve ${state2.name} arasında bir ${agreement_type} anlaşması için diplomasi başlatıldı.`, 'info'); | |
| const trustFactor = (state1.trust_with_neighbors[state2.name] + state2.trust_with_neighbors[state1.name]) / 2; | |
| const transparencyFactor = (state1.data_transparency + state2.data_transparency) / 2; | |
| const success_chance = trustFactor * 0.5 + transparencyFactor * 0.3 + (1 - CLIMATE_CHANGE_IMPACT_SEVERITY) * 0.2; | |
| if (Math.random() < success_chance) { | |
| logEvent(`Görüşmeler başarılı! ${state1.name} ve ${state2.name} anlaştı.`, 'success'); | |
| basin.agreements.push(new Agreement([state1, state2], agreement_type, {}, 20)); | |
| state1.update_trust(state2.name, 0.1); | |
| state2.update_trust(state1.name, 0.1); | |
| } else { | |
| logEvent(`${state1.name} ve ${state2.name} arasındaki görüşmeler başarısız oldu.`, 'warning'); | |
| state1.update_trust(state2.name, -0.05); | |
| state2.update_trust(state1.name, -0.05); | |
| } | |
| } | |
| function manage_unilateral_action(state, action_type) { | |
| logEvent(`${state.name} tek taraflı bir eylem deniyor: ${action_type}.`, 'event'); | |
| if (state.position === "Upstream" && action_type === "Büyük Baraj İnşa Et") { | |
| const willAct = state.isPlayerControlled ? (state.national_sovereignty_stance > 0.7) : (state.national_sovereignty_stance > 0.7 && Math.random() < 0.3); | |
| if (willAct) { | |
| logEvent(`${state.name} ulusal çıkarlarını önceleyerek büyük bir baraj inşa ediyor.`, 'danger'); | |
| state.economic_development += 0.05; | |
| basin.ecosystem_health -= 0.05; | |
| for (const s of state.get_neighbors()) { | |
| const stabilityLoss = 0.05 * (1 - s.sanction_resistance); | |
| s.political_stability -= stabilityLoss; | |
| state.update_trust(s.name, -0.15); | |
| s.update_trust(state.name, -0.15); | |
| } | |
| logEvent("Tek taraflı eylem, mansap ülkelerde olumsuz etkilere ve güvenin azalmasına neden oldu.", 'danger'); | |
| } else { | |
| logEvent(`${state.name} tek taraflı eylemden kaçındı.`, 'info'); | |
| } | |
| } | |
| } | |
| function implement_national_reforms(state, reform_type) { | |
| logEvent(`${state.name} ulusal yatırım yapıyor: ${reform_type}.`, 'event'); | |
| if (reform_type === "Modern Sulama Teknikleri") { | |
| if (state.tech_level > 0.4) { | |
| state.water_use_m3_per_year *= 0.95; | |
| state.economic_development += 0.01; | |
| logEvent(`${state.name} modern sulama tekniklerini benimsedi. Su tüketimi azaldı.`, 'success'); | |
| } else { | |
| logEvent(`${state.name}'ın teknoloji seviyesi modern sulama için yetersiz. Yatırım başarısız.`, 'warning'); | |
| } | |
| } else if (reform_type === "Su Arıtma Tesisi") { | |
| if (state.economic_development > 0.02) { | |
| basin.industrial_pollution *= 0.9; | |
| state.economic_development -= 0.02; | |
| logEvent(`${state.name} yeni bir su arıtma tesisi kurdu.`, 'success'); | |
| } else { | |
| logEvent(`${state.name}'ın ekonomisi arıtma tesisi için yetersiz.`, 'warning'); | |
| } | |
| } else if (reform_type === "Teknolojiye Yatırım") { | |
| if (state.economic_development > 0.03) { | |
| state.tech_level = Math.min(1.0, state.tech_level + 0.05); | |
| state.economic_development -= 0.03; | |
| logEvent(`${state.name} teknoloji seviyesini yükseltti.`, 'success'); | |
| } else { | |
| logEvent(`${state.name}'ın ekonomisi teknoloji yatırımı için yetersiz.`, 'warning'); | |
| } | |
| } | |
| } | |
| function triggerExtremeWeatherEvent() { | |
| const chance = Math.random(); | |
| const droughtChance = EXTREME_WEATHER_CHANCE * 0.6; | |
| const floodChance = EXTREME_WEATHER_CHANCE; | |
| if (chance < droughtChance) { | |
| basin.current_water_level_pct *= 0.7; | |
| logEvent(`AŞIRI HAVA OLAYI: Bölgeyi şiddetli bir kuraklık vurdu! Yüzey suyu seviyeleri dramatik şekilde düştü.`, 'danger'); | |
| } else if (chance < floodChance) { | |
| basin.riparianStates.forEach(s => { s.infrastructure_level *= 0.9; }); | |
| logEvent(`AŞIRI HAVA OLAYI: Büyük bir sel felaketi yaşandı! Ülkelerin su altyapıları hasar gördü.`, 'danger'); | |
| } | |
| } | |
| function stateAction_ExtractGroundwater(state) { | |
| if (basin.groundwater_level > 0) { | |
| const extractionAmount = state.water_use_m3_per_year * 0.1; | |
| const actualExtraction = Math.min(extractionAmount, basin.groundwater_level); | |
| basin.groundwater_level -= actualExtraction; | |
| state.current_turn_water_supply += actualExtraction; | |
| logEvent(`${state.name}, ${actualExtraction.toLocaleString()} m³ yeraltı suyu çekti.`, 'event'); | |
| } else { | |
| logEvent(`${state.name} yeraltı suyu çekmek istedi ancak akifer boşalmış!`, 'warning'); | |
| } | |
| } | |
| function* turnGenerator() { | |
| for (let i = 0; i < basin.riparianStates.length; i++) { | |
| const state = basin.riparianStates[i]; | |
| state.update_population(); | |
| state.current_turn_water_supply = state.water_use_m3_per_year; | |
| const currentSupply = state.current_turn_water_supply !== undefined ? state.current_turn_water_supply : state.water_use_m3_per_year; | |
| if(state.calculate_water_stress(currentSupply) < GLOBAL_WATER_STRESS_THRESHOLD * 1.2) { | |
| stateAction_ExtractGroundwater(state); | |
| } | |
| if (state.isPlayerControlled) { | |
| isPlayerTurn = true; | |
| showSubMenu('main-actions'); | |
| document.getElementById('player-action-panel').classList.remove('hidden'); | |
| yield 'player_turn'; | |
| } else { | |
| const action_choice = getRandomChoice(["Diplomacy", "National Reform", "Unilateral Action", "Wait"]); | |
| if (action_choice === "Diplomacy") { | |
| const target_state = getRandomChoice(state.get_neighbors()); | |
| if (target_state) initiate_diplomacy(state, target_state, getRandomChoice(["Su Tahsisi", "Kirlilik Kontrolü", "Veri Paylaşımı"])); | |
| } else if (action_choice === "National Reform") { | |
| implement_national_reforms(state, getRandomChoice(["Modern Sulama Teknikleri", "Su Arıtma Tesisi", "Teknolojiye Yatırım"])); | |
| } else if (action_choice === "Unilateral Action" && state.position === "Upstream") { | |
| manage_unilateral_action(state, "Büyük Baraj İnşa Et"); | |
| } | |
| } | |
| } | |
| return 'turn_end'; | |
| } | |
| function advanceTurn() { | |
| if (isGameOver || isPlayerTurn) return; | |
| const result = turnProcessor.next(); | |
| if (result.done && basin) { | |
| document.getElementById('next-turn-btn').disabled = false; | |
| updateUI(); | |
| checkWinLossConditions(); | |
| } | |
| } | |
| function handleNextTurnClick() { | |
| if (isGameOver) return; | |
| document.getElementById('next-turn-btn').disabled = true; | |
| GLOBAL_TURNS_PASSED++; | |
| CLIMATE_CHANGE_IMPACT_SEVERITY = Math.min(1.0, CLIMATE_CHANGE_IMPACT_SEVERITY + 0.01); | |
| basin.apply_climate_change_impact(); | |
| logEvent(`İklim Değişikliği Etkisi arttı: ${CLIMATE_CHANGE_IMPACT_SEVERITY.toFixed(2)}`, 'warning'); | |
| triggerExtremeWeatherEvent(); | |
| turnProcessor = turnGenerator(); | |
| advanceTurn(); | |
| } | |
| function handlePlayerAction(action, details = {}) { | |
| if (!isPlayerTurn || !basin) return; | |
| const playerState = basin.riparianStates.find(s => s.isPlayerControlled); | |
| if (!playerState) return; | |
| if (action === 'diplomacy') { | |
| const targetName = document.getElementById('diplomacy-target').value; | |
| const topic = document.getElementById('diplomacy-topic').value; | |
| const targetState = basin.riparianStates.find(s => s.name === targetName); | |
| logEvent(`Oyuncu olarak Aethelgard, ${targetName} ile ${topic} konusunda diplomasi başlattı.`, 'player'); | |
| if (targetState) initiate_diplomacy(playerState, targetState, topic); | |
| } else if (action === 'reform') { | |
| logEvent(`Oyuncu olarak Aethelgard, "${details.type}" yatırımı yaptı.`, 'player'); | |
| implement_national_reforms(playerState, details.type); | |
| } else if (action === 'unilateral') { | |
| logEvent(`Oyuncu olarak Aethelgard, tek taraflı eylem (baraj) yapmayı denedi.`, 'player'); | |
| manage_unilateral_action(playerState, "Büyük Baraj İnşa Et"); | |
| } else if (action === 'wait') { | |
| logEvent(`Oyuncu olarak Aethelgard bu tur bekledi.`, 'player'); | |
| } | |
| document.getElementById('player-action-panel').classList.add('hidden'); | |
| isPlayerTurn = false; | |
| advanceTurn(); | |
| } | |
| function checkWinLossConditions() { | |
| if (GLOBAL_TURNS_PASSED >= MAX_GAME_TURNS || (GLOBAL_TRUST_INDEX < 0.2 && basin.calculate_basin_water_stress() < GLOBAL_WATER_STRESS_THRESHOLD * 0.8) || basin.ecosystem_health < 0.1) { | |
| isGameOver = true; | |
| let msg = "", type = "info", title = "OYUN BİTTİ"; | |
| if (basin.calculate_basin_water_stress() > GLOBAL_WATER_STRESS_THRESHOLD * 1.2 && basin.ecosystem_health > 0.7 && GLOBAL_TRUST_INDEX > 0.7) { | |
| msg = "ZAFER! Bölge, sürdürülebilir su kaynakları yönetimine ulaştı ve güçlü bir işbirliği ortamı oluşturdu."; type = "success"; title = "ZAFER!"; | |
| } else if (GLOBAL_TRUST_INDEX < 0.2 && basin.calculate_basin_water_stress() < GLOBAL_WATER_STRESS_THRESHOLD * 0.8) { | |
| msg = "YENİLGİ! Şiddetli su krizi ve güvensizlik nedeniyle yaygın bir çatışma patlak verdi."; type = "danger"; title = "YENİLGİ: SU SAVAŞLARI"; | |
| } else if (basin.ecosystem_health < 0.1) { | |
| msg = "YENİLGİ! Havzanın ekosistemi, kötü yönetim ve kirlilik nedeniyle çöktü."; type = "danger"; title = "YENİLGİ: EKOLOJİK YIKIM"; | |
| } else { | |
| msg = "OYUN BİTTİ. Tüm sürdürülebilirlik ve işbirliği hedeflerine ulaşılamadı."; type = "info"; | |
| } | |
| logEvent(msg, type); | |
| const msgEl = document.getElementById('game-over-message'); | |
| msgEl.textContent = title; | |
| msgEl.className = `mt-4 text-center font-bold text-2xl ${type === 'success' ? 'text-green-500' : type === 'danger' ? 'text-red-500' : 'text-gray-700'}`; | |
| const nextTurnBtn = document.getElementById('next-turn-btn'); | |
| nextTurnBtn.disabled = true; | |
| nextTurnBtn.classList.add('opacity-50', 'cursor-not-allowed'); | |
| } | |
| } | |
| // --- ARAYÜZ GÜNCELLEME --- | |
| function updateUI() { | |
| if (!basin) return; | |
| document.getElementById('turn-counter').textContent = `${GLOBAL_TURNS_PASSED} / ${MAX_GAME_TURNS}`; | |
| document.getElementById('trust-index').textContent = GLOBAL_TRUST_INDEX.toFixed(2); | |
| document.getElementById('climate-severity').textContent = CLIMATE_CHANGE_IMPACT_SEVERITY.toFixed(2); | |
| document.getElementById('basin-name').textContent = basin.name; | |
| const updateBar = (id, value, invertColor = false) => { | |
| const bar = document.getElementById(`${id}-bar`); | |
| const valEl = document.getElementById(`${id}-value`); | |
| const percentage = value * 100; | |
| bar.style.width = `${percentage}%`; | |
| let color; | |
| if ((!invertColor && percentage > 60) || (invertColor && percentage < 30)) color = '#22c55e'; | |
| else if ((!invertColor && percentage > 30) || (invertColor && percentage < 60)) color = '#f97316'; | |
| else color = '#ef4444'; | |
| bar.style.backgroundColor = color; | |
| valEl.textContent = `${percentage.toFixed(1)}%`; | |
| }; | |
| updateBar('ecosystem-health', basin.ecosystem_health); | |
| updateBar('groundwater-level', basin.groundwater_level / basin.groundwater_capacity); | |
| updateBar('salinity', basin.salinity, true); | |
| updateBar('industrial-pollution', basin.industrial_pollution, true); | |
| updateBar('agricultural-pollution', basin.agricultural_pollution, true); | |
| document.getElementById('basin-stress').textContent = basin.calculate_basin_water_stress().toFixed(1); | |
| document.getElementById('basin-water-level').textContent = basin.current_water_level_pct.toFixed(1); | |
| const statesContainer = document.getElementById('states-container'); | |
| statesContainer.innerHTML = ''; | |
| for (const state of basin.riparianStates) { | |
| const waterStress = state.calculate_water_stress(state.current_turn_water_supply || state.water_use_m3_per_year); | |
| const stressColor = waterStress < GLOBAL_WATER_STRESS_THRESHOLD ? 'text-red-500' : waterStress < 1700 ? 'text-yellow-500' : 'text-green-500'; | |
| statesContainer.innerHTML += ` | |
| <div class="card p-5 ${state.isPlayerControlled ? 'border-2 border-blue-500' : ''}"> | |
| <h3 class="text-xl font-bold text-gray-800">${state.name} <span class="text-sm font-medium text-gray-500">(${state.position})</span></h3> | |
| <div class="mt-4 space-y-2 text-sm"> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>Su Stresi:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full" style="width: ${Math.min(100, waterStress/GLOBAL_WATER_STRESS_THRESHOLD * 50)}%; background-color: ${stressColor.replace('text-','bg-')}"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${waterStress.toFixed(1)}</span> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>Nüfus:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full bg-blue-500" style="width: ${state.population/100000000 * 100}%"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${(state.population/1000000).toFixed(1)}M</span> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>Ekonomi:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full bg-green-500" style="width: ${state.economic_development * 100}%"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${(state.economic_development * 100).toFixed(0)}%</span> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>İstikrar:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full bg-purple-500" style="width: ${state.political_stability * 100}%"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${(state.political_stability * 100).toFixed(0)}%</span> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>Teknoloji:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full bg-yellow-500" style="width: ${state.tech_level * 100}%"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${(state.tech_level * 100).toFixed(0)}%</span> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>Tarım:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full bg-orange-500" style="width: ${state.agricultural_dependency * 100}%"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${(state.agricultural_dependency * 100).toFixed(0)}%</span> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <span class="w-24 text-sm"><strong>Şeffaflık:</strong></span> | |
| <div class="w-full h-3 bg-gray-200 rounded-full ml-2"> | |
| <div class="h-full rounded-full bg-blue-400" style="width: ${state.data_transparency * 100}%"></div> | |
| </div> | |
| <span class="ml-2 text-xs font-medium">${(state.data_transparency * 100).toFixed(0)}%</span> | |
| </div> | |
| </div> | |
| </div>`; | |
| } | |
| } | |
| function showSubMenu(menuId) { | |
| const panel = document.getElementById('player-action-panel'); | |
| const menus = panel.querySelectorAll('[data-menu]'); | |
| menus.forEach(menu => { | |
| if (menu.dataset.menu === menuId) { | |
| menu.classList.remove('hidden'); | |
| } else { | |
| menu.classList.add('hidden'); | |
| } | |
| }); | |
| } | |
| // --- SİMÜLASYON KURULUMU VE KONTROLÜ --- | |
| const initialStatesData = [ | |
| { id: 'aethelgard', name: "Aethelgard", position: "Upstream", water_use: 50e9, econ: 0.7, stability: 0.8, sovereignty: 0.8, agri_dep: 0.3, tech: 0.8, transparency: 0.4, pop_growth: 0.01, sanction_res: 0.7 }, | |
| { id: 'baeldor', name: "Baeldor", position: "Midstream", water_use: 30e9, econ: 0.4, stability: 0.3, sovereignty: 0.5, agri_dep: 0.6, tech: 0.5, transparency: 0.6, pop_growth: 0.015, sanction_res: 0.4 }, | |
| { id: 'crystalia', name: "Crystalia", position: "Downstream", water_use: 70e9, econ: 0.3, stability: 0.2, sovereignty: 0.4, agri_dep: 0.8, tech: 0.3, transparency: 0.8, pop_growth: 0.02, sanction_res: 0.2 } | |
| ]; | |
| const paramConfig = { | |
| econ: { label: "Ekonomik Gelişim" }, | |
| stability: { label: "Politik İstikrar" }, | |
| sovereignty: { label: "Egemenlik Duruşu" }, | |
| agri_dep: { label: "Tarıma Bağımlılık" }, | |
| tech: { label: "Teknoloji Seviyesi" }, | |
| transparency: { label: "Veri Şeffaflığı" }, | |
| pop_growth: { label: "Nüfus Artış Hızı", min: 0.005, max: 0.03, step: 0.001 }, | |
| sanction_res: { label: "Yaptırım Direnci" } | |
| }; | |
| function createSetupUI() { | |
| document.getElementById('global-climate').addEventListener('input', (e) => { document.getElementById('global-climate-val').textContent = e.target.value; }); | |
| document.getElementById('global-groundwater').addEventListener('input', (e) => { document.getElementById('global-groundwater-val').textContent = e.target.value; }); | |
| document.getElementById('global-weather').addEventListener('input', (e) => { document.getElementById('global-weather-val').textContent = e.target.value; }); | |
| document.getElementById('max-turns').addEventListener('input', (e) => { document.getElementById('max-turns-val').textContent = e.target.value; }); | |
| const container = document.getElementById('state-settings'); | |
| container.innerHTML = ''; | |
| initialStatesData.forEach(stateData => { | |
| let slidersHTML = ''; | |
| for (const [key, config] of Object.entries(paramConfig)) { | |
| const min = config.min || 0.1; const max = config.max || 1; const step = config.step || 0.1; | |
| slidersHTML += ` | |
| <div> | |
| <label for="${stateData.id}-${key}" class="block text-sm font-medium text-gray-700">${config.label}: <span id="${stateData.id}-${key}-val">${stateData[key]}</span></label> | |
| <input type="range" id="${stateData.id}-${key}" min="${min}" max="${max}" step="${step}" value="${stateData[key]}" class="mt-1"> | |
| </div> | |
| `; | |
| } | |
| let trustSliders = '<div class="pt-4 mt-4 border-t"><h4 class="text-md font-semibold text-gray-700 mb-2">Başlangıç Güveni</h4>'; | |
| initialStatesData.forEach(neighborData => { | |
| if (stateData.id !== neighborData.id) { | |
| trustSliders += ` | |
| <div> | |
| <label for="trust-${stateData.id}-${neighborData.id}" class="block text-sm font-medium text-gray-700">${neighborData.name}'a Güven: <span id="trust-${stateData.id}-${neighborData.id}-val">0.5</span></label> | |
| <input type="range" id="trust-${stateData.id}-${neighborData.id}" min="0.1" max="0.9" step="0.1" value="0.5" class="mt-1"> | |
| </div>`; | |
| } | |
| }); | |
| trustSliders += '</div>'; | |
| container.innerHTML += ` | |
| <div class="card p-5"> | |
| <h3 class="text-xl font-bold text-gray-800">${stateData.name} (${stateData.position})</h3> | |
| <div class="mt-4 space-y-4"> | |
| ${slidersHTML} | |
| ${trustSliders} | |
| </div> | |
| </div>`; | |
| }); | |
| initialStatesData.forEach(stateData => { | |
| for (const key in paramConfig) { | |
| document.getElementById(`${stateData.id}-${key}`).addEventListener('input', (e) => { document.getElementById(`${stateData.id}-${key}-val`).textContent = e.target.value; }); | |
| } | |
| initialStatesData.forEach(neighborData => { | |
| if(stateData.id !== neighborData.id) { | |
| document.getElementById(`trust-${stateData.id}-${neighborData.id}`).addEventListener('input', (e) => { document.getElementById(`trust-${stateData.id}-${neighborData.id}-val`).textContent = e.target.value; }); | |
| } | |
| }); | |
| }); | |
| } | |
| function randomizeSettings() { | |
| // Randomize global settings | |
| document.getElementById('global-climate').value = (Math.random() * 0.5).toFixed(2); | |
| document.getElementById('global-climate-val').textContent = document.getElementById('global-climate').value; | |
| document.getElementById('global-groundwater').value = Math.floor(Math.random() * (500 - 50 + 1) / 50) * 50 + 50; | |
| document.getElementById('global-groundwater-val').textContent = document.getElementById('global-groundwater').value; | |
| document.getElementById('global-weather').value = Math.floor(Math.random() * 21); | |
| document.getElementById('global-weather-val').textContent = document.getElementById('global-weather').value; | |
| document.getElementById('max-turns').value = Math.floor(Math.random() * (200 - 50 + 1) / 10) * 10 + 50; | |
| document.getElementById('max-turns-val').textContent = document.getElementById('max-turns').value; | |
| // Randomize country settings | |
| initialStatesData.forEach(stateData => { | |
| for (const key in paramConfig) { | |
| const min = paramConfig[key].min || 0.1; | |
| const max = paramConfig[key].max || 1; | |
| const step = paramConfig[key].step || 0.1; | |
| let randomValue; | |
| if (key === 'pop_growth') { | |
| randomValue = (Math.random() * (max - min) + min).toFixed(3); | |
| } else { | |
| randomValue = (Math.random() * (max - min) + min).toFixed(1); | |
| } | |
| document.getElementById(`${stateData.id}-${key}`).value = randomValue; | |
| document.getElementById(`${stateData.id}-${key}-val`).textContent = randomValue; | |
| } | |
| // Randomize trust values | |
| initialStatesData.forEach(neighborData => { | |
| if (stateData.id !== neighborData.id) { | |
| const randomTrust = (Math.random() * (0.9 - 0.1) + 0.1).toFixed(1); | |
| document.getElementById(`trust-${stateData.id}-${neighborData.id}`).value = randomTrust; | |
| document.getElementById(`trust-${stateData.id}-${neighborData.id}-val`).textContent = randomTrust; | |
| } | |
| }); | |
| }); | |
| // Randomly select player control | |
| const playerControl = Math.random() > 0.5 ? 'user' : 'ai'; | |
| document.querySelector(`input[name="player_control"][value="${playerControl}"]`).checked = true; | |
| } | |
| function initializeSimulation() { | |
| logEvent('Simülasyon kullanıcı ayarlarıyla başlatılıyor...', 'info'); | |
| CLIMATE_CHANGE_IMPACT_SEVERITY = parseFloat(document.getElementById('global-climate').value); | |
| const groundwaterCapacity = parseFloat(document.getElementById('global-groundwater').value) * 1e9; | |
| EXTREME_WEATHER_CHANCE = parseFloat(document.getElementById('global-weather').value) / 100; | |
| MAX_GAME_TURNS = parseInt(document.getElementById('max-turns').value); | |
| const playerControlType = document.querySelector('input[name="player_control"]:checked').value; | |
| const states = initialStatesData.map(data => { | |
| let params = { water_use: data.water_use }; | |
| for (const key in paramConfig) { | |
| params[key] = parseFloat(document.getElementById(`${data.id}-${key}`).value); | |
| } | |
| params.is_player = (data.id === 'aethelgard' && playerControlType === 'user'); | |
| return new State(data.name, data.position, params); | |
| }); | |
| basin = new RiverBasin("Aethel Nehri Havzası", states, 100e9, groundwaterCapacity); | |
| basin.riparianStates.forEach(state => { | |
| const stateData = initialStatesData.find(d => d.name === state.name); | |
| state.get_neighbors().forEach(neighbor => { | |
| const neighborData = initialStatesData.find(d => d.name === neighbor.name); | |
| const trustElement = document.getElementById(`trust-${stateData.id}-${neighborData.id}`); | |
| if (trustElement) { | |
| state.trust_with_neighbors[neighbor.name] = parseFloat(trustElement.value); | |
| } | |
| }); | |
| }); | |
| document.getElementById('setup-panel').classList.add('hidden'); | |
| document.getElementById('simulation-panel').classList.remove('hidden'); | |
| updateUI(); | |
| } | |
| function resetSimulation() { | |
| GLOBAL_TURNS_PASSED = 0; CLIMATE_CHANGE_IMPACT_SEVERITY = 0.0; GLOBAL_TRUST_INDEX = 0.5; | |
| isGameOver = false; basin = null; isPlayerTurn = false; | |
| document.getElementById('event-log').innerHTML = ''; | |
| document.getElementById('game-over-message').classList.add('hidden'); | |
| const nextTurnBtn = document.getElementById('next-turn-btn'); | |
| nextTurnBtn.disabled = false; | |
| nextTurnBtn.classList.remove('opacity-50', 'cursor-not-allowed'); | |
| document.getElementById('setup-panel').classList.remove('hidden'); | |
| document.getElementById('simulation-panel').classList.add('hidden'); | |
| document.getElementById('player-action-panel').classList.add('hidden'); | |
| } | |
| document.addEventListener('DOMContentLoaded', () => { | |
| createSetupUI(); | |
| document.getElementById('start-sim-btn').addEventListener('click', initializeSimulation); | |
| document.getElementById('next-turn-btn').addEventListener('click', handleNextTurnClick); | |
| document.getElementById('reset-sim-btn').addEventListener('click', resetSimulation); | |
| document.getElementById('randomize-btn').addEventListener('click', randomizeSettings); | |
| // Help Menu | |
| const helpBtn = document.getElementById('help-btn'); | |
| const helpModal = document.getElementById('help-modal'); | |
| const closeHelpBtn = document.getElementById('close-help-btn'); | |
| helpBtn.addEventListener('click', () => { | |
| helpModal.classList.remove('hidden'); | |
| }); | |
| closeHelpBtn.addEventListener('click', () => { | |
| helpModal.classList.add('hidden'); | |
| }); | |
| helpModal.addEventListener('click', (e) => { | |
| if (e.target === helpModal) { | |
| helpModal.classList.add('hidden'); | |
| } | |
| }); | |
| }); | |
| </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=mserman/sudiplomasisi" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |