🎮ArcadeLab

Connect 4 - You vs AI Buddy

by SwiftPanda95
339 lines9.9 KB
▶ Play
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Connect 4 - You vs AI Buddy</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Roboto, sans-serif;
        }

        body {
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background: linear-gradient(135deg, #f0f4ff, #e6e9ff);
            padding: 20px;
        }

        .game-container {
            background: white;
            border-radius: 24px;
            padding: 30px 20px;
            box-shadow: 0 10px 40px rgba(100, 100, 255, 0.15);
            text-align: center;
            max-width: 550px;
            width: 100%;
        }

        h1 {
            font-size: 2.8rem;
            background: linear-gradient(90deg, #ff5e99, #ff9a56);
            -webkit-background-clip: text;
            color: transparent;
            margin-bottom: 8px;
        }

        .subtitle {
            color: #888;
            font-size: 1.1rem;
            margin-bottom: 20px;
        }

        .turn-bar {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 25px;
            padding: 12px 20px;
            background: #f8f9ff;
            border-radius: 16px;
        }

        .player-tag {
            display: flex;
            align-items: center;
            gap: 8px;
            font-weight: 600;
            color: #555;
        }

        .dot {
            width: 24px;
            height: 24px;
            border-radius: 50%;
        }
        .dot.you { background: #ff5252; }
        .dot.buddy { background: #ffc107; }

        .turn-text {
            font-size: 1rem;
            color: #555;
            font-weight: 500;
        }

        /* Game Board */
        .board {
            display: grid;
            grid-template-columns: repeat(7, 1fr);
            gap: 10px;
            background: linear-gradient(180deg, #6366f1, #8b5cf6);
            padding: 18px;
            border-radius: 16px;
            margin: 0 auto 25px;
            max-width: 480px;
        }

        .cell {
            aspect-ratio: 1;
            background: rgba(255,255,255,0.2);
            border-radius: 50%;
            position: relative;
            cursor: pointer;
            transition: background 0.2s;
        }

        .cell:hover {
            background: rgba(255,255,255,0.35);
        }

        .piece {
            position: absolute;
            width: 85%;
            height: 85%;
            left: 7.5%;
            top: 7.5%;
            border-radius: 50%;
            box-shadow: inset 0 3px 6px rgba(0,0,0,0.2);
            animation: drop 0.4s ease-out forwards;
        }

        .piece.player { background: radial-gradient(circle at 30% 30%, #ff7b7b, #ff3838); }
        .piece.ai { background: radial-gradient(circle at 30% 30%, #ffdd70, #ffc107); }

        @keyframes drop {
            0% { transform: translateY(-500px); opacity: 0; }
            100% { transform: translateY(0); opacity: 1; }
        }

        /* Buttons & Messages */
        .message {
            font-size: 1.3rem;
            font-weight: 600;
            color: #6366f1;
            margin-bottom: 20px;
            min-height: 2rem;
        }

        #restartBtn {
            padding: 14px 36px;
            font-size: 1.1rem;
            font-weight: 600;
            border: none;
            border-radius: 12px;
            background: linear-gradient(90deg, #ff7eb3, #ff758c);
            color: white;
            cursor: pointer;
            transition: transform 0.2s, box-shadow 0.2s;
        }

        #restartBtn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(255, 117, 140, 0.4);
        }

        /* Mobile Responsive */
        @media (max-width: 480px) {
            h1 { font-size: 2rem; }
            .board { gap: 6px; padding: 12px; }
            .turn-bar { padding: 10px; font-size: 0.9rem; }
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>Connect 4</h1>
        <p class="subtitle">You vs AI Buddy 🤝</p>

        <div class="turn-bar">
            <div class="player-tag">
                <div class="dot you"></div>
                <span>You</span>
            </div>
            <div class="turn-text" id="turnText">Your turn! Drop a piece 😊</div>
            <div class="player-tag">
                <span>AI Buddy 🤖</span>
                <div class="dot buddy"></div>
            </div>
        </div>

        <div class="board" id="board"></div>

        <div class="message" id="message"></div>
        <button id="restartBtn">Restart Game</button>
    </div>

    <script>
        // Game Settings
        const ROWS = 6;
        const COLS = 7;
        let board = [];
        let currentPlayer = 'player';
        let gameOver = false;

        const boardEl = document.getElementById('board');
        const turnText = document.getElementById('turnText');
        const messageEl = document.getElementById('message');
        const restartBtn = document.getElementById('restartBtn');

        // Start New Game
        function initGame() {
            board = Array(ROWS).fill().map(() => Array(COLS).fill(null));
            currentPlayer = 'player';
            gameOver = false;
            messageEl.textContent = '';
            turnText.textContent = 'Your turn! Drop a piece 😊';
            renderBoard();
        }

        // Draw Game Board
        function renderBoard() {
            boardEl.innerHTML = '';
            for (let r = 0; r < ROWS; r++) {
                for (let c = 0; c < COLS; c++) {
                    const cell = document.createElement('div');
                    cell.classList.add('cell');
                    cell.dataset.col = c;

                    if (board[r][c]) {
                        const piece = document.createElement('div');
                        piece.classList.add('piece', board[r][c]);
                        cell.appendChild(piece);
                    }

                    if (!gameOver && currentPlayer === 'player') {
                        cell.addEventListener('click', () => handleColClick(c));
                    }
                    boardEl.appendChild(cell);
                }
            }
        }

        // Handle Player Move
        function handleColClick(col) {
            if (gameOver || currentPlayer !== 'player') return;
            const row = getAvailableRow(col);
            if (row === -1) return;

            dropPiece(row, col, 'player');
            if (checkWin(row, col, 'player')) {
                endGame('🎉 You win! AI Buddy is sad 😢');
                return;
            }
            if (isBoardFull()) {
                endGame('🤝 It\'s a draw!');
                return;
            }

            currentPlayer = 'ai';
            turnText.textContent = 'AI Buddy is thinking... 🤔';
            setTimeout(aiMove, 700);
        }

        // Find Empty Row
        function getAvailableRow(col) {
            for (let r = ROWS - 1; r >= 0; r--) {
                if (!board[r][col]) return r;
            }
            return -1;
        }

        // Place Piece
        function dropPiece(row, col, player) {
            board[row][col] = player;
            renderBoard();
        }

        // Check Win Condition
        function checkWin(row, col, player) {
            const directions = [[0,1],[1,0],[1,1],[1,-1]];
            for (let [dr, dc] of directions) {
                let count = 1;
                for (let i=1; i<4; i++) {
                    const r = row + dr*i, c = col + dc*i;
                    if (r>=0 && r<ROWS && c>=0 && c<COLS && board[r][c]===player) count++;
                    else break;
                }
                for (let i=1; i<4; i++) {
                    const r = row - dr*i, c = col - dc*i;
                    if (r>=0 && r<ROWS && c>=0 && c<COLS && board[r][c]===player) count++;
                    else break;
                }
                if (count >=4) return true;
            }
            return false;
        }

        // Check Full Board
        function isBoardFull() {
            return board[0].every(cell => cell !== null);
        }

        // End Game
        function endGame(text) {
            gameOver = true;
            messageEl.textContent = text;
            turnText.textContent = 'Game Over!';
        }

        // AI Logic
        function aiMove() {
            let move = findWinningMove('ai');
            if (move === -1) move = findWinningMove('player');
            if (move === -1) move = chooseSmartColumn();

            const row = getAvailableRow(move);
            dropPiece(row, move, 'ai');

            if (checkWin(row, move, 'ai')) {
                endGame('😜 AI Buddy wins! Try again?');
                return;
            }
            if (isBoardFull()) {
                endGame('🤝 It\'s a draw!');
                return;
            }

            currentPlayer = 'player';
            turnText.textContent = 'Your turn! Drop a piece 😊';
        }

        // Find Winning Move
        function findWinningMove(player) {
            for (let c=0; c<COLS; c++) {
                const r = getAvailableRow(c);
                if (r === -1) continue;
                board[r][c] = player;
                const win = checkWin(r, c, player);
                board[r][c] = null;
                if (win) return c;
            }
            return -1;
        }

        // Smart Column Selection
        function chooseSmartColumn() {
            const priority = [3,2,4,1,5,0,6];
            for (let c of priority) {
                if (getAvailableRow(c) !== -1) return c;
            }
            return 0;
        }

        restartBtn.addEventListener('click',

Game Source: Connect 4 - You vs AI Buddy

Creator: SwiftPanda95

Libraries: none

Complexity: complex (339 lines, 9.9 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: connect-4-you-vs-ai-buddy-swiftpanda95" to link back to the original. Then publish at arcadelab.ai/publish.