لعبة XO - إصدار متطور
by SparkFlare70906 lines28.8 KB
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>لعبة XO - إصدار متطور</title>
<style>
/* ===== RESET & BASE ===== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
/* النهارية */
--bg: #f2f4fa;
--card-bg: #ffffff;
--text: #1e272e;
--text-light: #57606f;
--primary: #6c5ce7;
--primary-glow: rgba(108, 92, 231, 0.25);
--cell-bg: #f8f9fc;
--cell-hover: #eaeef5;
--border-light: #dfe6e9;
--shadow: 0 20px 60px rgba(0, 0, 0, 0.10);
--x-color: #e17055;
--o-color: #0984e3;
--win-color: #00b894;
--ad-bg: rgba(108, 92, 231, 0.05);
--ad-border: rgba(108, 92, 231, 0.15);
--splash-overlay: rgba(255, 255, 255, 0.92);
--toggle-bg: #dfe6e9;
--toggle-dot: #ffffff;
}
[data-theme="dark"] {
--bg: #1e1e2f;
--card-bg: #2d2d44;
--text: #f1f2f6;
--text-light: #b0b3c0;
--primary: #a29bfe;
--primary-glow: rgba(162, 155, 254, 0.20);
--cell-bg: #3a3a52;
--cell-hover: #4a4a62;
--border-light: #44445a;
--shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
--x-color: #fd79a8;
--o-color: #74b9ff;
--win-color: #55efc4;
--ad-bg: rgba(162, 155, 254, 0.08);
--ad-border: rgba(162, 155, 254, 0.20);
--splash-overlay: rgba(30, 30, 47, 0.95);
--toggle-bg: #4a4a62;
--toggle-dot: #2d2d44;
}
body {
font-family: 'Segoe UI', 'Tahoma', system-ui, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
transition: background 0.3s, color 0.3s;
position: relative;
}
/* ===== زر تبديل الوضع الليلي ===== */
.theme-toggle {
position: fixed;
top: 20px;
right: 20px;
z-index: 999;
background: var(--card-bg);
border: 2px solid var(--border-light);
border-radius: 40px;
width: 56px;
height: 30px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 6px;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
transition: 0.25s;
}
.theme-toggle:hover {
transform: scale(1.05);
}
.theme-toggle .dot {
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--toggle-dot);
transition: 0.3s;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
position: relative;
left: 0;
}
[data-theme="dark"] .theme-toggle .dot {
left: 20px;
background: #f1c40f;
}
.theme-toggle .icon-sun,
.theme-toggle .icon-moon {
font-size: 14px;
line-height: 1;
user-select: none;
}
.theme-toggle .icon-moon {
color: #f1c40f;
}
.theme-toggle .icon-sun {
color: #f39c12;
}
/* ===== الإعلانات ===== */
.ad {
position: fixed;
background: var(--ad-bg);
border: 2px dashed var(--ad-border);
border-radius: 14px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 8px;
font-size: 13px;
color: var(--text-light);
z-index: 100;
width: 140px;
height: 110px;
backdrop-filter: blur(6px);
transition: 0.3s;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.02);
}
.ad:hover {
border-color: var(--primary);
transform: scale(1.03);
}
.ad .ad-label {
font-size: 10px;
letter-spacing: 1px;
color: var(--primary);
background: rgba(108, 92, 231, 0.10);
padding: 2px 14px;
border-radius: 20px;
margin-bottom: 4px;
}
.ad .ad-content {
font-weight: 600;
text-align: center;
line-height: 1.3;
}
.ad .ad-content small {
font-weight: 400;
font-size: 10px;
display: block;
opacity: 0.6;
}
.ad-top-left {
top: 20px;
left: 20px;
}
.ad-top-right {
top: 20px;
right: 100px;
/* بجانب زر التبديل */;
}
.ad-bottom-left {
bottom: 20px;
left: 20px;
}
.ad-bottom-right {
bottom: 20px;
right: 20px;
}
@media (max-width: 820px) {
.ad {
width: 90px;
height: 70px;
padding: 4px;
border-radius: 8px;
font-size: 10px;
}
.ad .ad-label {
font-size: 7px;
padding: 1px 8px;
}
.ad .ad-content small {
font-size: 7px;
}
.ad-top-right {
right: 80px;
top: 16px;
}
}
@media (max-width: 560px) {
.ad {
width: 60px;
height: 48px;
border-radius: 6px;
font-size: 8px;
padding: 2px;
}
.ad .ad-label {
font-size: 5px;
padding: 0 4px;
}
.ad .ad-content small {
display: none;
}
.ad-top-right {
right: 60px;
top: 12px;
}
.ad-top-left {
top: 12px;
left: 12px;
}
.ad-bottom-left {
bottom: 12px;
left: 12px;
}
.ad-bottom-right {
bottom: 12px;
right: 12px;
}
.theme-toggle {
width: 44px;
height: 24px;
padding: 0 4px;
top: 12px;
right: 12px;
}
.theme-toggle .dot {
width: 18px;
height: 18px;
}
[data-theme="dark"] .theme-toggle .dot {
left: 16px;
}
.theme-toggle .icon-sun,
.theme-toggle .icon-moon {
font-size: 11px;
}
}
/* ===== شاشة البداية ===== */
.splash {
position: fixed;
inset: 0;
background: var(--splash-overlay);
backdrop-filter: blur(14px);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
transition: opacity 0.6s ease, visibility 0.6s;
padding: 20px;
}
.splash.hidden {
opacity: 0;
visibility: hidden;
pointer-events: none;
}
.splash-card {
background: var(--card-bg);
border-radius: 40px;
padding: 50px 45px;
max-width: 460px;
width: 100%;
text-align: center;
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.15);
border: 1px solid var(--border-light);
transition: 0.3s;
}
.splash-card h1 {
font-size: 48px;
font-weight: 900;
background: linear-gradient(135deg, var(--primary), #fd79a8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 6px;
letter-spacing: -1px;
}
.splash-card p {
color: var(--text-light);
font-size: 16px;
margin-bottom: 28px;
}
.splash-card .logo-big {
font-size: 72px;
margin-bottom: 10px;
display: block;
}
.splash-card .btn-start {
background: var(--primary);
border: none;
padding: 16px 48px;
border-radius: 60px;
font-size: 20px;
font-weight: 700;
color: #fff;
cursor: pointer;
box-shadow: 0 8px 28px var(--primary-glow);
transition: 0.25s;
font-family: inherit;
letter-spacing: 0.5px;
width: 100%;
}
.splash-card .btn-start:hover {
transform: translateY(-4px);
box-shadow: 0 14px 40px var(--primary-glow);
}
.splash-card .btn-start:active {
transform: translateY(0);
}
/* ===== حاوية اللعبة ===== */
.container {
background: var(--card-bg);
border-radius: 30px;
padding: 35px 40px 40px;
max-width: 520px;
width: 100%;
box-shadow: var(--shadow);
text-align: center;
position: relative;
z-index: 10;
transition: background 0.3s, box-shadow 0.3s;
border: 1px solid var(--border-light);
margin-top: 10px;
}
.header h1 {
font-size: 32px;
font-weight: 800;
background: linear-gradient(135deg, var(--primary), #fd79a8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 2px;
}
.header .sub {
font-size: 14px;
color: var(--text-light);
margin-bottom: 18px;
}
/* ===== أزرار الوضع ===== */
.mode-selector {
display: flex;
gap: 12px;
justify-content: center;
margin-bottom: 24px;
flex-wrap: wrap;
}
.mode-btn {
padding: 10px 26px;
border: 2px solid var(--border-light);
border-radius: 40px;
background: transparent;
font-size: 15px;
font-weight: 600;
color: var(--text-light);
cursor: pointer;
transition: 0.25s;
font-family: inherit;
display: flex;
align-items: center;
gap: 8px;
}
.mode-btn:hover {
border-color: var(--primary);
color: var(--primary);
}
.mode-btn.active {
background: var(--primary);
border-color: var(--primary);
color: #fff;
box-shadow: 0 6px 20px var(--primary-glow);
}
/* ===== رقعة اللعب ===== */
.board {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin: 0 auto 18px;
max-width: 360px;
aspect-ratio: 1/1;
width: 100%;
}
.cell {
background: var(--cell-bg);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 50px;
font-weight: 700;
cursor: pointer;
transition: 0.15s;
aspect-ratio: 1/1;
border: 2px solid transparent;
color: var(--text);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
}
.cell:hover:not(.taken):not(.game-over) {
background: var(--cell-hover);
transform: scale(1.02);
border-color: var(--primary);
}
.cell.taken {
cursor: default;
}
.cell.x {
color: var(--x-color);
}
.cell.o {
color: var(--o-color);
}
.cell.win-cell {
background: rgba(0, 184, 148, 0.15);
border-color: var(--win-color);
animation: pop 0.3s ease;
}
@keyframes pop {
0% {
transform: scale(0.7);
opacity: 0.5;
}
100% {
transform: scale(1);
opacity: 1;
}
}
/* ===== الحالة ===== */
.status {
font-size: 18px;
font-weight: 600;
margin-bottom: 12px;
min-height: 36px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
}
.turn-indicator {
display: inline-block;
width: 30px;
height: 30px;
border-radius: 10px;
font-weight: 700;
line-height: 30px;
text-align: center;
background: var(--cell-bg);
transition: 0.2s;
}
.turn-indicator.x-turn {
background: var(--x-color);
color: #fff;
}
.turn-indicator.o-turn {
background: var(--o-color);
color: #fff;
}
.result-msg {
font-weight: 700;
padding: 4px 20px;
border-radius: 30px;
background: rgba(0, 184, 148, 0.12);
color: var(--win-color);
}
.result-msg.draw {
background: rgba(99, 110, 114, 0.10);
color: var(--text-light);
}
/* ===== زر إعادة ===== */
.reset-btn {
padding: 12px 44px;
border: none;
border-radius: 40px;
font-size: 16px;
font-weight: 700;
background: var(--primary);
color: #fff;
cursor: pointer;
transition: 0.25s;
box-shadow: 0 6px 24px var(--primary-glow);
font-family: inherit;
}
.reset-btn:hover {
transform: translateY(-3px);
box-shadow: 0 12px 36px var(--primary-glow);
}
.reset-btn:active {
transform: translateY(0);
}
/* ===== النتيجة ===== */
.score {
display: flex;
justify-content: center;
gap: 30px;
margin-top: 16px;
font-size: 14px;
color: var(--text-light);
}
.score span {
font-weight: 700;
font-size: 18px;
}
.score .score-x {
color: var(--x-color);
}
.score .score-o {
color: var(--o-color);
}
.score .score-draw {
color: var(--text-light);
}
/* ===== استجابة ===== */
@media (max-width: 560px) {
.container {
padding: 20px 16px 24px;
border-radius: 20px;
}
.splash-card {
padding: 30px 20px;
border-radius: 28px;
}
.splash-card h1 {
font-size: 34px;
}
.splash-card .logo-big {
font-size: 52px;
}
.splash-card .btn-start {
font-size: 17px;
padding: 14px 28px;
}
.header h1 {
font-size: 26px;
}
.cell {
font-size: 34px;
border-radius: 10px;
}
.board {
gap: 6px;
max-width: 280px;
}
.mode-btn {
padding: 6px 16px;
font-size: 13px;
}
.status {
font-size: 15px;
}
.reset-btn {
padding: 10px 30px;
font-size: 14px;
}
.score {
font-size: 12px;
gap: 16px;
}
}
</style>
</head>
<body>
<!-- ===== زر تبديل الوضع الليلي ===== -->
<div class="theme-toggle" id="themeToggle" title="تبديل الوضع الليلي">
<span class="icon-sun">☀️</span>
<span class="dot" id="themeDot"></span>
<span class="icon-moon">🌙</span>
</div>
<!-- ===== الإعلانات الأربعة ===== -->
<div class="ad ad-top-left">
<span class="ad-label">📢 إعلان</span>
<div class="ad-content">مساحتك الإعلانية <small>ضع إعلانك هنا</small></div>
</div>
<div class="ad ad-top-right">
<span class="ad-label">📢 إعلان</span>
<div class="ad-content">مساحتك الإعلانية <small>ضع إعلانك هنا</small></div>
</div>
<div class="ad ad-bottom-left">
<span class="ad-label">📢 إعلان</span>
<div class="ad-content">مساحتك الإعلانية <small>ضع إعلانك هنا</small></div>
</div>
<div class="ad ad-bottom-right">
<span class="ad-label">📢 إعلان</span>
<div class="ad-content">مساحتك الإعلانية <small>ضع إعلانك هنا</small></div>
</div>
<!-- ===== شاشة البداية ===== -->
<div class="splash" id="splash">
<div class="splash-card">
<span class="logo-big">❌⭕</span>
<h1>لعبة XO</h1>
<p>تحدَّ أصدقاءك أو واجه الذكاء الاصطناعي</p>
<button class="btn-start" id="startBtn">🚀 ابدأ اللعب</button>
</div>
</div>
<!-- ===== حاوية اللعبة ===== -->
<div class="container" id="gameContainer">
<div class="header">
<h1>⭕ XO ❌</h1>
<div class="sub">اختر الوضع وابدأ التحدي</div>
</div>
<div class="mode-selector">
<button class="mode-btn active" data-mode="friend" id="modeFriend">
<span>👥</span> ضد صديق
</button>
<button class="mode-btn" data-mode="ai" id="modeAI">
<span>🤖</span> ضد الذكاء الاصطناعي
</button>
</div>
<div class="board" id="board"></div>
<div class="status" id="status">
<span>دور</span>
<span class="turn-indicator x-turn" id="turnIndicator">X</span>
<span id="statusText">اللاعب X</span>
</div>
<button class="reset-btn" id="resetBtn">🔄 إعادة البدء</button>
<div class="score">
<div>❌ X <span class="score-x" id="scoreX">0</span></div>
<div>🤝 تعادل <span class="score-draw" id="scoreDraw">0</span></div>
<div>⭕ O <span class="score-o" id="scoreO">0</span></div>
</div>
</div>
<script>
// ================================================================
// الوضع الليلي
// ================================================================
const themeToggle = document.getElementById('themeToggle');
const html = document.documentElement;
// استعادة التفضيل من localStorage
if (localStorage.getItem('theme') === 'dark') {
html.setAttribute('data-theme', 'dark');
} else {
html.removeAttribute('data-theme');
}
themeToggle.addEventListener('click', () => {
if (html.hasAttribute('data-theme')) {
html.removeAttribute('data-theme');
localStorage.setItem('theme', 'light');
} else {
html.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
}
});
// ================================================================
// شاشة البداية
// ================================================================
const splash = document.getElementById('splash');
const startBtn = document.getElementById('startBtn');
const gameContainer = document.getElementById('gameContainer');
startBtn.addEventListener('click', () => {
splash.classList.add('hidden');
// إظهار اللعبة (موجودة بالفعل)
});
// ================================================================
// منطق اللعبة
// ================================================================
const boardEl = document.getElementById('board');
const statusEl = document.getElementById('status');
const turnIndicator = document.getElementById('turnIndicator');
const statusText = document.getElementById('statusText');
const resetBtn = document.getElementById('resetBtn');
const modeFriend = document.getElementById('modeFriend');
const modeAI = document.getElementById('modeAI');
const scoreXEl = document.getElementById('scoreX');
const scoreOEl = document.getElementById('scoreO');
const scoreDrawEl = document.getElementById('scoreDraw');
let board = Array(9).fill(null);
let currentPlayer = 'X';
let gameOver = false;
let mode = 'friend';
let scores = { X: 0, O: 0, draw: 0 };
const WIN_PATTERNS = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
function renderBoard() {
boardEl.innerHTML = '';
for (let i = 0; i < 9; i++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.index = i;
cell.textContent = board[i] || '';
if (board[i]) {
cell.classList.add('taken', board[i].toLowerCase());
}
if (gameOver) cell.classList.add('game-over');
cell.addEventListener('click', () => handleCellClick(i));
boardEl.appendChild(cell);
}
updateStatus();
}
function updateStatus() {
const indicator = turnIndicator;
const text = statusText;
if (gameOver) {
const winner = checkWinner();
if (winner) {
indicator.className = `turn-indicator ${winner.toLowerCase()}-turn`;
indicator.textContent = winner;
text.innerHTML = `<span class="result-msg">🏆 فاز اللاعب ${winner}!</span>`;
} else if (board.every(c => c !== null)) {
indicator.className = 'turn-indicator';
indicator.textContent = '—';
text.innerHTML = `<span class="result-msg draw">🤝 تعادل!</span>`;
}
return;
}
indicator.className = `turn-indicator ${currentPlayer.toLowerCase()}-turn`;
indicator.textContent = currentPlayer;
text.textContent = `دور ${currentPlayer === 'X' ? 'اللاعب X' : 'اللاعب O'}`;
}
function updateScore() {
scoreXEl.textContent = scores.X;
scoreOEl.textContent = scores.O;
scoreDrawEl.textContent = scores.draw;
}
function checkWinner() {
for (const p of WIN_PATTERNS) {
const [a, b, c] = p;
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
return board[a];
}
}
return null;
}
function getWinningCells() {
for (const p of WIN_PATTERNS) {
const [a, b, c] = p;
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
return p;
}
}
return null;
}
function isDraw() {
return board.every(c => c !== null) && !checkWinner();
}
function handleCellClick(index) {
if (gameOver) return;
if (board[index] !== null) return;
if (mode === 'ai' && currentPlayer === 'O') return;
makeMove(index, currentPlayer);
if (!gameOver && mode === 'ai' && currentPlayer === 'O') {
setTimeout(() => aiMove(), 300);
}
}
function makeMove(index, player) {
board[index] = player;
const winner = checkWinner();
if (winner) {
gameOver = true;
scores[winner]++;
updateScore();
renderBoard();
highlightWin();
return;
}
if (isDraw()) {
gameOver = true;
scores.draw++;
updateScore();
renderBoard();
return;
}
currentPlayer = (player === 'X' ? 'O' : 'X');
renderBoard();
}
function highlightWin() {
const cells = document.querySelectorAll('.cell');
const winCells = getWinningCells();
if (!winCells) return;
winCells.forEach(i => cells[i].classList.add('win-cell'));
}
// ===== الذكاء الاصطناعي =====
function aiMove() {
if (gameOver || mode !== 'ai' || currentPlayer !== 'O') return;
// 1) فوز مباشر
for (let i = 0; i < 9; i++) {
if (board[i] === null) {
board[i] = 'O';
if (checkWinner() === 'O') {
board[i] = null;
makeMove(i, 'O');
return;
}
board[i] = null;
}
}
// 2) منع فوز الخصم
for (let i = 0; i < 9; i++) {
if (board[i] === null) {
board[i] = 'X';
if (checkWinner() === 'X') {
board[i] = null;
makeMove(i, 'O');
return;
}
board[i] = null;
}
}
// 3) المنتصف
if (board[4] === null) { makeMove(4, 'O'); return; }
// 4) زاوية عشوائية
const corners = [0, 2, 6, 8].filter(i => board[i] === null);
if (corners.length) {
makeMove(corners[Math.floor(Math.random() * corners.length)], 'O');
return;
}
// 5) حافة عشوائية
const edges = [1, 3, 5, 7].filter(i => board[i] === null);
if (edges.length) {
makeMove(edges[Math.floor(Math.random() * edges.length)], 'O');
return;
}
}
function resetGame() {
board = Array(9).fill(null);
currentPlayer = 'X';
gameOver = false;
renderBoard();
updateStatus();
}
function setMode(newMode) {
mode = newMode;
[modeFriend, modeAI].forEach(btn => btn.classList.remove('active'));
if (mode === 'friend') modeFriend.classList.add('active');
else modeAI.classList.add('active');
resetGame();
}
// ===== أحداث =====
modeFriend.addEventListener('click', () => setMode('friend'));
modeAI.addEventListener('click', () => setMode('ai'));
resetBtn.addEventListener('click', resetGame);
// ===== تشغيل =====
renderBoard();
updateScore();
</script>
</body>
</html>Game Source: لعبة XO - إصدار متطور
Creator: SparkFlare70
Libraries: none
Complexity: complex (906 lines, 28.8 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: xo-sparkflare70" to link back to the original. Then publish at arcadelab.ai/publish.