Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ER Emergency Room Game</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"> | |
| <style> | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| .pulse { | |
| animation: pulse 1.5s infinite; | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| .heartbeat { | |
| animation: heartbeat 1.5s ease-in-out infinite both; | |
| } | |
| @keyframes heartbeat { | |
| 0% { transform: scale(1); } | |
| 30% { transform: scale(1.1); } | |
| 50% { transform: scale(1); } | |
| 60% { transform: scale(1.1); } | |
| 100% { transform: scale(1); } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 font-sans"> | |
| <div id="app" class="min-h-screen flex flex-col"> | |
| <!-- Main Menu --> | |
| <div id="main-menu" class="flex flex-col items-center justify-center flex-grow p-4"> | |
| <div class="bg-white rounded-xl shadow-2xl p-8 max-w-2xl w-full text-center"> | |
| <div class="flex justify-center mb-6"> | |
| <i class="fas fa-hospital text-red-500 text-6xl"></i> | |
| </div> | |
| <h1 class="text-4xl font-bold text-gray-800 mb-2">ER EMERGENCY ROOM</h1> | |
| <p class="text-gray-600 mb-8">Test your skills as an ER doctor in this fast-paced medical drama game</p> | |
| <div class="space-y-4"> | |
| <button onclick="startGame()" 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"> | |
| <i class="fas fa-play mr-2"></i> Start Shift | |
| </button> | |
| <button onclick="showInstructions()" class="w-full bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-3 px-4 rounded-lg transition transform hover:scale-105"> | |
| <i class="fas fa-info-circle mr-2"></i> Instructions | |
| </button> | |
| <button onclick="showCredits()" class="w-full bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-3 px-4 rounded-lg transition transform hover:scale-105"> | |
| <i class="fas fa-star mr-2"></i> Credits | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Instructions --> | |
| <div id="instructions" class="hidden flex-col items-center justify-center flex-grow p-4"> | |
| <div class="bg-white rounded-xl shadow-2xl p-8 max-w-2xl w-full"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold text-gray-800">Game Instructions</h2> | |
| <button onclick="backToMenu()" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times text-2xl"></i> | |
| </button> | |
| </div> | |
| <div class="space-y-4 text-gray-700"> | |
| <div class="flex items-start"> | |
| <div class="bg-blue-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-user-md text-blue-600"></i> | |
| </div> | |
| <p>You play as an ER doctor at County General Hospital</p> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="bg-red-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-clock text-red-600"></i> | |
| </div> | |
| <p>Each case has a time limit - make decisions quickly!</p> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="bg-green-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-heartbeat text-green-600"></i> | |
| </div> | |
| <p>Examine patients, order tests, and choose treatments</p> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="bg-yellow-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-chart-line text-yellow-600"></i> | |
| </div> | |
| <p>Your score depends on patient outcomes and efficiency</p> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="bg-purple-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-procedures text-purple-600"></i> | |
| </div> | |
| <p>Different cases will challenge your medical knowledge</p> | |
| </div> | |
| </div> | |
| <div class="mt-8"> | |
| <button onclick="backToMenu()" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg"> | |
| <i class="fas fa-arrow-left mr-2"></i> Back to Menu | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Credits --> | |
| <div id="credits" class="hidden flex-col items-center justify-center flex-grow p-4"> | |
| <div class="bg-white rounded-xl shadow-2xl p-8 max-w-2xl w-full"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold text-gray-800">Credits</h2> | |
| <button onclick="backToMenu()" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times text-2xl"></i> | |
| </button> | |
| </div> | |
| <div class="space-y-6 text-gray-700"> | |
| <div> | |
| <h3 class="font-bold text-lg text-blue-600 mb-2">Inspired by</h3> | |
| <p>ER - The iconic medical drama television series</p> | |
| </div> | |
| <div> | |
| <h3 class="font-bold text-lg text-green-600 mb-2">Created by</h3> | |
| <p>Your friendly neighborhood web developer</p> | |
| </div> | |
| <div> | |
| <h3 class="font-bold text-lg text-purple-600 mb-2">Special Thanks</h3> | |
| <ul class="list-disc pl-5 space-y-1"> | |
| <li>Dr. Mark Greene</li> | |
| <li>Dr. John Carter</li> | |
| <li>Nurse Carol Hathaway</li> | |
| <li>Dr. Peter Benton</li> | |
| <li>All the ER staff at County General</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="mt-8"> | |
| <button onclick="backToMenu()" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg"> | |
| <i class="fas fa-arrow-left mr-2"></i> Back to Menu | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Game Screen --> | |
| <div id="game-screen" class="hidden flex-col flex-grow"> | |
| <!-- Header --> | |
| <div class="bg-blue-800 text-white p-4 shadow-md"> | |
| <div class="container mx-auto flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-hospital text-2xl"></i> | |
| <h1 class="text-xl font-bold">COUNTY GENERAL HOSPITAL - EMERGENCY ROOM</h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="bg-blue-700 px-3 py-1 rounded-lg"> | |
| <i class="fas fa-clock mr-1"></i> | |
| <span id="time-remaining">05:00</span> | |
| </div> | |
| <div class="bg-blue-700 px-3 py-1 rounded-lg"> | |
| <i class="fas fa-heart mr-1"></i> | |
| <span id="score">0</span> pts | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Game Area --> | |
| <div class="flex-grow container mx-auto p-4 flex flex-col"> | |
| <!-- Patient Info --> | |
| <div id="patient-info" class="bg-white rounded-lg shadow-md p-6 mb-4 fade-in"> | |
| <div class="flex justify-between items-start mb-4"> | |
| <div> | |
| <h2 class="text-2xl font-bold text-gray-800" id="patient-name">Loading patient...</h2> | |
| <div class="flex space-x-4 mt-2"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-venus-mars text-gray-500 mr-1"></i> | |
| <span id="patient-gender">-</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i class="fas fa-birthday-cake text-gray-500 mr-1"></i> | |
| <span id="patient-age">-</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i class="fas fa-thermometer-half text-gray-500 mr-1"></i> | |
| <span id="patient-temp">-</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i class="fas fa-heartbeat text-gray-500 mr-1"></i> | |
| <span id="patient-hr">-</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i class="fas fa-lungs text-gray-500 mr-1"></i> | |
| <span id="patient-rr">-</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i class="fas fa-tint text-gray-500 mr-1"></i> | |
| <span id="patient-bp">-</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-red-100 text-red-800 px-3 py-1 rounded-full text-sm font-semibold heartbeat" id="patient-status"> | |
| CRITICAL | |
| </div> | |
| </div> | |
| <div class="border-t pt-4"> | |
| <h3 class="font-bold text-lg text-gray-700 mb-2">Chief Complaint</h3> | |
| <p id="chief-complaint" class="text-gray-800">-</p> | |
| </div> | |
| </div> | |
| <!-- Action Area --> | |
| <div class="flex-grow grid grid-cols-1 md:grid-cols-3 gap-4"> | |
| <!-- Examination --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <h3 class="font-bold text-lg text-blue-700 mb-3 border-b pb-2 flex items-center"> | |
| <i class="fas fa-stethoscope mr-2"></i> Examination | |
| </h3> | |
| <div class="space-y-2" id="exam-options"> | |
| <!-- Options will be added by JS --> | |
| </div> | |
| </div> | |
| <!-- Tests --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <h3 class="font-bold text-lg text-green-700 mb-3 border-b pb-2 flex items-center"> | |
| <i class="fas fa-vial mr-2"></i> Order Tests | |
| </h3> | |
| <div class="space-y-2" id="test-options"> | |
| <!-- Options will be added by JS --> | |
| </div> | |
| </div> | |
| <!-- Treatment --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <h3 class="font-bold text-lg text-red-700 mb-3 border-b pb-2 flex items-center"> | |
| <i class="fas fa-syringe mr-2"></i> Treatment | |
| </h3> | |
| <div class="space-y-2" id="treatment-options"> | |
| <!-- Options will be added by JS --> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Results/Feedback --> | |
| <div id="feedback-area" class="mt-4 hidden"> | |
| <div class="bg-white rounded-lg shadow-md p-4 border-l-4 border-blue-500"> | |
| <h3 class="font-bold text-lg text-gray-800 mb-2">Results</h3> | |
| <p id="feedback-text" class="text-gray-700">-</p> | |
| <div class="mt-3"> | |
| <button onclick="nextCase()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> | |
| <i class="fas fa-arrow-right mr-1"></i> Next Patient | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Shift Summary --> | |
| <div id="shift-summary" class="hidden flex-col items-center justify-center flex-grow p-4"> | |
| <div class="bg-white rounded-xl shadow-2xl p-8 max-w-2xl w-full"> | |
| <div class="text-center mb-6"> | |
| <i class="fas fa-clipboard-check text-5xl text-blue-500 mb-4"></i> | |
| <h2 class="text-3xl font-bold text-gray-800">Shift Summary</h2> | |
| <p class="text-gray-600">Your performance at County General ER</p> | |
| </div> | |
| <div class="space-y-6 mb-8"> | |
| <div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-user-injured text-red-500 mr-3 text-xl"></i> | |
| <span class="font-medium">Patients Treated</span> | |
| </div> | |
| <span class="font-bold text-lg" id="summary-patients">0</span> | |
| </div> | |
| <div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-heart text-green-500 mr-3 text-xl"></i> | |
| <span class="font-medium">Lives Saved</span> | |
| </div> | |
| <span class="font-bold text-lg" id="summary-saved">0</span> | |
| </div> | |
| <div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-trophy text-yellow-500 mr-3 text-xl"></i> | |
| <span class="font-medium">Total Score</span> | |
| </div> | |
| <span class="font-bold text-lg" id="summary-score">0</span> | |
| </div> | |
| <div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-star text-blue-500 mr-3 text-xl"></i> | |
| <span class="font-medium">Performance Rating</span> | |
| </div> | |
| <span class="font-bold text-lg" id="summary-rating">-</span> | |
| </div> | |
| </div> | |
| <div class="flex flex-col space-y-3"> | |
| <button onclick="startGame()" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg"> | |
| <i class="fas fa-redo mr-2"></i> Another Shift | |
| </button> | |
| <button onclick="backToMenu()" class="w-full bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-3 px-4 rounded-lg"> | |
| <i class="fas fa-home mr-2"></i> Main Menu | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Game State | |
| const gameState = { | |
| score: 0, | |
| patientsTreated: 0, | |
| livesSaved: 0, | |
| currentCase: null, | |
| timeLeft: 300, // 5 minutes in seconds | |
| timer: null, | |
| cases: [ | |
| { | |
| name: "Michael Scott", | |
| gender: "Male", | |
| age: "42", | |
| temp: "101.2°F", | |
| hr: "112 bpm", | |
| rr: "22/min", | |
| bp: "150/90", | |
| status: "Critical", | |
| complaint: "Severe chest pain radiating to left arm, sweating profusely", | |
| exams: [ | |
| { text: "Listen to heart sounds", correct: true, feedback: "You hear a faint murmur and irregular rhythm" }, | |
| { text: "Check pupil response", correct: false, feedback: "Pupils are normal but this doesn't help diagnose the chest pain" }, | |
| { text: "Palpate abdomen", correct: false, feedback: "Abdomen is soft and non-tender - not relevant here" } | |
| ], | |
| tests: [ | |
| { text: "ECG", correct: true, feedback: "ECG shows ST elevation in leads II, III, aVF - inferior MI" }, | |
| { text: "Complete blood count", correct: false, feedback: "CBC won't show acute cardiac ischemia" }, | |
| { text: "Troponin level", correct: true, feedback: "Troponin is elevated at 5.2 ng/mL (normal <0.04)" } | |
| ], | |
| treatments: [ | |
| { text: "Aspirin 325mg", correct: true, feedback: "Given - helps prevent further clotting" }, | |
| { text: "Nitroglycerin SL", correct: true, feedback: "BP stable after NTG - pain decreased slightly" }, | |
| { text: "Morphine 2mg IV", correct: true, feedback: "Pain better after morphine" }, | |
| { text: "Call cardiology for cath lab", correct: true, feedback: "Cardiology on the way - patient needs PCI ASAP" }, | |
| { text: "IV fluids bolus", correct: false, feedback: "Not indicated with elevated BP and pulmonary congestion" } | |
| ], | |
| diagnosis: "Acute Myocardial Infarction (Inferior STEMI)" | |
| }, | |
| { | |
| name: "Sarah Johnson", | |
| gender: "Female", | |
| age: "28", | |
| temp: "98.6°F", | |
| hr: "88 bpm", | |
| rr: "18/min", | |
| bp: "110/70", | |
| status: "Stable", | |
| complaint: "Sudden onset of severe headache described as 'worst headache of my life'", | |
| exams: [ | |
| { text: "Neurological exam", correct: true, feedback: "Patient has neck stiffness and photophobia" }, | |
| { text: "Check for Kernig/Brudzinski signs", correct: true, feedback: "Positive Brudzinski sign present" }, | |
| { text: "Abdominal exam", correct: false, feedback: "Abdomen is benign - not relevant to headache" } | |
| ], | |
| tests: [ | |
| { text: "CT head without contrast", correct: true, feedback: "CT shows diffuse subarachnoid hemorrhage" }, | |
| { text: "Lumbar puncture", correct: true, feedback: "LP shows xanthochromia - confirms SAH" }, | |
| { text: "Chest X-ray", correct: false, feedback: "Chest is clear - not helpful for headache" } | |
| ], | |
| treatments: [ | |
| { text: "Pain medication", correct: false, feedback: "Need to find cause before treating pain" }, | |
| { text: "Nimodipine", correct: true, feedback: "Started to prevent vasospasm" }, | |
| { text: "Neurosurgery consult", correct: true, feedback: "Neurosurgeon evaluating for possible aneurysm" }, | |
| { text: "Blood pressure control", correct: true, feedback: "BP maintained at 120-140 systolic" } | |
| ], | |
| diagnosis: "Subarachnoid Hemorrhage (likely ruptured aneurysm)" | |
| }, | |
| { | |
| name: "David Miller", | |
| gender: "Male", | |
| age: "65", | |
| temp: "102.3°F", | |
| hr: "118 bpm", | |
| rr: "28/min", | |
| bp: "90/60", | |
| status: "Critical", | |
| complaint: "Fever, cough with green sputum, shortness of breath for 3 days", | |
| exams: [ | |
| { text: "Auscultate lungs", correct: true, feedback: "Crackles heard in right lower lobe" }, | |
| { text: "Check for egophony", correct: true, feedback: "Positive egophony in RLL" }, | |
| { text: "Abdominal exam", correct: false, feedback: "Not relevant for respiratory symptoms" } | |
| ], | |
| tests: [ | |
| { text: "Chest X-ray", correct: true, feedback: "RLL infiltrate consistent with pneumonia" }, | |
| { text: "Blood cultures", correct: true, feedback: "Drawn before antibiotics" }, | |
| { text: "CBC with diff", correct: true, feedback: "WBC 18,000 with left shift" }, | |
| { text: "ECG", correct: false, feedback: "Normal sinus tachycardia - not helpful here" } | |
| ], | |
| treatments: [ | |
| { text: "Oxygen therapy", correct: true, feedback: "SpO2 improves to 94% on 2L NC" }, | |
| { text: "IV fluids", correct: true, feedback: "Given for hypotension" }, | |
| { text: "Antibiotics (Zosyn)", correct: true, feedback: "Broad spectrum coverage started" }, | |
| { text: "Antipyretics", correct: true, feedback: "Tylenol given for fever" }, | |
| { text: "Cough suppressant", correct: false, feedback: "Not indicated - cough helps clear secretions" } | |
| ], | |
| diagnosis: "Community-Acquired Pneumonia with Sepsis" | |
| }, | |
| { | |
| name: "Emily Chen", | |
| gender: "Female", | |
| age: "19", | |
| temp: "97.8°F", | |
| hr: "104 bpm", | |
| rr: "16/min", | |
| bp: "95/65", | |
| status: "Stable", | |
| complaint: "Generalized abdominal pain, nausea, vomiting for 12 hours. Pain now localized to RLQ", | |
| exams: [ | |
| { text: "Palpate abdomen", correct: true, feedback: "Tenderness with guarding in RLQ" }, | |
| { text: "Check for rebound tenderness", correct: true, feedback: "Positive rebound present" }, | |
| { text: "Check for Rovsing's sign", correct: true, feedback: "Positive - pain in RLQ when LLQ pressed" }, | |
| { text: "Cardiac exam", correct: false, feedback: "Heart sounds normal - not relevant" } | |
| ], | |
| tests: [ | |
| { text: "CBC with diff", correct: true, feedback: "WBC 14,000 with neutrophilia" }, | |
| { text: "Urinalysis", correct: true, feedback: "Normal - rules out UTI" }, | |
| { text: "Pregnancy test", correct: true, feedback: "Negative" }, | |
| { text: "Abdominal CT", correct: true, feedback: "Appendiceal wall thickening with fat stranding" } | |
| ], | |
| treatments: [ | |
| { text: "IV fluids", correct: true, feedback: "Started for hydration" }, | |
| { text: "Pain medication", correct: false, feedback: "Need diagnosis first - may mask symptoms" }, | |
| { text: "Antibiotics", correct: true, feedback: "Cefoxitin started pre-op" }, | |
| { text: "Surgery consult", correct: true, feedback: "General surgeon agrees with appendicitis diagnosis" } | |
| ], | |
| diagnosis: "Acute Appendicitis" | |
| }, | |
| { | |
| name: "Robert Williams", | |
| gender: "Male", | |
| age: "54", | |
| temp: "99.1°F", | |
| hr: "92 bpm", | |
| rr: "20/min", | |
| bp: "210/110", | |
| status: "Critical", | |
| complaint: "Sudden onset of severe headache, blurred vision, and nausea", | |
| exams: [ | |
| { text: "Neurological exam", correct: true, feedback: "Left-sided facial droop and arm weakness noted" }, | |
| { text: "Fundoscopic exam", correct: true, feedback: "Papilledema present" }, | |
| { text: "Check reflexes", correct: true, feedback: "Hyperreflexia on left side" }, | |
| { text: "Abdominal exam", correct: false, feedback: "Not relevant for neurological symptoms" } | |
| ], | |
| tests: [ | |
| { text: "CT head without contrast", correct: true, feedback: "Shows right basal ganglia hemorrhage" }, | |
| { text: "Basic metabolic panel", correct: true, feedback: "Na 148, K 4.0, Cr 1.1" }, | |
| { text: "Coagulation studies", correct: true, feedback: "PT/INR normal" }, | |
| { text: "Chest X-ray", correct: false, feedback: "Not immediately helpful for stroke workup" } | |
| ], | |
| treatments: [ | |
| { text: "Labetalol IV", correct: true, feedback: "BP decreasing gradually to 180/100" }, | |
| { text: "Mannitol", correct: true, feedback: "Given for intracranial pressure" }, | |
| { text: "Neurosurgery consult", correct: true, feedback: "Evaluating for possible intervention" }, | |
| { text: "Anticoagulants", correct: false, feedback: "Contraindicated in hemorrhagic stroke!" } | |
| ], | |
| diagnosis: "Hypertensive Intracerebral Hemorrhage" | |
| } | |
| ] | |
| }; | |
| // DOM Elements | |
| const mainMenu = document.getElementById('main-menu'); | |
| const instructions = document.getElementById('instructions'); | |
| const credits = document.getElementById('credits'); | |
| const gameScreen = document.getElementById('game-screen'); | |
| const shiftSummary = document.getElementById('shift-summary'); | |
| // Game Functions | |
| function startGame() { | |
| gameState.score = 0; | |
| gameState.patientsTreated = 0; | |
| gameState.livesSaved = 0; | |
| mainMenu.classList.add('hidden'); | |
| gameScreen.classList.remove('hidden'); | |
| document.getElementById('feedback-area').classList.add('hidden'); | |
| loadNextCase(); | |
| } | |
| function loadNextCase() { | |
| // Reset timer | |
| clearInterval(gameState.timer); | |
| gameState.timeLeft = 300; | |
| updateTimerDisplay(); | |
| gameState.timer = setInterval(updateTimer, 1000); | |
| // Select a random case | |
| const randomIndex = Math.floor(Math.random() * gameState.cases.length); | |
| gameState.currentCase = gameState.cases[randomIndex]; | |
| // Update patient info | |
| document.getElementById('patient-name').textContent = gameState.currentCase.name; | |
| document.getElementById('patient-gender').textContent = gameState.currentCase.gender; | |
| document.getElementById('patient-age').textContent = gameState.currentCase.age; | |
| document.getElementById('patient-temp').textContent = gameState.currentCase.temp; | |
| document.getElementById('patient-hr').textContent = gameState.currentCase.hr; | |
| document.getElementById('patient-rr').textContent = gameState.currentCase.rr; | |
| document.getElementById('patient-bp').textContent = gameState.currentCase.bp; | |
| document.getElementById('patient-status').textContent = gameState.currentCase.status; | |
| document.getElementById('chief-complaint').textContent = gameState.currentCase.complaint; | |
| // Update score display | |
| document.getElementById('score').textContent = gameState.score; | |
| // Clear previous options | |
| document.getElementById('exam-options').innerHTML = ''; | |
| document.getElementById('test-options').innerHTML = ''; | |
| document.getElementById('treatment-options').innerHTML = ''; | |
| // Add exam options | |
| gameState.currentCase.exams.forEach(exam => { | |
| const button = document.createElement('button'); | |
| button.className = 'w-full text-left bg-blue-50 hover:bg-blue-100 text-blue-800 font-medium py-2 px-3 rounded transition'; | |
| button.innerHTML = `<i class="fas fa-search mr-2"></i> ${exam.text}`; | |
| button.onclick = () => selectOption('exam', exam); | |
| document.getElementById('exam-options').appendChild(button); | |
| }); | |
| // Add test options | |
| gameState.currentCase.tests.forEach(test => { | |
| const button = document.createElement('button'); | |
| button.className = 'w-full text-left bg-green-50 hover:bg-green-100 text-green-800 font-medium py-2 px-3 rounded transition'; | |
| button.innerHTML = `<i class="fas fa-flask mr-2"></i> ${test.text}`; | |
| button.onclick = () => selectOption('test', test); | |
| document.getElementById('test-options').appendChild(button); | |
| }); | |
| // Add treatment options | |
| gameState.currentCase.treatments.forEach(treatment => { | |
| const button = document.createElement('button'); | |
| button.className = 'w-full text-left bg-red-50 hover:bg-red-100 text-red-800 font-medium py-2 px-3 rounded transition'; | |
| button.innerHTML = `<i class="fas fa-medkit mr-2"></i> ${treatment.text}`; | |
| button.onclick = () => selectOption('treatment', treatment); | |
| document.getElementById('treatment-options').appendChild(button); | |
| }); | |
| } | |
| function selectOption(type, option) { | |
| // Add visual feedback | |
| const buttons = document.querySelectorAll(`#${type}-options button`); | |
| buttons.forEach(btn => { | |
| btn.disabled = true; | |
| if (btn.textContent.includes(option.text)) { | |
| btn.classList.remove( | |
| type === 'exam' ? 'bg-blue-50 hover:bg-blue-100 text-blue-800' : | |
| type === 'test' ? 'bg-green-50 hover:bg-green-100 text-green-800' : | |
| 'bg-red-50 hover:bg-red-100 text-red-800' | |
| ); | |
| btn.classList.add(option.correct ? 'bg-green-100 text-green-800 border border-green-300' : 'bg-red-100 text-red-800 border border-red-300'); | |
| } | |
| }); | |
| // Update score | |
| if (option.correct) { | |
| gameState.score += 10; | |
| document.getElementById('score').textContent = gameState.score; | |
| // Add positive feedback animation | |
| const scoreElement = document.getElementById('score'); | |
| scoreElement.classList.add('heartbeat'); | |
| setTimeout(() => scoreElement.classList.remove('heartbeat'), 1000); | |
| } else { | |
| gameState.score = Math.max(0, gameState.score - 5); | |
| document.getElementById('score').textContent = gameState.score; | |
| } | |
| // Check if all critical options were selected | |
| setTimeout(checkCaseCompletion, 500); | |
| } | |
| function checkCaseCompletion() { | |
| // In a real game, you'd have more complex logic to determine case completion | |
| // For this demo, we'll just move to the next case after a few selections | |
| const selectedCount = document.querySelectorAll('#exam-options button, #test-options button, #treatment-options button') | |
| .filter(btn => btn.disabled).length; | |
| const totalCriticalOptions = [ | |
| ...gameState.currentCase.exams.filter(e => e.correct), | |
| ...gameState.currentCase.tests.filter(t => t.correct), | |
| ...gameState.currentCase.treatments.filter(t => t.correct) | |
| ].length; | |
| if (selectedCount >= Math.min(5, totalCriticalOptions + 2)) { | |
| completeCase(); | |
| } | |
| } | |
| function completeCase() { | |
| clearInterval(gameState.timer); | |
| // Calculate time bonus | |
| const timeBonus = Math.floor(gameState.timeLeft / 10); | |
| gameState.score += timeBonus; | |
| // Update stats | |
| gameState.patientsTreated++; | |
| gameState.livesSaved++; // In a real game, this would depend on performance | |
| // Show feedback | |
| document.getElementById('feedback-area').classList.remove('hidden'); | |
| document.getElementById('feedback-text').innerHTML = ` | |
| <p class="mb-2"><strong>Diagnosis:</strong> ${gameState.currentCase.diagnosis}</p> | |
| <p class="mb-2"><strong>Time Bonus:</strong> +${timeBonus} points</p> | |
| <p>Patient stabilized and transferred to appropriate care.</p> | |
| `; | |
| // Update score display | |
| document.getElementById('score').textContent = gameState.score; | |
| } | |
| function nextCase() { | |
| if (gameState.patientsTreated >= 3) { // End after 3 cases for this demo | |
| endShift(); | |
| } else { | |
| loadNextCase(); | |
| document.getElementById('feedback-area').classList.add('hidden'); | |
| } | |
| } | |
| function endShift() { | |
| clearInterval(gameState.timer); | |
| gameScreen.classList.add('hidden'); | |
| shiftSummary.classList.remove('hidden'); | |
| // Update summary | |
| document.getElementById('summary-patients').textContent = gameState.patientsTreated; | |
| document.getElementById('summary-saved').textContent = gameState.livesSaved; | |
| document.getElementById('summary-score').textContent = gameState.score; | |
| // Performance rating | |
| let rating = ""; | |
| if (gameState.score >= 250) { | |
| rating = "Attending Level!"; | |
| } else if (gameState.score >= 150) { | |
| rating = "Senior Resident"; | |
| } else if (gameState.score >= 100) { | |
| rating = "Junior Resident"; | |
| } else { | |
| rating = "Intern - Keep Practicing!"; | |
| } | |
| document.getElementById('summary-rating').textContent = rating; | |
| } | |
| function updateTimer() { | |
| gameState.timeLeft--; | |
| updateTimerDisplay(); | |
| if (gameState.timeLeft <= 0) { | |
| clearInterval(gameState.timer); | |
| // Time's up - negative consequences | |
| gameState.score = Math.max(0, gameState.score - 20); | |
| document.getElementById('feedback-area').classList.remove('hidden'); | |
| document.getElementById('feedback-text').innerHTML = ` | |
| <p class="text-red-600 font-bold mb-2">Time's up!</p> | |
| <p class="mb-2">You took too long to treat this patient.</p> | |
| <p><strong>Score Penalty:</strong> -20 points</p> | |
| `; | |
| } | |
| } | |
| function updateTimerDisplay() { | |
| const minutes = Math.floor(gameState.timeLeft / 60); | |
| const seconds = gameState.timeLeft % 60; | |
| document.getElementById('time-remaining').textContent = | |
| `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; | |
| // Change color when time is low | |
| const timerElement = document.getElementById('time-remaining'); | |
| if (gameState.timeLeft <= 60) { | |
| timerElement.classList.remove('text-white'); | |
| timerElement.classList.add('text-red-400', 'font-bold'); | |
| } else { | |
| timerElement.classList.add('text-white'); | |
| timerElement.classList.remove('text-red-400', 'font-bold'); | |
| } | |
| } | |
| // Menu Navigation | |
| function showInstructions() { | |
| mainMenu.classList.add('hidden'); | |
| instructions.classList.remove('hidden'); | |
| } | |
| function showCredits() { | |
| mainMenu.classList.add('hidden'); | |
| credits.classList.remove('hidden'); | |
| } | |
| function backToMenu() { | |
| instructions.classList.add('hidden'); | |
| credits.classList.add('hidden'); | |
| gameScreen.classList.add('hidden'); | |
| shiftSummary.classList.add('hidden'); | |
| mainMenu.classList.remove('hidden'); | |
| } | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Add any initialization code if needed | |
| }); | |
| </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=KatEdwards/assorted-games" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |