KEXEL commited on
Commit
a788d76
·
verified ·
1 Parent(s): 0c534cc
Files changed (1) hide show
  1. VitaMahjong.html +665 -1
VitaMahjong.html CHANGED
@@ -194,6 +194,669 @@
194
  </div>
195
  </div>
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  <script>
198
  document.addEventListener('DOMContentLoaded', () => {
199
  // Game state
@@ -597,4 +1260,5 @@
597
  });
598
  </script>
599
  </body>
600
- </html>
 
 
194
  </div>
195
  </div>
196
 
197
+ <!-- Audio elements for sound effects -->
198
+ <audio id="flip-sound" src="https://kexel-git.static.hf.space/gsom/zapsplat_multimedia_button_click.mp3" preload="auto"></audio>
199
+ <audio id="match-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-positive-interface-beep-221.mp3" preload="auto"></audio>
200
+ <audio id="mismatch-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-quick-jump-arcade-game-239.mp3" preload="auto"></audio>
201
+ <audio id="hint-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-unlock-game-notification-253.mp3" preload="auto"></audio>
202
+ <audio id="level-complete-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-winning-chimes-2015.mp3" preload="auto"></audio>
203
+ <audio id="game-over-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-retro-arcade-lose-2027.mp3" preload="auto"></audio>
204
+ <audio id="button-click-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-select-click-1109.mp3" preload="auto"></audio>
205
+
206
+ <script>
207
+ document.addEventListener('DOMContentLoaded', () => {
208
+ // Game state
209
+ const state = {
210
+ board: [],
211
+ level: 1,
212
+ score: 0,
213
+ time: 0,
214
+ timerInterval: null,
215
+ selectedTiles: [],
216
+ matchedPairs: 0,
217
+ totalPairs: 0,
218
+ soundEnabled: true,
219
+ gameActive: false
220
+ };
221
+
222
+ // Audio elements
223
+ const flipSound = document.getElementById('flip-sound');
224
+ const matchSound = document.getElementById('match-sound');
225
+ const mismatchSound = document.getElementById('mismatch-sound');
226
+ const hintSound = document.getElementById('hint-sound');
227
+ const levelCompleteSound = document.getElementById('level-complete-sound');
228
+ const gameOverSound = document.getElementById('game-over-sound');
229
+ const buttonClickSound = document.getElementById('button-click-sound');
230
+
231
+ // DOM elements
232
+ const boardElement = document.getElementById('board');
233
+ const timerElement = document.getElementById('timer');
234
+ const levelElement = document.getElementById('level');
235
+ const scoreElement = document.getElementById('score');
236
+ const newGameButton = document.getElementById('new-game');
237
+ const hintButton = document.getElementById('hint');
238
+ const soundToggleButton = document.getElementById('sound-toggle');
239
+ const gameStatusElement = document.getElementById('game-status');
240
+ const levelCompleteModal = document.getElementById('level-complete-modal');
241
+ const gameOverModal = document.getElementById('game-over-modal');
242
+ const nextLevelButton = document.getElementById('next-level');
243
+ const playAgainButton = document.getElementById('play-again');
244
+ const levelTimeElement = document.getElementById('level-time');
245
+ const levelScoreElement = document.getElementById('level-score');
246
+ const finalLevelElement = document.getElementById('final-level');
247
+ const finalScoreElement = document.getElementById('final-score');
248
+
249
+ // Tile types (Vita Mahjong style)
250
+ const tileTypes = [
251
+ '1m', '2m', '3m', '4m', '5m', '6m', '7m', '8m', '9m', // Characters
252
+ '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', // Bamboo
253
+ '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', // Circles
254
+ 'ew', 'sw', 'ww', 'nw', // Winds
255
+ 'wd', 'gd', 'rd' // Dragons
256
+ ];
257
+
258
+ // Initialize game
259
+ function initGame() {
260
+ state.level = 1;
261
+ state.score = 0;
262
+ state.time = 0;
263
+ state.matchedPairs = 0;
264
+ state.gameActive = true;
265
+
266
+ clearInterval(state.timerInterval);
267
+ startTimer();
268
+
269
+ updateUI();
270
+ createBoard();
271
+
272
+ // Play button click sound
273
+ playSound('button-click');
274
+ }
275
+
276
+ // Create game board based on current level
277
+ function createBoard() {
278
+ boardElement.innerHTML = '';
279
+ state.board = [];
280
+ state.selectedTiles = [];
281
+ state.matchedPairs = 0;
282
+
283
+ // Determine number of pairs based on level
284
+ const pairs = Math.min(4 + state.level, 32); // Max 32 pairs (64 tiles)
285
+ state.totalPairs = pairs;
286
+
287
+ // Create array of tile pairs
288
+ let tiles = [];
289
+ const availableTypes = [...tileTypes].sort(() => 0.5 - Math.random()).slice(0, pairs);
290
+
291
+ availableTypes.forEach(type => {
292
+ tiles.push(type, type);
293
+ });
294
+
295
+ // Shuffle tiles
296
+ tiles = shuffleArray(tiles);
297
+
298
+ // Create board matrix (8 columns, rows as needed)
299
+ const cols = 8;
300
+ const rows = Math.ceil(tiles.length / cols);
301
+
302
+ for (let i = 0; i < rows; i++) {
303
+ const row = [];
304
+ for (let j = 0; j < cols; j++) {
305
+ const index = i * cols + j;
306
+ if (index < tiles.length) {
307
+ row.push({
308
+ type: tiles[index],
309
+ flipped: false,
310
+ matched: false,
311
+ row: i,
312
+ col: j
313
+ });
314
+ } else {
315
+ row.push(null); // Empty slot for uneven boards
316
+ }
317
+ }
318
+ state.board.push(row);
319
+ }
320
+
321
+ // Render tiles
322
+ renderBoard();
323
+ }
324
+
325
+ // Render the game board
326
+ function renderBoard() {
327
+ boardElement.innerHTML = '';
328
+
329
+ // Calculate grid rows based on board rows
330
+ boardElement.className = `grid gap-3 mx-auto`;
331
+ boardElement.style.gridTemplateColumns = `repeat(8, minmax(0, 1fr))`;
332
+
333
+ state.board.forEach((row, rowIndex) => {
334
+ row.forEach((tile, colIndex) => {
335
+ if (!tile) return;
336
+
337
+ const tileElement = document.createElement('div');
338
+ tileElement.className = `tile aspect-square cursor-pointer transition-all duration-300 ${tile.matched ? 'opacity-0' : ''}`;
339
+
340
+ tileElement.innerHTML = `
341
+ <div class="tile-inner ${tile.flipped ? 'flipped' : ''}">
342
+ <div class="tile-back flex items-center justify-center">
343
+ <i class="fas fa-dragon text-2xl"></i>
344
+ </div>
345
+ <div class="tile-front">
346
+ <span class="text-3xl font-bold">${getTileSymbol(tile.type)}</span>
347
+ </div>
348
+ </div>
349
+ `;
350
+
351
+ tileElement.addEventListener('click', () => handleTileClick(tile));
352
+
353
+ if (!tile.matched) {
354
+ tileElement.classList.add('tile-hover');
355
+ }
356
+
357
+ boardElement.appendChild(tileElement);
358
+ });
359
+ });
360
+ }
361
+
362
+ // Handle tile click
363
+ function handleTileClick(tile) {
364
+ if (!state.gameActive || tile.matched || tile.flipped || state.selectedTiles.length >= 2) {
365
+ return;
366
+ }
367
+
368
+ // Flip the tile
369
+ tile.flipped = true;
370
+ state.selectedTiles.push(tile);
371
+
372
+ // Play sound
373
+ playSound('flip');
374
+
375
+ renderBoard();
376
+
377
+ // Check for match if two tiles are selected
378
+ if (state.selectedTiles.length === 2) {
379
+ const [tile1, tile2] = state.selectedTiles;
380
+
381
+ if (tile1.type === tile2.type) {
382
+ // Match found
383
+ tile1.matched = true;
384
+ tile2.matched = true;
385
+ state.matchedPairs++;
386
+ state.score += 50 * state.level;
387
+
388
+ // Play success sound
389
+ playSound('match');
390
+
391
+ // Check if level is complete
392
+ if (state.matchedPairs === state.totalPairs) {
393
+ levelComplete();
394
+ }
395
+
396
+ // Clear selection after delay
397
+ setTimeout(() => {
398
+ state.selectedTiles = [];
399
+ renderBoard();
400
+ }, 500);
401
+ } else {
402
+ // No match
403
+ setTimeout(() => {
404
+ tile1.flipped = false;
405
+ tile2.flipped = false;
406
+ state.selectedTiles = [];
407
+ renderBoard();
408
+
409
+ // Play mismatch sound
410
+ playSound('mismatch');
411
+ }, 1000);
412
+ }
413
+ }
414
+
415
+ updateUI();
416
+ }
417
+
418
+ // Level complete
419
+ function levelComplete() {
420
+ state.gameActive = false;
421
+ clearInterval(state.timerInterval);
422
+
423
+ // Calculate bonus points based on time
424
+ const timeBonus = Math.max(0, 300 - state.time);
425
+ state.score += timeBonus;
426
+
427
+ // Show level complete modal
428
+ levelTimeElement.textContent = formatTime(state.time);
429
+ levelScoreElement.textContent = `+${timeBonus}`;
430
+ levelCompleteModal.classList.remove('hidden');
431
+
432
+ // Play level complete sound
433
+ playSound('level-complete');
434
+
435
+ updateUI();
436
+ }
437
+
438
+ // Next level
439
+ function nextLevel() {
440
+ playSound('button-click');
441
+
442
+ state.level++;
443
+ state.time = 0;
444
+ state.gameActive = true;
445
+
446
+ levelCompleteModal.classList.add('hidden');
447
+ startTimer();
448
+ createBoard();
449
+ updateUI();
450
+
451
+ // Show level up message
452
+ gameStatusElement.classList.remove('hidden');
453
+ gameStatusElement.querySelector('p').textContent = `Level ${state.level}!`;
454
+
455
+ setTimeout(() => {
456
+ gameStatusElement.classList.add('hidden');
457
+ }, 2000);
458
+ }
459
+
460
+ // Game over
461
+ function gameOver() {
462
+ state.gameActive = false;
463
+ clearInterval(state.timerInterval);
464
+
465
+ // Update final stats
466
+ finalLevelElement.textContent = state.level;
467
+ finalScoreElement.textContent = state.score;
468
+
469
+ // Show game over modal
470
+ gameOverModal.classList.remove('hidden');
471
+
472
+ // Play game over sound
473
+ playSound('game-over');
474
+ }
475
+
476
+ // Start timer
477
+ function startTimer() {
478
+ state.time = 0;
479
+ updateTimerDisplay();
480
+
481
+ state.timerInterval = setInterval(() => {
482
+ state.time++;
483
+ updateTimerDisplay();
484
+
485
+ // Game over if time exceeds limit (5 minutes)
486
+ if (state.time >= 300) {
487
+ gameOver();
488
+ }
489
+ }, 1000);
490
+ }
491
+
492
+ // Update timer display
493
+ function updateTimerDisplay() {
494
+ timerElement.textContent = formatTime(state.time);
495
+ }
496
+
497
+ // Format time as MM:SS
498
+ function formatTime(seconds) {
499
+ const mins = Math.floor(seconds / 60).toString().padStart(2, '0');
500
+ const secs = (seconds % 60).toString().padStart(2, '0');
501
+ return `${mins}:${secs}`;
502
+ }
503
+
504
+ // Update UI elements
505
+ function updateUI() {
506
+ levelElement.textContent = `Level ${state.level}`;
507
+ scoreElement.textContent = state.score;
508
+ }
509
+
510
+ // Get tile symbol for display
511
+ function getTileSymbol(type) {
512
+ const symbols = {
513
+ '1m': '一', '2m': '二', '3m': '三', '4m': '四', '5m': '五',
514
+ '6m': '六', '7m': '七', '8m': '八', '9m': '九',
515
+ '1s': '1', '2s': '2', '3s': '3', '4s': '4', '5s': '5',
516
+ '6s': '6', '7s': '7', '8s': '8', '9s': '9',
517
+ '1p': '❶', '2p': '❷', '3p': '❸', '4p': '❹', '5p': '❺',
518
+ '6p': '❻', '7p': '❼', '8p': '❽', '9p': '❾',
519
+ 'ew': '東', 'sw': '南', 'ww': '西', 'nw': '北',
520
+ 'wd': '白', 'gd': '發', 'rd': '中'
521
+ };
522
+ return symbols[type] || type;
523
+ }
524
+
525
+ // Shuffle array
526
+ function shuffleArray(array) {
527
+ const newArray = [...array];
528
+ for (let i = newArray.length - 1; i > 0; i--) {
529
+ const j = Math.floor(Math.random() * (i + 1));
530
+ [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
531
+ }
532
+ return newArray;
533
+ }
534
+
535
+ // Play sound
536
+ function playSound(type) {
537
+ if (!state.soundEnabled) return;
538
+
539
+ try {
540
+ switch (type) {
541
+ case 'flip':
542
+ flipSound.currentTime = 0;
543
+ flipSound.play();
544
+ break;
545
+ case 'match':
546
+ matchSound.currentTime = 0;
547
+ matchSound.play();
548
+ break;
549
+ case 'mismatch':
550
+ mismatchSound.currentTime = 0;
551
+ mismatchSound.play();
552
+ break;
553
+ case 'hint':
554
+ hintSound.currentTime = 0;
555
+ hintSound.play();
556
+ break;
557
+ case 'level-complete':
558
+ levelCompleteSound.currentTime = 0;
559
+ levelCompleteSound.play();
560
+ break;
561
+ case 'game-over':
562
+ gameOverSound.currentTime = 0;
563
+ gameOverSound.play();
564
+ break;
565
+ case 'button-click':
566
+ buttonClickSound.currentTime = 0;
567
+ buttonClickSound.play();
568
+ break;
569
+ }
570
+ } catch (e) {
571
+ console.error('Error playing sound:', e);
572
+ }
573
+ }
574
+
575
+ // Provide hint
576
+ function provideHint() {
577
+ if (!state.gameActive || state.matchedPairs === state.totalPairs) {
578
+ return;
579
+ }
580
+
581
+ // Play button click sound
582
+ playSound('button-click');
583
+
584
+ // Find all unflipped, unmatched tiles
585
+ const unflippedTiles = [];
586
+ state.board.forEach(row => {
587
+ row.forEach(tile => {
588
+ if (tile && !tile.flipped && !tile.matched) {
589
+ unflippedTiles.push(tile);
590
+ }
591
+ });
592
+ });
593
+
594
+ if (unflippedTiles.length < 2) return;
595
+
596
+ // Find a matching pair
597
+ const tileCount = {};
598
+ let hintTile1 = null;
599
+ let hintTile2 = null;
600
+
601
+ for (const tile of unflippedTiles) {
602
+ if (tileCount[tile.type]) {
603
+ hintTile1 = tileCount[tile.type];
604
+ hintTile2 = tile;
605
+ break;
606
+ }
607
+ tileCount[tile.type] = tile;
608
+ }
609
+
610
+ if (hintTile1 && hintTile2) {
611
+ // Highlight the hint tiles
612
+ const tileElements = boardElement.querySelectorAll('.tile');
613
+
614
+ tileElements.forEach((element, index) => {
615
+ const row = Math.floor(index / 8);
616
+ const col = index % 8;
617
+ const tile = state.board[row]?.[col];
618
+
619
+ if (tile === hintTile1 || tile === hintTile2) {
620
+ element.classList.add('ring-4', 'ring-yellow-400', 'ring-opacity-75');
621
+
622
+ // Remove highlight after delay
623
+ setTimeout(() => {
624
+ element.classList.remove('ring-4', 'ring-yellow-400', 'ring-opacity-75');
625
+ }, 2000);
626
+ }
627
+ });
628
+
629
+ // Deduct points for using hint
630
+ state.score = Math.max(0, state.score - 25);
631
+ updateUI();
632
+
633
+ // Play hint sound
634
+ playSound('hint');
635
+ }
636
+ }
637
+
638
+ // Event listeners
639
+ newGameButton.addEventListener('click', initGame);
640
+ hintButton.addEventListener('click', provideHint);
641
+ soundToggleButton.addEventListener('click', () => {
642
+ state.soundEnabled = !state.soundEnabled;
643
+ soundToggleButton.innerHTML = state.soundEnabled
644
+ ? '<i class="fas fa-volume-up mr-2"></i> Sound On'
645
+ : '<i class="fas fa-volume-mute mr-2"></i> Sound Off';
646
+ playSound('button-click');
647
+ });
648
+ nextLevelButton.addEventListener('click', nextLevel);
649
+ playAgainButton.addEventListener('click', () => {
650
+ playSound('button-click');
651
+ gameOverModal.classList.add('hidden');
652
+ initGame();
653
+ });
654
+
655
+ // Initialize the game
656
+ initGame();
657
+ });
658
+ </script>
659
+ </body>
660
+ </html>
661
+
662
+
663
+
664
+ <!--<!DOCTYPE html>
665
+ <html lang="en">
666
+ <head>
667
+ <meta charset="UTF-8">
668
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
669
+ <title>Vita Mahjong</title>
670
+ <script src="https://cdn.tailwindcss.com"></script>
671
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
672
+ <style>
673
+ @keyframes tileHover {
674
+ 0% { transform: translateY(0); }
675
+ 50% { transform: translateY(-5px); }
676
+ 100% { transform: translateY(0); }
677
+ }
678
+
679
+ .tile-hover:hover {
680
+ animation: tileHover 0.3s ease;
681
+ transform: translateY(-5px);
682
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
683
+ }
684
+
685
+ .tile-selected {
686
+ transform: translateY(-15px);
687
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2);
688
+ z-index: 10;
689
+ }
690
+
691
+ .tile-matched {
692
+ animation: fadeOut 0.5s ease forwards;
693
+ }
694
+
695
+ @keyframes fadeOut {
696
+ to {
697
+ opacity: 0;
698
+ transform: scale(0.8);
699
+ }
700
+ }
701
+
702
+ .board-container {
703
+ perspective: 1000px;
704
+ }
705
+
706
+ .tile {
707
+ transition: all 0.3s ease;
708
+ transform-style: preserve-3d;
709
+ }
710
+
711
+ .tile-inner {
712
+ position: relative;
713
+ width: 100%;
714
+ height: 100%;
715
+ transform-style: preserve-3d;
716
+ }
717
+
718
+ .tile-front, .tile-back {
719
+ position: absolute;
720
+ width: 100%;
721
+ height: 100%;
722
+ backface-visibility: hidden;
723
+ border-radius: 8px;
724
+ display: flex;
725
+ align-items: center;
726
+ justify-content: center;
727
+ }
728
+
729
+ .tile-front {
730
+ background: linear-gradient(145deg, #f0f0f0, #ffffff);
731
+ transform: rotateY(180deg);
732
+ }
733
+
734
+ .tile-back {
735
+ background: linear-gradient(145deg, #4f46e5, #7c3aed);
736
+ color: white;
737
+ }
738
+
739
+ .flipped {
740
+ transform: rotateY(180deg);
741
+ }
742
+
743
+ .level-complete {
744
+ animation: pulse 2s infinite;
745
+ }
746
+
747
+ @keyframes pulse {
748
+ 0% { transform: scale(1); }
749
+ 50% { transform: scale(1.05); }
750
+ 100% { transform: scale(1); }
751
+ }
752
+ </style>
753
+ </head>
754
+ <body class="bg-gray-100 min-h-screen font-sans">
755
+ <div class="container mx-auto px-4 py-8">
756
+
757
+ <header class="flex justify-between items-center mb-8">
758
+ <div class="flex items-center">
759
+ <i class="fas fa-dragon text-4xl text-purple-600 mr-3"></i>
760
+ <h1 class="text-3xl font-bold text-gray-800">Vita Mahjong</h1>
761
+ </div>
762
+ <div class="flex items-center space-x-4">
763
+ <div class="bg-white rounded-lg shadow p-3 flex items-center">
764
+ <i class="fas fa-clock text-purple-600 mr-2"></i>
765
+ <span id="timer" class="font-bold">00:00</span>
766
+ </div>
767
+ <div class="bg-white rounded-lg shadow p-3 flex items-center">
768
+ <i class="fas fa-layer-group text-purple-600 mr-2"></i>
769
+ <span id="level" class="font-bold">Level 1</span>
770
+ </div>
771
+ <div class="bg-white rounded-lg shadow p-3 flex items-center">
772
+ <i class="fas fa-star text-yellow-500 mr-2"></i>
773
+ <span id="score" class="font-bold">0</span>
774
+ </div>
775
+ </div>
776
+ </header>
777
+
778
+
779
+ <div class="flex justify-between mb-6">
780
+ <div class="flex space-x-3">
781
+ <button id="new-game" class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg shadow flex items-center">
782
+ <i class="fas fa-plus-circle mr-2"></i> New Game
783
+ </button>
784
+ <button id="hint" class="bg-amber-500 hover:bg-amber-600 text-white px-4 py-2 rounded-lg shadow flex items-center">
785
+ <i class="fas fa-lightbulb mr-2"></i> Hint
786
+ </button>
787
+ </div>
788
+ <div>
789
+ <button id="sound-toggle" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg shadow flex items-center">
790
+ <i class="fas fa-volume-up mr-2"></i> Sound On
791
+ </button>
792
+ </div>
793
+ </div>
794
+
795
+
796
+ <div class="board-container bg-white rounded-xl shadow-xl p-6 mb-6">
797
+ <div id="board" class="grid grid-cols-8 gap-3 mx-auto"></div>
798
+ </div>
799
+
800
+
801
+ <div id="game-status" class="text-center mb-6 hidden">
802
+ <div class="inline-block bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg">
803
+ <p class="font-bold">Level Complete!</p>
804
+ </div>
805
+ </div>
806
+
807
+
808
+ <div id="level-complete-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
809
+ <div class="bg-white rounded-xl shadow-2xl p-8 max-w-md w-full level-complete">
810
+ <div class="text-center">
811
+ <div class="text-6xl text-yellow-500 mb-4">
812
+ <i class="fas fa-trophy"></i>
813
+ </div>
814
+ <h2 class="text-3xl font-bold text-gray-800 mb-2">Level Complete!</h2>
815
+ <p class="text-gray-600 mb-6">Great job! Ready for the next challenge?</p>
816
+ <div class="grid grid-cols-2 gap-4 mb-6">
817
+ <div class="bg-purple-50 rounded-lg p-3">
818
+ <p class="text-sm text-purple-600">Time</p>
819
+ <p id="level-time" class="font-bold text-xl">00:45</p>
820
+ </div>
821
+ <div class="bg-purple-50 rounded-lg p-3">
822
+ <p class="text-sm text-purple-600">Score</p>
823
+ <p id="level-score" class="font-bold text-xl">+250</p>
824
+ </div>
825
+ </div>
826
+ <button id="next-level" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-3 rounded-lg shadow-lg font-bold">
827
+ Next Level <i class="fas fa-arrow-right ml-2"></i>
828
+ </button>
829
+ </div>
830
+ </div>
831
+ </div>
832
+
833
+
834
+ <div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
835
+ <div class="bg-white rounded-xl shadow-2xl p-8 max-w-md w-full">
836
+ <div class="text-center">
837
+ <div class="text-6xl text-red-500 mb-4">
838
+ <i class="fas fa-gamepad"></i>
839
+ </div>
840
+ <h2 class="text-3xl font-bold text-gray-800 mb-2">Game Over</h2>
841
+ <p class="text-gray-600 mb-6">Better luck next time!</p>
842
+ <div class="grid grid-cols-2 gap-4 mb-6">
843
+ <div class="bg-purple-50 rounded-lg p-3">
844
+ <p class="text-sm text-purple-600">Level Reached</p>
845
+ <p id="final-level" class="font-bold text-xl">3</p>
846
+ </div>
847
+ <div class="bg-purple-50 rounded-lg p-3">
848
+ <p class="text-sm text-purple-600">Total Score</p>
849
+ <p id="final-score" class="font-bold text-xl">750</p>
850
+ </div>
851
+ </div>
852
+ <button id="play-again" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-3 rounded-lg shadow-lg font-bold">
853
+ Play Again <i class="fas fa-redo ml-2"></i>
854
+ </button>
855
+ </div>
856
+ </div>
857
+ </div>
858
+ </div>
859
+
860
  <script>
861
  document.addEventListener('DOMContentLoaded', () => {
862
  // Game state
 
1260
  });
1261
  </script>
1262
  </body>
1263
+ </html>
1264
+ -->