Tic-Tac-Toe 3D

copy code

Tic-Tac-Toe 3D

CODE:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tic-Tac-Toe 3D</title>
    <style>
        .tictactoe3d5432-body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .tictactoe3d5432-game-container {
            display: flex;
            flex-direction: row;
            align-items: flex-start;
            gap: 20px;
        }
        .tictactoe3d5432-cube-container {
            width: 400px;
            height: 400px;
            perspective: 1000px;
        }
        .tictactoe3d5432-cube {
            width: 100%;
            height: 100%;
            position: relative;
            transform-style: preserve-3d;
            transform: rotateX(-20deg) rotateY(-20deg);
            transition: transform 0.1s;
        }
        .tictactoe3d5432-face {
            position: absolute;
            width: 400px;
            height: 400px;
            border: 2px solid #000;
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(4, 1fr);
            background-color: rgba(255, 255, 255, 0.8);
        }
        .tictactoe3d5432-cell {
            border: 1px solid #000;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 24px;
            cursor: pointer;
        }
        .tictactoe3d5432-face-front { transform: translateZ(200px); }
        .tictactoe3d5432-face-back { transform: rotateY(180deg) translateZ(200px); }
        .tictactoe3d5432-face-right { transform: rotateY(90deg) translateZ(200px); }
        .tictactoe3d5432-face-left { transform: rotateY(-90deg) translateZ(200px); }
        .tictactoe3d5432-face-top { transform: rotateX(90deg) translateZ(200px); }
        .tictactoe3d5432-face-bottom { transform: rotateX(-90deg) translateZ(200px); }
        .tictactoe3d5432-controls {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        .tictactoe3d5432-button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }
        .tictactoe3d5432-description {
            max-width: 300px;
            margin-bottom: 20px;
        }
        .tictactoe3d5432-score {
            font-size: 18px;
            font-weight: bold;
            margin-bottom: 10px;
        }
        .tictactoe3d5432-won-face {
            background-color: rgba(0, 255, 0, 0.2);
        }
        @media (max-width: 768px) {
            .tictactoe3d5432-game-container {
                flex-direction: column;
                align-items: center;
            }
            .tictactoe3d5432-cube-container {
                width: 300px;
                height: 300px;
            }
            .tictactoe3d5432-face {
                width: 300px;
                height: 300px;
            }
            .tictactoe3d5432-face-front, .tictactoe3d5432-face-back, .tictactoe3d5432-face-right, .tictactoe3d5432-face-left, .tictactoe3d5432-face-top, .tictactoe3d5432-face-bottom {
                transform: translateZ(150px);
            }
        }
    </style>
</head>
<body class="tictactoe3d5432-body">
    <div class="tictactoe3d5432-game-container">
        <div class="tictactoe3d5432-cube-container">
            <div class="tictactoe3d5432-cube" id="cube">
                <div class="tictactoe3d5432-face tictactoe3d5432-face-front"></div>
                <div class="tictactoe3d5432-face tictactoe3d5432-face-back"></div>
                <div class="tictactoe3d5432-face tictactoe3d5432-face-right"></div>
                <div class="tictactoe3d5432-face tictactoe3d5432-face-left"></div>
                <div class="tictactoe3d5432-face tictactoe3d5432-face-top"></div>
                <div class="tictactoe3d5432-face tictactoe3d5432-face-bottom"></div>
            </div>
        </div>
        <div class="tictactoe3d5432-controls">
            <div class="tictactoe3d5432-description">
                <h2>3D Tic-Tac-Toe</h2>
                <p>Play the classic game in a 4x4x4 3D grid!</p>
                <h3>How to play:</h3>
                <ul>
                    <li>Click on any empty cell to place your mark (X or O)</li>
                    <li>Get 4 in a row on a side to win that side and score a point</li>
                    <li>Game ends when all sides are won or filled</li>
                    <li>Drag the cube with your mouse to rotate it</li>
                </ul>
            </div>
            <div class="tictactoe3d5432-score" id="score">
                X: 0 | O: 0
            </div>
            <button class="tictactoe3d5432-button" id="startButton">Start Game</button>
            <button class="tictactoe3d5432-button" id="newGameButton">New Game</button>
        </div>
    </div>
    <script>
        const cube = document.getElementById('cube');
        const startButton = document.getElementById('startButton');
        const newGameButton = document.getElementById('newGameButton');
        const scoreDisplay = document.getElementById('score');

        let currentPlayer = 'X';
        let gameBoard = Array(6).fill().map(() => Array(4).fill().map(() => Array(4).fill('')));
        let gameActive = false;
        let score = { X: 0, O: 0 };
        let wonFaces = new Set();

        function initializeGame() {
            const faces = document.querySelectorAll('.tictactoe3d5432-face');
            faces.forEach((face, faceIndex) => {
                face.innerHTML = '';
                for (let i = 0; i < 16; i++) {
                    const cell = document.createElement('div');
                    cell.classList.add('tictactoe3d5432-cell');
                    cell.dataset.face = faceIndex;
                    cell.dataset.index = i;
                    cell.addEventListener('click', handleCellClick);
                    face.appendChild(cell);
                }
            });
        }

        function handleCellClick(event) {
            if (!gameActive) return;
            const cell = event.target;
            const face = parseInt(cell.dataset.face);
            const index = parseInt(cell.dataset.index);
            const row = Math.floor(index / 4);
            const col = index % 4;

            if (wonFaces.has(face)) return;

            if (gameBoard[face][row][col] === '') {
                gameBoard[face][row][col] = currentPlayer;
                cell.textContent = currentPlayer;
                if (checkWin(face, row, col)) {
                    wonFaces.add(face);
                    score[currentPlayer]++;
                    updateScore();
                    document.querySelectorAll('.tictactoe3d5432-face')[face].classList.add('tictactoe3d5432-won-face');
                    if (checkGameEnd()) {
                        alert(`Game Over! ${score.X > score.O ? 'X' : 'O'} wins!`);
                        gameActive = false;
                    }
                } else if (checkDraw()) {
                    alert("It's a draw!");
                    gameActive = false;
                } else {
                    currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
                }
            }
        }

        function checkWin(face, row, col) {
            // Check horizontal, vertical, and diagonal on the same face
            if (checkLine(face, row, 0, 0, 1) || checkLine(face, 0, col, 1, 0) ||
                checkLine(face, 0, 0, 1, 1) || checkLine(face, 0, 3, 1, -1)) {
                return true;
            }
            return false;
        }

        function checkLine(face, startRow, startCol, rowInc, colInc) {
            const player = gameBoard[face][startRow][startCol];
            if (player === '') return false;

            for (let i = 1; i < 4; i++) {
                const row = startRow + i * rowInc;
                const col = startCol + i * colInc;
                if (row < 0 || row >= 4 || col < 0 || col >= 4 ||
                    gameBoard[face][row][col] !== player) {
                    return false;
                }
            }
            return true;
        }

        function checkDraw() {
            return gameBoard.every(face => face.every(row => row.every(cell => cell !== '')));
        }

        function checkGameEnd() {
            if (wonFaces.size === 6) return true;
            const remainingSides = 6 - wonFaces.size;
            return Math.abs(score.X - score.O) > remainingSides;
        }

        function resetGame() {
            gameBoard = Array(6).fill().map(() => Array(4).fill().map(() => Array(4).fill('')));
            currentPlayer = 'X';
            gameActive = true;
            score = { X: 0, O: 0 };
            wonFaces.clear();
            updateScore();
            initializeGame();
            document.querySelectorAll('.tictactoe3d5432-face').forEach(face => {
                face.classList.remove('tictactoe3d5432-won-face');
            });
        }

        function updateScore() {
            scoreDisplay.textContent = `X: ${score.X} | O: ${score.O}`;
        }

        startButton.addEventListener('click', () => {
            if (!gameActive) {
                resetGame();
                gameActive = true;
            }
        });

        newGameButton.addEventListener('click', resetGame);

        let isDragging = false;
        let previousMousePosition = { x: 0, y: 0 };
        let rotationX = -20;
        let rotationY = -20;

        cube.addEventListener('mousedown', (e) => {
            isDragging = true;
            previousMousePosition = { x: e.clientX, y: e.clientY };
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;

            const deltaMove = {
                x: e.clientX - previousMousePosition.x,
                y: e.clientY - previousMousePosition.y
            };

            rotationY += deltaMove.x * 0.5;
            rotationX -= deltaMove.y * 0.5;

            cube.style.transform = `rotateX(${rotationX}deg) rotateY(${rotationY}deg)`;

            previousMousePosition = { x: e.clientX, y: e.clientY };
        });

        document.addEventListener('mouseup', () => {
            isDragging = false;
        });

        initializeGame();
    </script>
</body>
</html>