f / index.html
V-Booking's picture
Add 1 files
b64c847 verified
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>لعبة سكرو - Skru Card 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>
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap');
body {
font-family: 'Tajawal', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.card {
width: 80px;
height: 120px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
position: relative;
cursor: pointer;
user-select: none;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
.card-back {
background: linear-gradient(45deg, #8e2de2, #4a00e0);
color: white;
background-size: 200% 200%;
animation: gradient 3s ease infinite;
}
.card-front {
background: white;
color: #333;
}
.player-area {
transition: all 0.3s ease;
position: relative;
}
.player-area.active {
border: 3px solid #4CAF50;
box-shadow: 0 0 15px rgba(76, 175, 80, 0.5);
}
.player-area.active::after {
content: "اللاعب الحالي";
position: absolute;
top: -15px;
right: 50%;
transform: translateX(50%);
background: #4CAF50;
color: white;
padding: 2px 10px;
border-radius: 20px;
font-size: 12px;
font-weight: bold;
}
.special-card {
background: linear-gradient(45deg, #ff416c, #ff4b2b);
color: white;
background-size: 200% 200%;
animation: gradient 3s ease infinite;
}
.thief-card {
background: linear-gradient(45deg, #000000, #434343);
color: white;
}
.action-card {
background: linear-gradient(45deg, #00b09b, #96c93d);
color: white;
}
.modal {
transition: all 0.3s ease;
}
.modal.show {
opacity: 1;
pointer-events: auto;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.card-icon {
font-size: 24px;
margin-bottom: 5px;
}
.card-value {
font-size: 28px;
font-weight: bold;
}
.card-special {
font-size: 14px;
text-align: center;
padding: 0 5px;
}
.highlight {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(76, 175, 80, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(76, 175, 80, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(76, 175, 80, 0);
}
}
.penalty-badge {
position: absolute;
top: -8px;
right: -8px;
background: #ff5722;
color: white;
border-radius: 50%;
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
animation: bounce 0.5s alternate infinite;
}
@keyframes bounce {
from {
transform: translateY(0);
}
to {
transform: translateY(-5px);
}
}
.winner-crown {
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
color: gold;
font-size: 24px;
text-shadow: 0 0 3px rgba(0,0,0,0.5);
}
</style>
</head>
<body class="text-gray-800">
<div class="container mx-auto px-4 py-8">
<header class="text-center mb-8">
<h1 class="text-4xl font-bold text-indigo-800 mb-2">لعبة سكرو</h1>
<p class="text-lg text-gray-600">اللعبة التي تتحدى ذكاءك وتركيزك!</p>
</header>
<!-- Game Mode Selection -->
<div id="mode-selection" class="bg-white rounded-lg shadow-lg p-6 mb-8">
<h2 class="text-2xl font-bold mb-4 text-center text-indigo-700">اختر نمط اللعبة</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="mode-option bg-indigo-50 hover:bg-indigo-100 rounded-lg p-4 cursor-pointer transition flex flex-col items-center" data-mode="general">
<div class="w-12 h-12 bg-gradient-to-r from-purple-500 to-pink-500 rounded-full flex items-center justify-center text-white mb-2">
<i class="fas fa-star"></i>
</div>
<h3 class="font-bold text-lg text-indigo-800">سكرو العامة</h3>
<p class="text-gray-600 text-sm text-center">يمكن اللعبة واضافة جميع الاوراق</p>
</div>
<div class="mode-option bg-indigo-50 hover:bg-indigo-100 rounded-lg p-4 cursor-pointer transition flex flex-col items-center" data-mode="classic">
<div class="w-12 h-12 bg-gradient-to-r from-blue-500 to-teal-400 rounded-full flex items-center justify-center text-white mb-2">
<i class="fas fa-history"></i>
</div>
<h3 class="font-bold text-lg text-indigo-800">سكرو كلاسيك</h3>
<p class="text-gray-600 text-sm text-center">جميع الاوراق ما عدا كرت الحرامي وكرتين بينج وبونج</p>
</div>
<div class="mode-option bg-indigo-50 hover:bg-indigo-100 rounded-lg p-4 cursor-pointer transition flex flex-col items-center" data-mode="thief">
<div class="w-12 h-12 bg-gradient-to-r from-gray-700 to-gray-900 rounded-full flex items-center justify-center text-white mb-2">
<i class="fas fa-user-ninja"></i>
</div>
<h3 class="font-bold text-lg text-indigo-800">سكرو الحرامي</h3>
<p class="text-gray-600 text-sm text-center">جميع الاوراق ما عدا كرت بينج وبونج</p>
</div>
<div class="mode-option bg-indigo-50 hover:bg-indigo-100 rounded-lg p-4 cursor-pointer transition flex flex-col items-center" data-mode="duos">
<div class="w-12 h-12 bg-gradient-to-r from-green-500 to-green-700 rounded-full flex items-center justify-center text-white mb-2">
<i class="fas fa-users"></i>
</div>
<h3 class="font-bold text-lg text-indigo-800">سكرو الثنائيات</h3>
<p class="text-gray-600 text-sm text-center">جميع الاوراق ما عدا كرت الحرامي</p>
</div>
</div>
</div>
<!-- Player Setup -->
<div id="player-setup" class="bg-white rounded-lg shadow-lg p-6 mb-8 hidden">
<h2 class="text-2xl font-bold mb-4 text-center text-indigo-700">إعداد اللاعبين</h2>
<div class="mb-4">
<label class="block text-gray-700 mb-2">عدد اللاعبين (2-6)</label>
<input type="number" min="2" max="6" value="4" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div id="player-names" class="space-y-3">
<!-- Player name inputs will be added here -->
</div>
<button id="start-game" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded-md mt-4 transition transform hover:scale-105">
<i class="fas fa-play mr-2"></i> بدء اللعبة
</button>
</div>
<!-- Game Board -->
<div id="game-board" class="hidden">
<!-- Game Info -->
<div class="flex flex-col md:flex-row justify-between items-center mb-6 gap-4">
<div class="bg-white rounded-lg shadow px-4 py-2 flex items-center gap-4">
<div>
<span class="font-bold">الجولة:</span> <span id="round-number" class="text-indigo-600 font-bold">1</span>
</div>
<div>
<span class="font-bold">النمط:</span> <span id="game-mode" class="text-indigo-600 font-bold">سكرو العامة</span>
</div>
<div>
<span class="font-bold">اللاعب الحالي:</span> <span id="current-player" class="text-green-600 font-bold"></span>
</div>
</div>
<div class="flex gap-2">
<button id="rules-button" class="bg-yellow-500 hover:bg-yellow-600 text-white px-4 py-2 rounded-lg transition flex items-center">
<i class="fas fa-info-circle mr-2"></i> القواعد
</button>
<button id="end-game" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition flex items-center">
<i class="fas fa-stop mr-2"></i> إنهاء اللعبة
</button>
</div>
</div>
<!-- Center Area -->
<div class="relative mb-16 bg-indigo-50 rounded-xl p-6 shadow-inner">
<!-- Draw Pile -->
<div class="absolute left-1/2 transform -translate-x-1/2 -top-8">
<div id="draw-pile" class="card card-back flex flex-col items-center justify-center cursor-pointer hover:shadow-lg">
<i class="fas fa-layer-group text-2xl"></i>
<span class="text-xs mt-1">السحب</span>
<span id="draw-count" class="text-xs mt-1">0</span>
</div>
</div>
<!-- Discard Pile -->
<div class="flex justify-center">
<div id="discard-pile" class="card card-front mx-2">
<!-- Cards will be placed here -->
</div>
</div>
<!-- Current Round Info -->
<div class="absolute right-0 -top-8 bg-white rounded-lg shadow px-4 py-2 text-center flex items-center gap-2">
<div id="round-info" class="font-bold text-indigo-700">الجولة الأولى: النظر إلى أول كرتين على اليمين</div>
<div id="round-warning" class="text-xs text-red-500 hidden bg-red-100 px-2 py-1 rounded-full">
<i class="fas fa-exclamation-triangle mr-1"></i> تحذير: +10 عند مخالفة قواعد الجولة
</div>
</div>
</div>
<!-- Players Area -->
<div id="players-container" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Player areas will be added here -->
</div>
<!-- Current Player Actions -->
<div id="player-actions" class="bg-white rounded-lg shadow-lg p-4 mt-8 hidden">
<h3 class="font-bold mb-4 text-center text-lg text-indigo-700">اختياراتك</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<button id="draw-from-pile" class="bg-blue-500 hover:bg-blue-600 text-white py-3 px-4 rounded-lg transition transform hover:scale-105 flex flex-col items-center">
<i class="fas fa-draw-polygon text-xl mb-1"></i>
<span>سحب من ميدان الكروت</span>
</button>
<button id="draw-from-discard" class="bg-green-500 hover:bg-green-600 text-white py-3 px-4 rounded-lg transition transform hover:scale-105 flex flex-col items-center">
<i class="fas fa-hand-paper text-xl mb-1"></i>
<span>سحب من الأرض</span>
</button>
<button id="play-similar" class="bg-purple-500 hover:bg-purple-600 text-white py-3 px-4 rounded-lg transition transform hover:scale-105 flex flex-col items-center">
<i class="fas fa-exchange-alt text-xl mb-1"></i>
<span>التخلص من كرت مشابه</span>
</button>
</div>
<div class="mt-6 text-center">
<button id="declare-skru" class="bg-red-500 hover:bg-red-600 text-white py-3 px-8 rounded-lg font-bold transition transform hover:scale-105 flex items-center justify-center mx-auto">
<i class="fas fa-flag mr-2"></i> سكرو!
</button>
<p class="text-xs text-gray-500 mt-2">عند إعلان "سكرو"، سيتم احتساب النقاط بعد انتهاء الجولة</p>
</div>
</div>
</div>
<!-- Card Selection Modal -->
<div id="card-selection-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<h3 class="font-bold text-xl mb-4 text-center text-indigo-700" id="selection-title">اختر كرت</h3>
<div id="selectable-cards" class="flex flex-wrap justify-center gap-3 mb-6">
<!-- Cards will be added here -->
</div>
<div class="flex justify-center gap-4">
<button id="confirm-selection" class="bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded-lg transition flex items-center">
<i class="fas fa-check mr-2"></i> تأكيد
</button>
<button id="cancel-selection" class="bg-gray-500 hover:bg-gray-600 text-white px-6 py-2 rounded-lg transition flex items-center">
<i class="fas fa-times mr-2"></i> إلغاء
</button>
</div>
</div>
</div>
<!-- Player Selection Modal -->
<div id="player-selection-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<h3 class="font-bold text-xl mb-4 text-center text-indigo-700" id="player-selection-title">اختر لاعب</h3>
<div id="selectable-players" class="space-y-3 mb-6">
<!-- Players will be added here -->
</div>
<div class="flex justify-center gap-4">
<button id="confirm-player" class="bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded-lg transition flex items-center">
<i class="fas fa-check mr-2"></i> تأكيد
</button>
<button id="cancel-player" class="bg-gray-500 hover:bg-gray-600 text-white px-6 py-2 rounded-lg transition flex items-center">
<i class="fas fa-times mr-2"></i> إلغاء
</button>
</div>
</div>
</div>
<!-- Card View Modal -->
<div id="card-view-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<h3 class="font-bold text-xl mb-4 text-center text-indigo-700" id="card-view-title">عرض الكرت</h3>
<div id="viewed-card" class="flex justify-center mb-6">
<!-- Card will be shown here -->
</div>
<div class="flex justify-center">
<button id="close-view" class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-lg transition flex items-center">
<i class="fas fa-check mr-2"></i> موافق
</button>
</div>
</div>
</div>
<!-- Game Over Modal -->
<div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<h3 class="font-bold text-2xl mb-6 text-center text-indigo-800">نتيجة اللعبة</h3>
<div id="game-results" class="mb-6 space-y-4 max-h-96 overflow-y-auto">
<!-- Results will be added here -->
</div>
<div class="flex justify-center gap-4">
<button id="play-again" class="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-2 rounded-lg font-bold transition flex items-center">
<i class="fas fa-redo mr-2"></i> لعب مرة أخرى
</button>
<button id="new-game" class="bg-gray-600 hover:bg-gray-700 text-white px-6 py-2 rounded-lg font-bold transition flex items-center">
<i class="fas fa-plus mr-2"></i> لعبة جديدة
</button>
</div>
</div>
</div>
<!-- Rules Modal -->
<div id="rules-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto">
<div class="flex justify-between items-center mb-4">
<h3 class="font-bold text-xl text-indigo-800">قواعد لعبة سكرو</h3>
<button id="close-rules" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="space-y-4">
<div class="bg-blue-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-blue-800">هدف اللعبة:</h4>
<p>الحصول على أقل عدد من الأرقام في نهاية الجولة.</p>
</div>
<div class="bg-green-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-green-800">بداية اللعبة:</h4>
<ul class="list-disc list-inside space-y-1">
<li>كل لاعب يحصل على 4 كروت غير مكشوفة</li>
<li>يتم وضع ميدان للكروت في المنتصف</li>
<li>اللاعبون يسحبون بالترتيب من اليمين إلى اليسار</li>
</ul>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-purple-800">طرق اللعب:</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div class="bg-white p-3 rounded border border-purple-200">
<h5 class="font-bold text-purple-700">سكرو العامة</h5>
<p class="text-sm">يمكن اللعبة واضافة جميع الاوراق</p>
</div>
<div class="bg-white p-3 rounded border border-purple-200">
<h5 class="font-bold text-purple-700">سكرو كلاسيك</h5>
<p class="text-sm">جميع الاوراق ما عدا كرت الحرامي وكرتين بينج وبونج</p>
</div>
<div class="bg-white p-3 rounded border border-purple-200">
<h5 class="font-bold text-purple-700">سكرو الحرامي</h5>
<p class="text-sm">جميع الاوراق ما عدا كرت بينج وبونج</p>
</div>
<div class="bg-white p-3 rounded border border-purple-200">
<h5 class="font-bold text-purple-700">سكرو الثنائيات</h5>
<p class="text-sm">جميع الاوراق ما عدا كرت الحرامي</p>
</div>
</div>
</div>
<div class="bg-yellow-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-yellow-800">خيارات اللاعب:</h4>
<ol class="list-decimal list-inside space-y-2">
<li class="font-medium">سحب من ميدان الكروت ثم الاحتفاظ به أو التخلص منه</li>
<li class="font-medium">سحب من الأرض آخر كرت تركه اللاعب السابق</li>
<li class="font-medium">التخلص من كرت يشابه آخر كرت في الأرض</li>
</ol>
<div class="mt-2 bg-red-50 p-2 rounded text-red-600 text-sm flex items-start">
<i class="fas fa-exclamation-circle mt-1 mr-2"></i>
<span>⛔️ تحذير: إذا لم يكن الكرت مشابهاً يعود إليه كرته + الكرت الآخر</span>
</div>
</div>
<div class="bg-indigo-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-indigo-800">جولات اللعبة:</h4>
<div class="space-y-3">
<div class="bg-white p-3 rounded border border-indigo-200">
<h5 class="font-bold text-indigo-700">الجولة الأولى</h5>
<p class="text-sm">ينظر الجميع إلى أول كرتين على اليمين فقط</p>
<div class="mt-1 bg-red-50 p-1 rounded text-red-600 text-xs">
⛔️ تحذير: +10 عند النظر إلى أكثر من كرتين أو تبديل الكروت
</div>
</div>
<div class="bg-white p-3 rounded border border-indigo-200">
<h5 class="font-bold text-indigo-700">الجولة الثانية (الصامتة)</h5>
<p class="text-sm">لا يجوز الكلام خلال هذه الجولة</p>
<div class="mt-1 bg-red-50 p-1 rounded text-red-600 text-xs">
⛔️ تحذير: +10 عند الكلام
</div>
</div>
<div class="bg-white p-3 rounded border border-indigo-200">
<h5 class="font-bold text-indigo-700">الجولة الثالثة</h5>
<p class="text-sm">لا يستطيع أي لاعب النظر إلى كروته</p>
<div class="mt-1 bg-red-50 p-1 rounded text-red-600 text-xs">
⛔️ تحذير: +10 عند النظر إلى أي كرت
</div>
</div>
<div class="bg-white p-3 rounded border border-indigo-200">
<h5 class="font-bold text-indigo-700">الجولة الرابعة</h5>
<p class="text-sm">جولة الدبل: مجموع ما تحصل عليه بعد انتهاء الجولة × 2</p>
</div>
</div>
</div>
<div class="bg-pink-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-pink-800">مهام الكروت الخاصة:</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">7 أو 8</h5>
<p class="text-xs">تنظر في كرت واحد فقط من كروتك</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">9 أو 10</h5>
<p class="text-xs">تنظر في كرت واحد فقط من أحد اللاعبين</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">البصرة</h5>
<p class="text-xs">تستطيع التخلص من كرت من كروتك باختيارك</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">خذ وهات</h5>
<p class="text-xs">تستبدل كرت من أحد اللاعبين بكرت من عندك دون النظر</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">خذ بس</h5>
<p class="text-xs">تستطيع إعطاء كرت من كروتك لأحد اللاعبين</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">دائر ما يدور</h5>
<p class="text-xs">تنظر في كرت واحد من كل لاعب أو كرتين من أوراقك</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">عجب ما عجب</h5>
<p class="text-xs">مثل خذ وهات ولكن مع خيار الاستبدال مع لاعب آخر</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">الحرامي</h5>
<p class="text-xs">لا يمكن التخلص منه ويقوم بسرقة نقاط الخصم</p>
</div>
<div class="bg-white p-2 rounded border border-pink-200">
<h5 class="font-bold text-pink-700 text-sm">بونج/بينج</h5>
<p class="text-xs">تمنع فريق الخصم من اللعب في الجولة التالية</p>
</div>
</div>
</div>
<div class="bg-teal-50 p-4 rounded-lg">
<h4 class="font-bold text-lg text-teal-800">نهاية اللعبة:</h4>
<p class="text-sm">عندما يقول لاعب "سكرو"، يكمل الجميع حتى يعود دوره ثم تكشف الكروت. اللاعب الأقل عدداً هو الفائز، وقد يكون هناك أكثر من فائز. الخاسر هو من لديه أكبر مجموع أرقام.</p>
</div>
</div>
</div>
</div>
<!-- Help Button -->
<button id="help-button" class="fixed bottom-6 left-6 bg-indigo-600 text-white w-14 h-14 rounded-full shadow-lg flex items-center justify-center hover:bg-indigo-700 transition z-40 transform hover:scale-110">
<i class="fas fa-question text-2xl"></i>
</button>
<!-- Sound Toggle -->
<button id="sound-toggle" class="fixed bottom-6 right-6 bg-gray-600 text-white w-14 h-14 rounded-full shadow-lg flex items-center justify-center hover:bg-gray-700 transition z-40 transform hover:scale-110">
<i class="fas fa-volume-up text-2xl"></i>
</button>
</div>
<script>
// Game State
const gameState = {
mode: null,
players: [],
currentPlayerIndex: 0,
round: 1,
drawPile: [],
discardPile: [],
gameStarted: false,
skruDeclared: false,
skruPlayer: null,
soundEnabled: true,
specialCards: {
thief: { name: 'الحرامي', type: 'thief', penalty: 10 },
bing: { name: 'بينج', type: 'action', penalty: 10 },
bong: { name: 'بونج', type: 'action', penalty: 10 },
basra: { name: 'البصرة', type: 'action' },
takeAndGive: { name: 'خذ وهات', type: 'action' },
takeOnly: { name: 'خذ بس', type: 'action' },
lookAround: { name: 'دائر ما يدور', type: 'action' },
likeOrNot: { name: 'عجب ما عجب', type: 'action' }
},
cardActions: {
7: { name: 'انظر إلى كرت واحد من كروتك', type: 'view-self' },
8: { name: 'انظر إلى كرت واحد من كروتك', type: 'view-self' },
9: { name: 'انظر إلى كرت واحد من لاعب آخر', type: 'view-other' },
10: { name: 'انظر إلى كرت واحد من لاعب آخر', type: 'view-other' }
}
};
// DOM Elements
const modeSelection = document.getElementById('mode-selection');
const playerSetup = document.getElementById('player-setup');
const gameBoard = document.getElementById('game-board');
const playersContainer = document.getElementById('players-container');
const playerActions = document.getElementById('player-actions');
const drawPile = document.getElementById('draw-pile');
const discardPile = document.getElementById('discard-pile');
const roundNumber = document.getElementById('round-number');
const gameMode = document.getElementById('game-mode');
const currentPlayer = document.getElementById('current-player');
const roundInfo = document.getElementById('round-info');
const roundWarning = document.getElementById('round-warning');
const cardSelectionModal = document.getElementById('card-selection-modal');
const selectionTitle = document.getElementById('selection-title');
const selectableCards = document.getElementById('selectable-cards');
const playerSelectionModal = document.getElementById('player-selection-modal');
const playerSelectionTitle = document.getElementById('player-selection-title');
const selectablePlayers = document.getElementById('selectable-players');
const cardViewModal = document.getElementById('card-view-modal');
const cardViewTitle = document.getElementById('card-view-title');
const viewedCard = document.getElementById('viewed-card');
const gameOverModal = document.getElementById('game-over-modal');
const gameResults = document.getElementById('game-results');
const rulesModal = document.getElementById('rules-modal');
const helpButton = document.getElementById('help-button');
const soundToggle = document.getElementById('sound-toggle');
const drawCount = document.getElementById('draw-count');
// Buttons
const startGameBtn = document.getElementById('start-game');
const endGameBtn = document.getElementById('end-game');
const drawFromPileBtn = document.getElementById('draw-from-pile');
const drawFromDiscardBtn = document.getElementById('draw-from-discard');
const playSimilarBtn = document.getElementById('play-similar');
const declareSkruBtn = document.getElementById('declare-skru');
const confirmSelectionBtn = document.getElementById('confirm-selection');
const cancelSelectionBtn = document.getElementById('cancel-selection');
const confirmPlayerBtn = document.getElementById('confirm-player');
const cancelPlayerBtn = document.getElementById('cancel-player');
const closeViewBtn = document.getElementById('close-view');
const playAgainBtn = document.getElementById('play-again');
const newGameBtn = document.getElementById('new-game');
const closeRulesBtn = document.getElementById('close-rules');
const rulesButton = document.getElementById('rules-button');
// Audio Elements
const drawSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-unlock-game-notification-253.mp3');
const discardSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-quick-jump-arcade-game-239.mp3');
const skruSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-winning-chimes-2015.mp3');
const errorSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-software-interface-remove-notification-257.mp3');
const specialSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-magic-ping-utility-notification-308.mp3');
const winSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3');
const loseSound = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-sad-game-over-trombone-471.mp3');
// Event Listeners
document.querySelectorAll('.mode-option').forEach(option => {
option.addEventListener('click', () => {
gameState.mode = option.dataset.mode;
modeSelection.classList.add('hidden');
playerSetup.classList.remove('hidden');
// Set game mode display text
let modeText = '';
switch(gameState.mode) {
case 'general': modeText = 'سكرو العامة'; break;
case 'classic': modeText = 'سكرو كلاسيك'; break;
case 'thief': modeText = 'سكرو الحرامي'; break;
case 'duos': modeText = 'سكرو الثنائيات'; break;
}
gameMode.textContent = modeText;
// Setup player name inputs
const playerCount = document.querySelector('#player-setup input').value;
setupPlayerInputs(playerCount);
});
});
document.querySelector('#player-setup input').addEventListener('input', (e) => {
setupPlayerInputs(e.target.value);
});
startGameBtn.addEventListener('click', startGame);
endGameBtn.addEventListener('click', endGame);
drawFromPileBtn.addEventListener('click', drawFromPile);
drawFromDiscardBtn.addEventListener('click', drawFromDiscard);
playSimilarBtn.addEventListener('click', playSimilarCard);
declareSkruBtn.addEventListener('click', declareSkru);
confirmSelectionBtn.addEventListener('click', confirmCardSelection);
cancelSelectionBtn.addEventListener('click', cancelCardSelection);
confirmPlayerBtn.addEventListener('click', confirmPlayerSelection);
cancelPlayerBtn.addEventListener('click', cancelPlayerSelection);
closeViewBtn.addEventListener('click', closeCardView);
playAgainBtn.addEventListener('click', resetGame);
newGameBtn.addEventListener('click', newGame);
helpButton.addEventListener('click', showRules);
closeRulesBtn.addEventListener('click', hideRules);
rulesButton.addEventListener('click', showRules);
soundToggle.addEventListener('click', toggleSound);
// Initialize
function setupPlayerInputs(count) {
const playerNames = document.getElementById('player-names');
playerNames.innerHTML = '';
for (let i = 0; i < count; i++) {
const div = document.createElement('div');
div.className = 'flex items-center';
div.innerHTML = `
<span class="bg-indigo-100 text-indigo-800 px-3 py-2 rounded-l-md flex items-center justify-center w-24">
<i class="fas fa-user mr-2"></i> لاعب ${i+1}
</span>
<input type="text" class="flex-1 px-3 py-2 border border-gray-300 rounded-r-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="اسم اللاعب" required>
`;
playerNames.appendChild(div);
}
}
function startGame() {
// Get player names
const inputs = document.querySelectorAll('#player-setup input');
gameState.players = [];
inputs.forEach(input => {
if (input.type === 'text' && input.value.trim() !== '') {
gameState.players.push({
name: input.value.trim(),
cards: [],
points: 0,
isActive: false,
penalties: 0
});
}
});
if (gameState.players.length < 2) {
alert('يجب إدخال اسماء لاثنين من اللاعبين على الأقل');
return;
}
playerSetup.classList.add('hidden');
gameBoard.classList.remove('hidden');
// Initialize game
initializeGame();
}
function initializeGame() {
// Reset game state
gameState.round = 1;
gameState.skruDeclared = false;
gameState.skruPlayer = null;
gameState.gameStarted = true;
// Create deck based on game mode
gameState.drawPile = createDeck();
// Shuffle deck
shuffleDeck(gameState.drawPile);
// Deal cards to players (4 each)
gameState.players.forEach(player => {
player.cards = [];
for (let i = 0; i < 4; i++) {
player.cards.push({
value: gameState.drawPile.pop(),
isFaceUp: false
});
}
});
// Set first card in discard pile
gameState.discardPile = [gameState.drawPile.pop()];
// Set first player
gameState.currentPlayerIndex = 0;
gameState.players[0].isActive = true;
// Update UI
updateGameBoard();
updateRoundInfo();
// Show actions for current player
playerActions.classList.remove('hidden');
// Play sound
playSound(specialSound);
}
function createDeck() {
const deck = [];
// Regular cards (1-10)
for (let i = 1; i <= 10; i++) {
// Add 4 copies of each number
for (let j = 0; j < 4; j++) {
deck.push(i);
}
}
// Special cards based on game mode
switch(gameState.mode) {
case 'general': // All special cards
deck.push(gameState.specialCards.thief);
deck.push(gameState.specialCards.bing);
deck.push(gameState.specialCards.bong);
deck.push(gameState.specialCards.basra);
deck.push(gameState.specialCards.takeAndGive);
deck.push(gameState.specialCards.takeOnly);
deck.push(gameState.specialCards.lookAround);
deck.push(gameState.specialCards.likeOrNot);
break;
case 'classic': // All except thief, bing, bong
deck.push(gameState.specialCards.basra);
deck.push(gameState.specialCards.takeAndGive);
deck.push(gameState.specialCards.takeOnly);
deck.push(gameState.specialCards.lookAround);
deck.push(gameState.specialCards.likeOrNot);
break;
case 'thief': // All except bing, bong
deck.push(gameState.specialCards.thief);
deck.push(gameState.specialCards.basra);
deck.push(gameState.specialCards.takeAndGive);
deck.push(gameState.specialCards.takeOnly);
deck.push(gameState.specialCards.lookAround);
deck.push(gameState.specialCards.likeOrNot);
break;
case 'duos': // All except thief
deck.push(gameState.specialCards.bing);
deck.push(gameState.specialCards.bong);
deck.push(gameState.specialCards.basra);
deck.push(gameState.specialCards.takeAndGive);
deck.push(gameState.specialCards.takeOnly);
deck.push(gameState.specialCards.lookAround);
deck.push(gameState.specialCards.likeOrNot);
break;
}
return deck;
}
function shuffleDeck(deck) {
for (let i = deck.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[deck[i], deck[j]] = [deck[j], deck[i]];
}
}
function updateGameBoard() {
// Update players display
playersContainer.innerHTML = '';
gameState.players.forEach((player, index) => {
const playerDiv = document.createElement('div');
playerDiv.className = `player-area bg-white rounded-lg shadow p-4 ${player.isActive ? 'active' : ''}`;
const playerName = document.createElement('h3');
playerName.className = 'font-bold text-lg text-center mb-2 relative';
playerName.textContent = player.name;
if (player.penalties > 0) {
const penaltyBadge = document.createElement('div');
penaltyBadge.className = 'penalty-badge';
penaltyBadge.textContent = `+${player.penalties}`;
playerName.appendChild(penaltyBadge);
}
const playerCards = document.createElement('div');
playerCards.className = 'flex justify-center gap-2';
player.cards.forEach((card, cardIndex) => {
const cardDiv = document.createElement('div');
cardDiv.className = `card ${card.isFaceUp ? 'card-front' : 'card-back'}`;
cardDiv.dataset.playerIndex = index;
cardDiv.dataset.cardIndex = cardIndex;
if (card.isFaceUp) {
if (typeof card.value === 'object') {
// Special card
cardDiv.innerHTML = `
<div class="card-icon">${getCardIcon(card.value)}</div>
<div class="card-special">${card.value.name}</div>
`;
if (card.value.type === 'thief') {
cardDiv.classList.add('thief-card');
} else {
cardDiv.classList.add('action-card');
}
} else {
// Number card
if (card.value >= 7 && card.value <= 10) {
cardDiv.classList.add('action-card');
}
cardDiv.innerHTML = `
<div class="card-value">${card.value}</div>
`;
}
}
// Add click event for viewing cards in certain rounds
if (gameState.round === 1 || (card.isFaceUp && typeof card.value === 'number' && card.value >= 7 && card.value <= 10)) {
cardDiv.addEventListener('click', () => handleCardClick(index, cardIndex));
}
playerCards.appendChild(cardDiv);
});
const playerPoints = document.createElement('div');
playerPoints.className = 'text-center mt-2 text-gray-600';
playerPoints.textContent = `النقاط: ${player.points}`;
playerDiv.appendChild(playerName);
playerDiv.appendChild(playerCards);
playerDiv.appendChild(playerPoints);
playersContainer.appendChild(playerDiv);
});
// Update discard pile
discardPile.innerHTML = '';
if (gameState.discardPile.length > 0) {
const lastCard = gameState.discardPile[gameState.discardPile.length - 1];
const cardDiv = document.createElement('div');
cardDiv.className = 'card card-front';
if (typeof lastCard === 'object') {
// Special card
cardDiv.innerHTML = `
<div class="card-icon">${getCardIcon(lastCard)}</div>
<div class="card-special">${lastCard.name}</div>
`;
if (lastCard.type === 'thief') {
cardDiv.classList.add('thief-card');
} else {
cardDiv.classList.add('action-card');
}
} else {
// Number card
if (lastCard >= 7 && lastCard <= 10) {
cardDiv.classList.add('action-card');
}
cardDiv.innerHTML = `
<div class="card-value">${lastCard}</div>
`;
}
discardPile.appendChild(cardDiv);
}
// Update draw pile count
drawCount.textContent = gameState.drawPile.length;
// Update round number
roundNumber.textContent = gameState.round;
// Update current player name
currentPlayer.textContent = gameState.players[gameState.currentPlayerIndex].name;
}
function getCardIcon(card) {
if (typeof card === 'number') {
return card;
}
switch(card.name) {
case 'الحرامي': return '<i class="fas fa-user-ninja"></i>';
case 'بينج': return '<i class="fas fa-ban"></i>';
case 'بونج': return '<i class="fas fa-ban"></i>';
case 'البصرة': return '<i class="fas fa-trash-alt"></i>';
case 'خذ وهات': return '<i class="fas fa-exchange-alt"></i>';
case 'خذ بس': return '<i class="fas fa-hand-holding"></i>';
case 'دائر ما يدور': return '<i class="fas fa-eye"></i>';
case 'عجب ما عجب': return '<i class="fas fa-random"></i>';
default: return card.value || '?';
}
}
function handleCardClick(playerIndex, cardIndex) {
const player = gameState.players[playerIndex];
const card = player.cards[cardIndex];
// In round 1, players can view their first two cards
if (gameState.round === 1 && cardIndex < 2) {
viewCard(card, `كرت ${player.name}`);
}
// For action cards (7-10)
if (card.isFaceUp && typeof card.value === 'number' && card.value >= 7 && card.value <= 10) {
useActionCard(playerIndex, cardIndex);
}
}
function useActionCard(playerIndex, cardIndex) {
const player = gameState.players[playerIndex];
const card = player.cards[cardIndex];
if (playerIndex !== gameState.currentPlayerIndex) {
alert('ليس دورك لاستخدام هذا الكرت!');
return;
}
const action = gameState.cardActions[card.value];
switch(action.type) {
case 'view-self':
// Player can view one of their own cards
const options = player.cards
.filter((c, i) => !c.isFaceUp && i !== cardIndex)
.map((c, i) => ({ index: i, value: c.value }));
if (options.length === 0) {
alert('لا توجد كروت مخفية لديك!');
return;
}
showCardSelectionModal(
options,
`اختر كرتاً من كروتك لرؤيته (باستخدام كرت ${card.value})`,
false
);
// Store the action card info for later use
selectableCards.dataset.actionCardIndex = cardIndex;
selectableCards.dataset.actionPlayerIndex = playerIndex;
break;
case 'view-other':
// Player can view one card from another player
showPlayerSelectionModal(
`اختر لاعباً لرؤية أحد كروته (باستخدام كرت ${card.value})`,
playerIndex
);
// Store the action card info for later use
selectablePlayers.dataset.actionCardIndex = cardIndex;
selectablePlayers.dataset.actionPlayerIndex = playerIndex;
break;
}
}
function viewCard(card, title) {
cardViewTitle.textContent = title;
viewedCard.innerHTML = '';
const cardDiv = document.createElement('div');
cardDiv.className = 'card card-front';
if (typeof card.value === 'object') {
// Special card
cardDiv.innerHTML = `
<div class="card-icon">${getCardIcon(card.value)}</div>
<div class="card-special">${card.value.name}</div>
`;
if (card.value.type === 'thief') {
cardDiv.classList.add('thief-card');
} else {
cardDiv.classList.add('action-card');
}
} else {
// Number card
if (card.value >= 7 && card.value <= 10) {
cardDiv.classList.add('action-card');
}
cardDiv.innerHTML = `
<div class="card-value">${card.value}</div>
`;
}
viewedCard.appendChild(cardDiv);
// Show modal
cardViewModal.classList.remove('opacity-0', 'pointer-events-none');
cardViewModal.classList.add('opacity-100');
playSound(specialSound);
}
function updateRoundInfo() {
let info = '';
let warning = false;
switch(gameState.round) {
case 1:
info = 'الجولة الأولى: النظر إلى أول كرتين على اليمين فقط';
warning = true;
break;
case 2:
info = 'الجولة الثانية: الجولة الصامتة - ممنوع الكلام';
warning = true;
break;
case 3:
info = 'الجولة الثالثة: لا يمكن النظر إلى أي كرت من كروتك';
warning = true;
break;
case 4:
info = 'الجولة الرابعة: جولة الدبل - النقاط × 2';
break;
default:
info = `الجولة ${gameState.round}`;
}
roundInfo.textContent = info;
if (warning) {
roundWarning.classList.remove('hidden');
} else {
roundWarning.classList.add('hidden');
}
}
function drawFromPile() {
if (gameState.drawPile.length === 0) {
alert('لا توجد كروت متبقية في ميدان السحب!');
playSound(errorSound);
return;
}
const drawnCard = gameState.drawPile.pop();
const currentPlayer = gameState.players[gameState.currentPlayerIndex];
// Check if drawn card is the thief in certain modes
if (gameState.mode !== 'classic' && typeof drawnCard === 'object' && drawnCard.type === 'thief') {
// Player must keep the thief card
currentPlayer.cards.push({
value: drawnCard,
isFaceUp: true
});
alert(`لقد سحبت كرت ${drawnCard.name}! يجب عليك الاحتفاظ به ولا يمكنك التخلص منه.`);
updateGameBoard();
playSound(specialSound);
return;
}
// Show card selection modal to choose whether to keep or discard
showCardSelectionModal([{
value: drawnCard,
isFaceUp: true
}], 'ماذا تريد أن تفعل بهذا الكرت؟', true);
playSound(drawSound);
}
function drawFromDiscard() {
if (gameState.discardPile.length === 0) {
alert('لا توجد كروت في الأرض!');
playSound(errorSound);
return;
}
const drawnCard = gameState.discardPile.pop();
const currentPlayer = gameState.players[gameState.currentPlayerIndex];
// Player must keep the card from discard
currentPlayer.cards.push({
value: drawnCard,
isFaceUp: true
});
// Check if player can play a similar card immediately
checkForSimilarCards();
updateGameBoard();
playSound(drawSound);
}
function playSimilarCard() {
const currentPlayer = gameState.players[gameState.currentPlayerIndex];
const lastDiscard = gameState.discardPile[gameState.discardPile.length - 1];
// Find cards that match the last discarded card
const similarCards = currentPlayer.cards.filter(card =>
card.isFaceUp && (
(typeof card.value === 'number' && typeof lastDiscard === 'number' && card.value === lastDiscard) ||
(typeof card.value === 'object' && typeof lastDiscard === 'object' && card.value.name === lastDiscard.name)
)
);
if (similarCards.length === 0) {
alert('ليس لديك أي كرت مشابه لآخر كرت في الأرض!');
playSound(errorSound);
return;
}
// Show card selection to choose which similar card to play
showCardSelectionModal(similarCards, 'اختر كرت للتخلص منه:');
}
function declareSkru() {
if (confirm('هل أنت متأكد أنك تريد إعلان "سكرو"؟')) {
gameState.skruDeclared = true;
gameState.skruPlayer = gameState.currentPlayerIndex;
// Current player skips their turn
nextPlayer();
// Hide actions for current player
playerActions.classList.add('hidden');
alert(`أعلن ${gameState.players[gameState.skruPlayer].name} "سكرو"! سيتم احتساب النقاط بعد انتهاء الجولة.`);
playSound(skruSound);
}
}
function checkForSimilarCards() {
const currentPlayer = gameState.players[gameState.currentPlayerIndex];
const lastDiscard = gameState.discardPile[gameState.discardPile.length - 1];
// Check if player has any cards that match the last discarded card
const hasSimilar = currentPlayer.cards.some(card =>
card.isFaceUp && (
(typeof card.value === 'number' && typeof lastDiscard === 'number' && card.value === lastDiscard) ||
(typeof card.value === 'object' && typeof lastDiscard === 'object' && card.value.name === lastDiscard.name)
)
);
if (hasSimilar) {
if (confirm('لديك كرت مشابه لآخر كرت في الأرض، هل تريد التخلص منه؟')) {
playSimilarCard();
}
}
}
function nextPlayer() {
// Deactivate current player
gameState.players[gameState.currentPlayerIndex].isActive = false;
// Move to next player
gameState.currentPlayerIndex = (gameState.currentPlayerIndex + 1) % gameState.players.length;
// Check if we've completed a full round
if (gameState.currentPlayerIndex === 0 && !gameState.skruDeclared) {
gameState.round++;
updateRoundInfo();
// Check for round-specific rules
applyRoundRules();
}
// Check if game should end (after skru)
if (gameState.skruDeclared && gameState.currentPlayerIndex === gameState.skruPlayer) {
endGame();
return;
}
// Activate next player
gameState.players[gameState.currentPlayerIndex].isActive = true;
// Update UI
updateGameBoard();
// Show actions for current player
playerActions.classList.remove('hidden');
}
function applyRoundRules() {
// Apply rules specific to each round
switch(gameState.round) {
case 1: // First round - players can look at first two cards on the right
gameState.players.forEach(player => {
// Reveal first two cards
if (player.cards.length >= 1) player.cards[0].isFaceUp = true;
if (player.cards.length >= 2) player.cards[1].isFaceUp = true;
});
break;
case 2: // Silent round - no talking (handled by UI warning)
break;
case 3: // No looking round - all cards face down
gameState.players.forEach(player => {
player.cards.forEach(card => {
card.isFaceUp = false;
});
});
break;
case 4: // Double points round (handled at scoring)
break;
}
}
function showCardSelectionModal(cards, message, showKeepOption = false) {
selectableCards.innerHTML = '';
selectionTitle.textContent = message;
// Add cards
cards.forEach((card, index) => {
const cardDiv = document.createElement('div');
cardDiv.className = `card ${card.isFaceUp ? 'card-front' : 'card-back'} cursor-pointer`;
cardDiv.dataset.cardIndex = index;
if (card.isFaceUp) {
if (typeof card.value === 'object') {
// Special card
cardDiv.innerHTML = `
<div class="card-icon">${getCardIcon(card.value)}</div>
<div class="card-special">${card.value.name}</div>
`;
if (card.value.type === 'thief') {
cardDiv.classList.add('thief-card');
} else {
cardDiv.classList.add('action-card');
}
} else {
// Number card
if (card.value >= 7 && card.value <= 10) {
cardDiv.classList.add('action-card');
}
function showPlayerSelectionModal(message, excludePlayerIndex) {
selectablePlayers.innerHTML = '';
playerSelectionTitle.textContent = message;
// Add players
gameState.players.forEach((player, index) => {
if (index !== excludePlayerIndex) {
const playerDiv = document.createElement('div');
playerDiv.className = 'bg-gray-100 hover:bg-gray-200 p-3 rounded-lg cursor-pointer flex items-center justify-between';
playerDiv.dataset.playerIndex = index;
playerDiv.innerHTML = `
<span class="font-medium">${player.name}</span>
<span class="text-sm text-gray-500">${player.cards.length} كروت</span>
`;
playerDiv.addEventListener('click', () => {
// Toggle selection
document.querySelectorAll('#selectable-players > div').forEach(p => {
p.classList.remove('bg-blue-100', 'border', 'border-blue-300');
});
playerDiv.classList.add('bg-blue-100', 'border', 'border-blue-300');
});
selectablePlayers.appendChild(playerDiv);
}
});
// Show modal
playerSelectionModal.classList.remove('opacity-0', 'pointer-events-none');
playerSelectionModal.classList.add('opacity-100');
}
function hideCardSelectionModal() {
cardSelectionModal.classList.remove('opacity-100');
cardSelectionModal.classList.add('opacity-0', 'pointer-events-none');
}
function hidePlayerSelectionModal() {
playerSelectionModal.classList.remove('opacity-100');
playerSelectionModal.classList.add('opacity-0', 'pointer-events-none');
}
function confirmCardSelection() {
const selectedCard = document.querySelector('#selectable-cards .card.ring-4');
if (!selectedCard) {
alert('الرجاء اختيار كرت أولاً');
playSound(errorSound);
return;
}
const cardIndex = selectedCard.dataset.cardIndex;
const currentPlayer = gameState.players[gameState.currentPlayerIndex];
const lastDiscard = gameState.discardPile[gameState.discardPile.length - 1];
// Check if this is an action card selection
if (selectableCards.dataset.actionCardIndex !== undefined) {
const actionCardIndex = selectableCards.dataset.actionCardIndex;
const actionPlayerIndex = selectableCards.dataset.actionPlayerIndex;
const actionPlayer = gameState.players[actionPlayerIndex];
const actionCard = actionPlayer.cards[actionCardIndex];
// View the selected card
const selectedCardObj = currentPlayer.cards[cardIndex];
viewCard(selectedCardObj, `كرت ${currentPlayer.name}`);
// Remove the action card from player's hand
actionPlayer.cards.splice(actionCardIndex, 1);
// Add action card to discard pile
gameState.discardPile.push(actionCard.value);
// Clear stored data
delete selectableCards.dataset.actionCardIndex;
delete selectableCards.dataset.actionPlayerIndex;
// Hide modal and continue
hideCardSelectionModal();
updateGameBoard();
nextPlayer();
return;
}
// Normal card selection for playing similar card
// Get the actual card from player's hand that matches the last discard
const selectedCardObj = currentPlayer.cards.find(card =>
card.isFaceUp && (
(typeof card.value === 'number' && typeof lastDiscard === 'number' && card.value === lastDiscard) ||
(typeof card.value === 'object' && typeof lastDiscard === 'object' && card.value.name === lastDiscard.name)
)
);
if (!selectedCardObj) {
alert('خطأ: الكرت المحدد غير موجود!');
playSound(errorSound);
return;
}
// Remove card from player's hand
const cardIndexInHand = currentPlayer.cards.indexOf(selectedCardObj);
if (cardIndexInHand !== -1) {
currentPlayer.cards.splice(cardIndexInHand, 1);
}
// Add card to discard pile
gameState.discardPile.push(selectedCardObj.value);
// Hide modal and continue
hideCardSelectionModal();
updateGameBoard();
nextPlayer();
playSound(discardSound);
}
function confirmPlayerSelection() {
const selectedPlayer = document.querySelector('#selectable-players > div.bg-blue-100');
if (!selectedPlayer) {
alert('الرجاء اختيار لاعب أولاً');
playSound(errorSound);
return;
}
const playerIndex = selectedPlayer.dataset.playerIndex;
const selectedPlayerObj = gameState.players[playerIndex];
// Check if this is for an action card
if (selectablePlayers.dataset.actionCardIndex !== undefined) {
const actionCardIndex = selectablePlayers.dataset.actionCardIndex;
const actionPlayerIndex = selectablePlayers.dataset.actionPlayerIndex;
const actionPlayer = gameState.players[actionPlayerIndex];
const actionCard = actionPlayer.cards[actionCardIndex];
// Get a random face-down card from the selected player
const faceDownCards = selectedPlayerObj.cards.filter(card => !card.isFaceUp);
if (faceDownCards.length === 0) {
alert('لا توجد كروت مخفية لدى هذا اللاعب!');
playSound(errorSound);
return;
}
// Select a random face-down card
const randomIndex = Math.floor(Math.random() * faceDownCards.length);
const viewedCard = faceDownCards[randomIndex];
// View the card
viewCard(viewedCard, `كرت ${selectedPlayerObj.name}`);
// Remove the action card from player's hand
actionPlayer.cards.splice(actionCardIndex, 1);
// Add action card to discard pile
gameState.discardPile.push(actionCard.value);
// Clear stored data
delete selectablePlayers.dataset.actionCardIndex;
delete selectablePlayers.dataset.actionPlayerIndex;
// Hide modal and continue
hidePlayerSelectionModal();
updateGameBoard();
nextPlayer();
return;
}
}
function cancelCardSelection() {
hideCardSelectionModal();
}
function cancelPlayerSelection() {
hidePlayerSelectionModal();
}
function closeCardView() {
cardViewModal.classList.remove('opacity-100');
cardViewModal.classList.add('opacity-0', 'pointer-events-none');
}
function calculateScores() {
// Calculate scores for each player
gameState.players.forEach(player => {
let score = 0;
player.cards.forEach(card => {
if (typeof card.value === 'number') {
score += card.value;
} else if (typeof card.value === 'object' && card.value.penalty) {
score += card.value.penalty;
}
});
// Add any penalties
score += player.penalties;
// Double points in round 4
if (gameState.round === 4) {
score *= 2;
}
player.points += score;
});
}
function endGame() {
// Calculate scores
calculateScores();
// Determine winners and losers
const scores = gameState.players.map(player => player.points);
const minScore = Math.min(...scores);
const maxScore = Math.max(...scores);
// Display results
gameResults.innerHTML = '';
// Sort players by score (ascending)
const sortedPlayers = [...gameState.players].sort((a, b) => a.points - b.points);
sortedPlayers.forEach((player, index) => {
const playerDiv = document.createElement('div');
playerDiv.className = `mb-3 p-4 rounded-lg flex justify-between items-center ${
player.points === minScore ? 'bg-green-100 text-green-800 border border-green-200' :
player.points === maxScore ? 'bg-red-100 text-red-800 border border-red-200' : 'bg-gray-100 border border-gray-200'
}`;
playerDiv.innerHTML = `
<div class="flex items-center gap-3">
${player.points === minScore ? '<div class="winner-crown">👑</div>' : ''}
<span class="font-bold">${player.name}</span>
</div>
<span class="font-bold ${player.points === minScore ? 'text-green-600' : player.points === maxScore ? 'text-red-600' : 'text-gray-600'}">
${player.points} نقطة
</span>
`;
gameResults.appendChild(playerDiv);
});
// Show game over modal
gameOverModal.classList.remove('opacity-0', 'pointer-events-none');
gameOverModal.classList.add('opacity-100');
// Play sound
playSound(winSound);
}
function resetGame() {
// Hide game over modal
gameOverModal.classList.remove('opacity-100');
gameOverModal.classList.add('opacity-0', 'pointer-events-none');
// Reset game with same players and mode
initializeGame();
}
function newGame() {
// Hide game over modal
gameOverModal.classList.remove('opacity-100');
gameOverModal.classList.add('opacity-0', 'pointer-events-none');
// Hide game board
gameBoard.classList.add('hidden');
// Show mode selection
modeSelection.classList.remove('hidden');
}
function showRules() {
rulesModal.classList.remove('opacity-0', 'pointer-events-none');
rulesModal.classList.add('opacity-100');
}
function hideRules() {
rulesModal.classList.remove('opacity-100');
rulesModal.classList.add('opacity-0', 'pointer-events-none');
}
function toggleSound() {
gameState.soundEnabled = !gameState.soundEnabled;
if (gameState.soundEnabled) {
soundToggle.innerHTML = '<i class="fas fa-volume-up text-2xl"></i>';
} else {
soundToggle.innerHTML = '<i class="fas fa-volume-mute text-2xl"></i>';
}
}
function playSound(sound) {
if (gameState.soundEnabled) {
sound.currentTime = 0;
sound.play().catch(e => console.log('Sound playback prevented:', e));
}
}
</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=V-Booking/f" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>