game\index.html
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Card Bluff & Shoot</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            background: #1a1a1a;
            color: white;
            font-family: Arial, sans-serif;
        }

        .game-container {
            width: 100%;
            min-height: 100vh;
            display: grid;
            grid-template-rows: auto 2fr 1fr;
            gap: 20px;
        }

        .top-section, .bottom-section {
            display: flex;
            justify-content: space-around;
            align-items: center;
            flex-wrap: wrap;
        }

        .player {
            background: #333;
            padding: 10px 20px;
            border-radius: 8px;
            text-align: center;
            margin: 5px;
            min-width: 120px;
            position: relative;
        }

        .player.active {
            border: 2px solid #4CAF50;
        }

        .player.eliminated {
            background: #555;
            opacity: 0.6;
            text-decoration: line-through;
        }

        .player .bullets {
            margin-top: 5px;
            font-size: 14px;
        }

        .middle-section {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 15px;
        }

        .game-info {
            text-align: center;
            font-size: 1.2em;
            color: #ddd;
        }

        .player-hand {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
            justify-content: center;
        }

        .card {
            width: 60px;
            height: 90px;
            background: white;
            border-radius: 5px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: black;
            cursor: pointer;
            user-select: none;
            border: 2px solid transparent;
            transition: border 0.3s;
            position: relative;
            font-size: 1em;
        }

        .card.selected {
            border: 2px solid yellow;
        }

        .card.back {
            background: #333;
            color: #333;
            cursor: default;
        }

        .actions {
            display: flex;
            gap: 10px;
            margin-top: 10px;
        }

        button {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            background: #4CAF50;
            color: white;
            transition: background 0.3s;
        }

        button:hover {
            background: #45a049;
        }

        button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.9);
            display: none;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            gap: 20px;
            z-index: 1000;
        }

        .overlay.active {
            display: flex;
        }

        #debugControls {
            position: fixed;
            bottom: 10px;
            right: 10px;
            background: #333;
            padding: 10px;
            border-radius: 5px;
            display: flex;
            gap: 10px;
        }

        /* Modal Styles */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.8);
            display: none;
            justify-content: center;
            align-items: center;
            z-index: 2000;
        }

        .modal.active {
            display: flex;
        }

        .modal-content {
            background: #222;
            padding: 20px 30px;
            border-radius: 10px;
            text-align: center;
            color: #ddd;
        }

        .modal-content h2 {
            margin-bottom: 15px;
        }

        .modal-content input {
            padding: 10px;
            width: 80%;
            margin-bottom: 15px;
            border: none;
            border-radius: 5px;
        }

        .modal-content button {
            padding: 10px 20px;
            background: #4CAF50;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            color: white;
        }

        .modal-content button:hover {
            background: #45a049;
        }

        @media (max-width: 600px) {
            .player {
                min-width: 100px;
                padding: 8px 15px;
            }

            .card {
                width: 50px;
                height: 75px;
                font-size: 0.9em;
            }
        }

        /* Central Table Styles */
        .central-table {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
            justify-content: center;
            margin-top: 20px;
        }

        .central-table .card {
            cursor: default;
        }

        /* Suit Color Styling */
        .card.spades, .card.clubs {
            color: black;
        }

        .card.hearts, .card.diamonds {
            color: red;
        }
    </style>
</head>
<body>
    <!-- Player Setup Modal (Hidden) -->
    <div class="modal" id="setupModal">
        <div class="modal-content">
            <h2>Setup Players</h2>
            <div id="playerInputs">
                <input type="text" placeholder="Player 1 Name" required>
                <input type="text" placeholder="Player 2 Name" required>
                <input type="text" placeholder="Player 3 Name" required>
                <input type="text" placeholder="Player 4 Name (Optional)">
                <input type="text" placeholder="Player 5 Name (Optional)">
            </div>
            <button onclick="startGame()">Start Game</button>
        </div>
    </div>

    <div class="game-container">
        <div class="top-section" id="players"></div>
        
        <div class="middle-section">
            <div class="game-info">
                <strong>Core Card:</strong> <span id="coreCard">-</span>
            </div>
            <div class="game-info">
                <strong>Last Played:</strong> <span id="lastPlayed">None</span>
            </div>
            <!-- Central Card Table -->
            <div class="central-table" id="centralTable"></div>
        </div>

        <div class="bottom-section">
            <div class="player-hand" id="currentHand"></div>
            <div class="actions">
                <button id="playButton" onclick="game.playSelectedCards()">Play Selected Cards</button>
                <button id="callBluffButton" onclick="game.callBluff()" style="background: #f44336">Call Bluff</button>
            </div>
        </div>
    </div>

    <div class="overlay" id="shootingOverlay">
        <h2>🎲 Russian Roulette Time! 🔫</h2>
        <button onclick="game.pullTrigger()" style="padding: 15px 30px; font-size: 1em;">Pull Trigger</button>
    </div>

    <div id="debugControls">
        <button onclick="game.startNewGame()">New Game</button>
    </div>

    <script>
        // Card Class
        class Card {
            constructor(value, suit) {
                this.value = value;
                this.suit = suit;
            }

            toString() {
                return `${this.value}${this.suit}`;
            }

            getSuitClass() {
                return this.suit === '♠' ? 'spades' :
                       this.suit === '♣' ? 'clubs' :
                       this.suit === '♥' ? 'hearts' :
                       'diamonds';
            }

            getColor() {
                return (this.suit === '♥' || this.suit === '♦') ? 'red' : 'black';
            }
        }

        // Player Class
        class Player {
            constructor(id, name, isHuman = false) {
                this.id = id;
                this.name = name;
                this.hand = [];
                this.bulletSlots = 6;
                this.isEliminated = false;
                this.isHuman = isHuman;
            }
        }

        // Game Class
        class Game {
            constructor() {
                this.players = [];
                this.currentPlayerIndex = 0;
                this.coreCard = null;
                this.lastPlayedCards = [];
                this.deck = [];
                this.shootingPlayer = null;
                this.isGameOver = false;
                this.centralTableCards = []; // To keep track of displayed cards
                this.initializeDeck();
                this.initializePlayers();
                this.startNewGame();
                this.render();
            }

            // Initialize the deck of cards
            initializeDeck() {
                const values = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
                const suits = ['♠', '♥', '♦', '♣'];
                this.deck = [];
                for (let value of values) {
                    for (let suit of suits) {
                        this.deck.push(new Card(value, suit));
                    }
                }
            }

            // Automatically initialize players: You + 3 Robots
            initializePlayers() {
                this.players = [];
                this.players.push(new Player(0, 'You', true));
                this.players.push(new Player(1, 'Robot 1'));
                this.players.push(new Player(2, 'Robot 2'));
                this.players.push(new Player(3, 'Robot 3'));
            }

            // Shuffle the deck using Fisher-Yates algorithm
            shuffleDeck() {
                for (let i = this.deck.length - 1; i > 0; i--) {
                    const j = Math.floor(Math.random() * (i + 1));
                    [this.deck[i], this.deck[j]] = [this.deck[j], this.deck[i]];
                }
            }

            // Start a new game
            startNewGame() {
                this.initializeDeck();
                this.shuffleDeck();
                this.currentPlayerIndex = 0;
                this.lastPlayedCards = [];
                this.centralTableCards = [];
                this.coreCard = null;
                this.isGameOver = false;

                this.players.forEach(player => {
                    player.hand = [];
                    player.bulletSlots = 6;
                    player.isEliminated = false;
                });

                this.dealNewRound();
                this.render();
            }

            // Deal hands for a new round
            dealNewRound() {
                this.shuffleDeck();

                // Ensure coreCard is set once per round and persists
                if (!this.coreCard) {
                    // Assign the first card as the core card and remove it from the deck
                    this.coreCard = this.deck.shift();
                }

                // Ensure enough cards for all players
                const requiredCards = this.players.filter(p => !p.isEliminated).length * 5;
                if (this.deck.length < requiredCards) {
                    // Reinitialize and shuffle again if not enough cards
                    this.initializeDeck();
                    this.shuffleDeck();
                    this.coreCard = this.deck.shift();
                }

                let cardIndex = 0;
                this.players.forEach(player => {
                    if (!player.isEliminated) {
                        player.hand = this.deck.slice(cardIndex, cardIndex + 5);
                        cardIndex += 5;
                    }
                });

                this.lastPlayedCards = [];
                this.centralTableCards = [];
            }

            // Get the current active player
            getCurrentPlayer() {
                return this.players[this.currentPlayerIndex];
            }

            // Move to the next active player
            nextPlayer() {
                if (this.isGameOver) return;
                let attempts = 0;
                do {
                    this.currentPlayerIndex = (this.currentPlayerIndex + 1) % this.players.length;
                    attempts++;
                    if (attempts > this.players.length) break; // Prevent infinite loop
                } while (this.getCurrentPlayer().isEliminated);
            }

            // Play selected cards
            playSelectedCards() {
                const selectedCardsElements = Array.from(document.querySelectorAll('.card.selected'));
                const selectedIndices = selectedCardsElements.map(el => parseInt(el.dataset.index));
                const selectedCards = selectedIndices.map(index => this.getCurrentPlayer().hand[index]);

                if (selectedCards.length === 0) {
                    alert('Please select at least one card to play.');
                    return;
                }

                // Remove played cards from player's hand
                selectedCards.sort((a, b) => this.getCurrentPlayer().hand.indexOf(b) - this.getCurrentPlayer().hand.indexOf(a));
                selectedCards.forEach(card => {
                    const idx = this.getCurrentPlayer().hand.indexOf(card);
                    if (idx > -1) {
                        this.getCurrentPlayer().hand.splice(idx, 1);
                    }
                });

                this.lastPlayedCards = selectedCards;

                // Add cards to central table as face-down
                selectedCards.forEach(card => {
                    const cardObj = {
                        card: card,
                        revealed: false
                    };
                    this.centralTableCards.push(cardObj);
                });

                // Update last played description to show the declared value
                this.updateLastPlayedDescription(false, selectedCards.length);

                this.nextPlayer();
                this.render();

                // If the next player is a robot and the game is not over, make it act automatically
                const nextPlayer = this.getCurrentPlayer();
                if (!nextPlayer.isHuman && !this.isGameOver) {
                    setTimeout(() => {
                        this.robotDecide(nextPlayer);
                    }, 1000);
                }
            }

            // Robot decision: play or call bluff
            robotDecide(player) {
                if (player.isEliminated || this.isGameOver) return;

                // Decide randomly to play or call bluff based on previous actions
                if (this.lastPlayedCards.length > 0) {
                    // 30% chance to call bluff
                    if (Math.random() < 0.3) {
                        this.callBluff();
                        return;
                    }
                }

                // Play cards
                this.robotPlay(player);
            }

            // Robot player action: play cards
            robotPlay(player) {
                if (player.isEliminated || this.isGameOver) return;

                const numCards = Math.min(3, player.hand.length);
                if (numCards === 0) return;

                // Select random cards to play
                const selectedIndices = [];
                while (selectedIndices.length < numCards) {
                    const randIndex = Math.floor(Math.random() * player.hand.length);
                    if (!selectedIndices.includes(randIndex)) {
                        selectedIndices.push(randIndex);
                    }
                }

                // Select the cards in the UI (simulate selection)
                selectedIndices.forEach(index => {
                    const cardEl = document.querySelector(`.card[data-index="${index}"]`);
                    if (cardEl) {
                        cardEl.classList.add('selected');
                    }
                });

                setTimeout(() => {
                    this.playSelectedCards();
                }, 1000);
            }

            // Call bluff on the previous player's last play
            callBluff() {
                if (this.lastPlayedCards.length === 0) {
                    alert('No cards have been played to call bluff!');
                    return;
                }

                const previousPlayerIndex = (this.currentPlayerIndex - 1 + this.players.length) % this.players.length;
                const previousPlayer = this.players[previousPlayerIndex];

                // Determine if the previous player was bluffing
                const isBluff = !this.lastPlayedCards.every(card => card.value === this.coreCard.value);
                this.shootingPlayer = isBluff ? previousPlayer : this.getCurrentPlayer();

                // Reveal the last played cards if bluff was called
                if (this.lastPlayedCards.length > 0) {
                    this.centralTableCards.forEach(cardObj => {
                        if (this.lastPlayedCards.includes(cardObj.card)) {
                            cardObj.revealed = true;
                        }
                    });
                }

                // Update last played description to indicate bluff
                this.updateLastPlayedDescription(isBluff, this.lastPlayedCards.length);

                // Show the shooting overlay
                document.getElementById('shootingOverlay').classList.add('active');
                this.render();
            }

            // Update the "Last Played" description based on bluff
            updateLastPlayedDescription(isBluff, numCards) {
                const lastPlayedSpan = document.getElementById('lastPlayed');
                if (isBluff) {
                    lastPlayedSpan.textContent = 'Bluff Called!';
                } else {
                    lastPlayedSpan.textContent = `${numCards} card(s) played as ${this.coreCard.value}${this.coreCard.suit}`;
                }
            }

            // Handle the trigger pull
            pullTrigger() {
                document.getElementById('shootingOverlay').classList.remove('active');

                const chance = 1 / this.shootingPlayer.bulletSlots;
                const hitBullet = Math.random() < chance;

                if (hitBullet) {
                    alert(`${this.shootingPlayer.name} has been shot and is eliminated!`);
                    this.shootingPlayer.isEliminated = true;

                    // Remove one bullet slot
                    this.shootingPlayer.bulletSlots--;

                    // Check if game is over
                    const remainingPlayers = this.players.filter(p => !p.isEliminated);
                    if (remainingPlayers.length === 1) {
                        alert(`Game Over! ${remainingPlayers[0].name} wins! 👑`);
                        this.isGameOver = true;
                        return;
                    }

                    // Reset coreCard for the next round
                    this.coreCard = null;
                } else {
                    alert(`${this.shootingPlayer.name} survived the shot!`);
                    this.shootingPlayer.bulletSlots--;
                }

                // Start a new round
                this.dealNewRound();
                this.nextPlayer();
                this.render();

                // If the next player is a robot and the game is not over, make it act automatically
                const nextPlayer = this.getCurrentPlayer();
                if (!nextPlayer.isHuman && !this.isGameOver) {
                    setTimeout(() => {
                        this.robotDecide(nextPlayer);
                    }, 1000);
                }
            }

            // Render the game state to the UI
            render() {
                // Render players
                const playersContainer = document.getElementById('players');
                playersContainer.innerHTML = '';
                this.players.forEach(player => {
                    const playerEl = document.createElement('div');
                    playerEl.className = `player ${player === this.getCurrentPlayer() ? 'active' : ''} ${player.isEliminated ? 'eliminated' : ''}`;
                    playerEl.innerHTML = `
                        <strong>${player.name}${player.isHuman ? ' (You)' : ''}</strong>
                        <div class="bullets">Bullets: ${player.bulletSlots}/6</div>
                    `;
                    playersContainer.appendChild(playerEl);
                });

                // Render core card
                const coreCardSpan = document.getElementById('coreCard');
                if (this.coreCard) {
                    const coreCard = this.coreCard; // This is now a Card object
                    coreCardSpan.innerHTML = this.createCardHTML(coreCard);
                } else {
                    coreCardSpan.textContent = '-';
                }

                // Render last played
                const lastPlayedSpan = document.getElementById('lastPlayed');
                if (this.lastPlayedCards.length > 0) {
                    // If "Bluff Called!", it's already updated in updateLastPlayedDescription
                    if (lastPlayedSpan.textContent !== 'Bluff Called!' && lastPlayedSpan.textContent !== 'Bluff Called!') {
                        lastPlayedSpan.textContent = `${this.lastPlayedCards.length} card(s) played as ${this.coreCard.value}${this.coreCard.suit}`;
                    }
                } else {
                    lastPlayedSpan.textContent = 'None';
                }

                // Render central table
                const centralTable = document.getElementById('centralTable');
                centralTable.innerHTML = '';
                this.centralTableCards.forEach((cardObj, index) => {
                    const cardEl = document.createElement('div');
                    cardEl.className = `card ${cardObj.revealed ? cardObj.card.getSuitClass() : 'back'}`;
                    if (cardObj.revealed) {
                        cardEl.innerHTML = `${cardObj.card.value}${cardObj.card.suit}`;
                        cardEl.style.color = cardObj.card.getColor();
                    } else {
                        cardEl.innerHTML = '🂠';
                    }
                    centralTable.appendChild(cardEl);
                });

                // Render current player's hand
                const handContainer = document.getElementById('currentHand');
                handContainer.innerHTML = '';
                const currentPlayer = this.getCurrentPlayer();
                if (!this.isGameOver && currentPlayer.isHuman) {
                    currentPlayer.hand.forEach((card, index) => {
                        const cardEl = document.createElement('div');
                        cardEl.className = `card ${card.getSuitClass()}`;
                        cardEl.style.color = card.getColor();
                        cardEl.dataset.index = index;
                        cardEl.innerHTML = `${card.value}${card.suit}`;
                        cardEl.onclick = () => {
                            cardEl.classList.toggle('selected');
                        };
                        handContainer.appendChild(cardEl);
                    });
                }

                // Enable/Disable buttons based on game state
                const isHuman = currentPlayer.isHuman;
                document.getElementById('playButton').disabled = (isHuman && currentPlayer.hand.length === 0) || this.isGameOver || !isHuman;
                document.getElementById('callBluffButton').disabled = this.lastPlayedCards.length === 0 || this.isGameOver;
            }

            // Helper function to create card HTML with proper styling
            createCardHTML(card) {
                const color = card.getColor();
                return `<span style="color: ${color}; font-size: 1em;">${card.value}${card.suit}</span>`;
            }
        }

        // Initialize Game Instance
        const game = new Game();

        // Hide the setup modal since players are auto-added
        document.getElementById('setupModal').style.display = 'none';
    </script>
</body>
</html>
```

I need you to remove the robot players from the game's logic and instead set up an Express.js server. This server should manage a central data source, stored in a JSON object in memory, that holds all the room information—such as player data, player hands, and the game state (e.g., what's on the table, turns, etc... ). The index.html file will then establish a WebSocket connection to interact with the server, enabling a real-time multiplayer experience. So, when you open the index.html for the first time you are going to be able to create or join to a room, if the user creates a room, returns an id that can be share with other players that they can use to join to the room... Once the creator of the room decide that all the players joined to the room, then starts the match, making impossible join to the room.

TLR:

Remove robot players from the game's logic.
Set up an Express.js server to manage a central data source.
Store all room information (player data, player hands, game state, etc.) in a JSON file.
The index.html file should establish a WebSocket connection to the server for real-time interaction.
On opening the index.html file, the user can either create or join a room.
If the user creates a room, the server returns a unique room ID that can be shared with others.
Players can use the room ID to join the created room.
Waiting room it's created, showing in real time the players that joined to the match.
Once the room creator confirms all players have joined, the match begins.
After the match starts, joining the room will no longer be possible.

Goal: Start by setting up the server, and the client's side room's joining / creation. (Avoid the game's logic or game overall, let's focus on check the server and client connection works) Don't over engine, avoid socket.io, but ws. Now, start by the goal.