Software-Dev-Project / Website / templates / gamePage.html
gamePage.html
Raw
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{url_for('static', filename='css/gamePage.css')}}" />
    <link rel="icon" type="image/x-icon" href="../static/images/favicon.png">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.2/socket.io.js"></script>
    <title> {{ data.roomTitle }}</title>
</head>

<body>
    <div class="room-container" style="display: block;">
        <table id="room-header">
            <tr>
                <th>Room ID</th>
                <th>Host Name</th>
                <th>Players</th>
            </tr>
            <tr>
                <td>{{data.roomID}}</td>
                <td>{{data.hostName}}</td>
                <td id='activeNums'>{{data.activeNums}} / {{data.numPlayers}}</td>
            </tr>
        </table>

        <div id="player-list">
        </div>

        {% if data.isHost %}
        <div class="buttons">
            <button id="start-button" onclick="startGame()">Start Game</button>
            <button id="leave-button" onclick="leaveRoom()">Leave Room</button>
        </div>
        {% else %}
        <div class="buttons">
            <button id="ready-button" onclick="toggleReady()">Ready</button>
            <button id="leave-button" onclick="leaveRoom()">Leave Room</button>
        </div>
        {% endif %}
    </div>

    <div class="game-container" style="display: none;">
        <div class="south">
            <div class="info">
            </div>
            <ul class="discard">
            </ul>
            <ul class="hand">
            </ul>
        </div>

        <div class="north">
            <div class="info">
            </div>
            <ul class="discard">
            </ul>
            <ul class="hand">
            </ul>
        </div>

        <div class="west">
            <div class="info">
            </div>
            <ul class="discard">
            </ul>
            <ul class="hand">
            </ul>
        </div>

        <div class="east">
            <div class="info">
            </div>
            <ul class="discard">
            </ul>
            <ul class="hand">
            </ul>
        </div>

        <div class="deck">
            <img src="/static/images/card_face0.png" alt="">
        </div>

        <div class="outOfPlay">
            <ul class="cards">
            </ul>
        </div>
        <div id="displayArea" style="display: none;">
            <h3 id="message"></h3>
            <button id="next-button">Next Round</button>
        </div>
    </div>
    <script type="text/javascript">
        var socket = io();

        socket.on('connect', function () {
            socket.emit('join', {
                roomID: '{{data.roomID}}',
            });
        })

        socket.on('playerJoined', function (data) {
            const playerName = data.name;
            console.log(`Player ${playerName} joined the room.`);
        });

        socket.on('playerLeft', function (data) {
            const playerName = data.name;
            console.log(`Player ${playerName} left the room.`)
        })

        socket.on('updatePlayerList', function (data) {
            const playerList = document.getElementById('player-list');
            const activeNums = document.getElementById('activeNums');
            activeNums.innerText = `${data.players.length} / {{data.numPlayers}}`
            playerList.innerHTML = "";
            data.players.forEach(function (player) {
                var item = document.createElement('div');
                item.classList.add("list-item");
                item.innerHTML = `
                <img src="../static/images/person-icon.jpg" alt="Player Image" />
                <h2 class="player-name">${player.name}</h2>
                <div class="readiness-status">
                    <span class="status-label">Readiness:</span>
                    <span class="status-value">${player.readyStatus ? "Ready" : "Not Ready"}</span>
                </div>
                `;
                playerList.appendChild(item);
            })
        })

        socket.on('message', function (data) {
            console.log(data)
            var displayArea = document.getElementById("displayArea");
            var text = document.getElementById("message");
            var nextBtn = document.getElementById("next-button")
            displayArea.style.display = "block";
            text.innerHTML = `${data.message}`;
            if (Object.keys(data).length == 2) {
                nextBtn.onclick = function () {
                    socket.emit("nextRound", {
                        players: data.players,
                        roomID: data.players[0]["roomID"]
                    })
                    this.onclick = null;
                }
            } else {
                nextBtn.innerText = "Game Over";
                nextBtn.onclick = function () {
                    window.location.href = '/session';
                }
            }
        })

        socket.on('startGame', function (data) {
            const roomContainer = document.querySelector(".room-container");
            const gameContainer = document.querySelector(".game-container");
            const outOfPlay = document.querySelector(".cards");
            var displayArea = document.getElementById("displayArea");
            displayArea.style.display = "none";
            roomContainer.style.display = "none";
            gameContainer.style.display = "block";

            if ((data.outOfCards).length > 0) {
                var content = "";
                for (var i = 0; i < (data.outOfCards).length; i++) {
                    content +=
                        `<li><img src="/static/images/card_face${data.outOfCards[i].value}.png" alt=""></li>`
                }
                outOfPlay.innerHTML = content
            }
            updateCards(data.players);
        });

        socket.on('yourTurn', function (data) {
            var currentPlayer = data.player
            if (currentPlayer.sid == socket.id && currentPlayer.isMyTurn) {
                var deck = document.querySelector(".deck img");
                deck.onclick = function () {
                    socket.emit('drawCard', {
                        player: currentPlayer,
                        roomID: '{{ data.roomID }}'
                    })
                    this.onclick = null;
                }
            }
        })

        function renderCards(player, direction, playerIndex, players) {
            var info = document.querySelector(`.${direction} .info`);
            var hand = document.querySelector(`.${direction} .hand`);
            var discard = document.querySelector(`.${direction} .discard`);
            var cardsInHand = '';
            var cardsInDiscard = '';

            info.innerHTML = `
            <span>${player.name}</span>
            <span>${'⭐'.repeat(player.token)}</span>
            ${player.outOfRound ? "<span class ='active'> Out Of Round </span>" : player.isMyTurn ? "<span class ='active'> Your Turn </span>" : "<span></span>"}
            `
            hand.removeEventListener("dblclick", playCard);
            for (var i = 0; i < player.hand.length; i++) {
                cardsInHand +=
                    `<li><img src="/static/images/card_face${direction == "south" ? player.hand[i].value: 0}.png" alt=""></li>`;
            }
            hand.innerHTML = cardsInHand;
            hand.addEventListener("dblclick", function (event) {
                if (player.isMyTurn && player.hand.length > 1 && player.outOfRound == false) {
                    playCard(event, player, playerIndex, players);
                    player.isMyTurn = false
                    hand.removeEventListener("dblclick", playCard);
                }
            });

            for (var j = 0; j < player.discard.length; j++) {
                cardsInDiscard += `<li><img src="/static/images/card_face${player.discard[j].value}.png" alt=""></li>`;
            }
            discard.innerHTML = cardsInDiscard;
        }

        function playCard(event, player, playerIndex, players) {
            var clickedCardElement = event.target;
            var cardIndex = -1;

            while (clickedCardElement !== null) {
                if (clickedCardElement.tagName === 'LI') {
                    cardIndex = Array.from(clickedCardElement.parentNode.children).indexOf(clickedCardElement);
                    break;
                }
                clickedCardElement = clickedCardElement.parentElement;
            }

            if (cardIndex >= 0 && cardIndex < player.hand.length) {
                var bool = shouldDiscard(player)
                while (bool && player.hand[cardIndex].value != 7) {
                    alert("You can not play this card!")
                    cardIndex = (cardIndex + 1) % player.hand.length;
                }

                var playedCard = players[playerIndex].hand.splice(cardIndex, 1)[0];
                players[playerIndex].discard.push(playedCard);

                if (playedCard.value == 1) {
                    var [playerList, choices] = handlePlayerSelection(players, playedCard.value);
                    var index = prompt(`Please select one player to target:
${choices}`)
                    while (index == null || !(index in playerList)) {
                        index = prompt(`Please select one player to target:
${choices}`)
                    }
                    var namedCardValue = prompt(`Please name greater than 1 card:
2 - Powdered
3 - Chocolate Sprinkle
4 - Cinnamon Bun
5 - Jelly Filled
6 - Boston Cream
7 - Bear Claw
8 - Apple Fritter`)
                    while (namedCardValue == null || !(["2", "3", "4", "5", "6", "7", "8"].includes(namedCardValue))) {
                        namedCardValue = prompt(`Please name greater than 1 card:
2 - Powdered
3 - Chocolate Sprinkle
4 - Cinnamon Bun
5 - Jelly Filled
6 - Boston Cream
7 - Bear Claw
8 - Apple Fritter`)
                    }
                    var idx = players.findIndex(p => p.playerID === playerList[index]);

                    if (players[idx].invincible == true) {
                        alert("Sorry, No Effects!")
                        socket.emit("playcard", {
                            players: players,
                            roomID: player.roomID,
                            playerIndex: playerIndex
                        });
                        return;
                    }

                    if (players[idx].hand[0].value == Number(namedCardValue)) {
                        alert(`${players[idx].name} is Out Of Round!`)
                        players[idx].outOfRound = true;
                    } else {
                        alert(`${players[idx].name} does not have named card!`)
                    }

                } else if (playedCard.value == 2) {
                    var [playerList, choices] = handlePlayerSelection(players, playedCard.value);
                    var index = prompt(`Please select one player to target:
${choices}`)
                    while (index == null || !(index in playerList)) {
                        index = prompt(`Please select one player to target:
${choices}`)
                    }

                    var idx = players.findIndex(p => p.playerID === playerList[index]);

                    if (players[idx].invincible == true) {
                        alert("Sorry, No Effects!")
                        socket.emit("playcard", {
                            players: players,
                            roomID: player.roomID,
                            playerIndex: playerIndex
                        });
                        return;
                    }

                    alert(`${players[idx].hand[0].value} - ${players[idx].hand[0].name}`)

                } else if (playedCard.value == 3) {
                    var [playerList, choices] = handlePlayerSelection(players, playedCard.value);
                    var index = prompt(`Please select one player to target:
${choices}`)
                    while (index == null || !(index in playerList)) {
                        index = prompt(`Please select one player to target:
${choices}`)
                    }

                    var idx = players.findIndex(p => p.playerID === playerList[index]);

                    if (players[idx].invincible == true) {
                        alert("Sorry, No Effects!")
                        socket.emit("playcard", {
                            players: players,
                            roomID: player.roomID,
                            playerIndex: playerIndex
                        });
                        return;
                    }

                    if (players[playerIndex].hand[0].value == players[idx].hand[0].value) {

                    } else if (players[playerIndex].hand[0].value < players[idx].hand[0].value) {
                        players[playerIndex].outOfRound = true
                        alert(`${player.name} is Out Of Round!`)
                    } else {
                        players[idx].outOfRound = true;
                        alert(`${players[idx].name} is Out Of Round!`)
                    }

                } else if (playedCard.value == 4) {
                    players[playerIndex].invincible = true;
                } else if (playedCard.value == 5) {
                    var [playerList, choices] = handlePlayerSelection(players, playedCard.value);
                    var index = prompt(`Please select one player to target:
${choices}`)
                    while (index == null || !(index in playerList)) {
                        index = prompt(`Please select one player to target:
${choices}`)
                    }

                    var idx = players.findIndex(p => p.playerID === playerList[index]);

                    if (players[idx].invincible == true) {
                        alert("Sorry, No Effects!")
                        socket.emit("playcard", {
                            players: players,
                            roomID: player.roomID,
                            playerIndex: playerIndex
                        });
                        return;
                    }

                    console.log(players[idx])
                    players[idx].discard.push(players[idx].hand.pop())


                } else if (playedCard.value == 6) {
                    var [playerList, choices] = handlePlayerSelection(players, playedCard.value);
                    var index = prompt(`Please select one player to target:
${choices}`)

                    while (index == null || !(index in playerList)) {
                        index = prompt(`Please select one player to target:
${choices}`)
                    }

                    var idx = players.findIndex(p => p.playerID === playerList[index]);

                    if (players[idx].invincible == true) {
                        alert("Sorry, No Effects!")
                        socket.emit("playcard", {
                            players: players,
                            roomID: player.roomID,
                            playerIndex: playerIndex
                        });
                        return;
                    }

                    var exchange = prompt(`Do you want to trade with ${players[idx].name}?
${players[idx].hand[0].value} - ${players[idx].hand[0].name}
Please Enter Y or N`)

                    if (exchange == 'N' || exchange == null) {

                    } else {
                        while (exchange != 'Y') {
                            exchange = prompt(`Do you want to trade with ${players[idx].name}?
${players[idx].hand[0].value} - ${players[idx].hand[0].name}
Please Enter Y or N`)
                        }
                        if (exchange == 'Y') {
                            var temp = players[idx].hand[0];
                            players[idx].hand[0] = players[playerIndex].hand[0]
                            players[playerIndex].hand[0] = temp
                        }
                    }

                } else if (playedCard.value == 8) {
                    players[playerIndex].outOfRound = true;
                }


                socket.emit("playcard", {
                    players: players,
                    roomID: player.roomID,
                    playerIndex: playerIndex
                });
            }
        }


        function updateCards(players) {
            var startIdx = players.findIndex(player => player.sid == socket.id);
            if (players.length == 2) {
                for (var player of players) {
                    if (player.sid == socket.id) {
                        renderCards(player, "south", startIdx, players);
                    } else {
                        renderCards(player, "north", ((startIdx + 1) % players.length), players);
                    }
                }
            } else {
                for (let i = 0; i < players.length; i++) {
                    let playerIndex = (startIdx + i) % players.length;

                    if (i === 0) {
                        renderCards(players[playerIndex], "south", playerIndex, players);
                    } else if (i === 1) {
                        renderCards(players[playerIndex], "west", playerIndex, players);
                    } else if (i === 2) {
                        renderCards(players[playerIndex], "north", playerIndex, players);
                    } else if (i === 3) {
                        renderCards(players[playerIndex], "east", playerIndex, players);
                    }
                }
            }
        }

        socket.on("updateGameStatus", function (data) {
            const deck = document.querySelector(".deck");
            if (data.players[0].deck.length == 0) {
                deck.innerHTML = "";
            }
            updateCards(data.players);
        })

        function toggleReady() {
            var readyBtn = document.getElementById('ready-button');
            var isReady = readyBtn.innerText;

            if (isReady === 'Ready') {
                readyBtn.innerText = 'Not Ready';
            } else {
                readyBtn.innerText = 'Ready';
            }

            socket.emit('ready', {
                playerID: '{{ data.playerID }}',
                roomID: '{{ data.roomID }}',
                readyStatus: readyBtn.innerText !== 'Ready'
            });

        }

        function leaveRoom() {
            socket.emit('leave', {
                roomID: '{{ data.roomID }}',
                sid: socket.id
            })
            window.location.href = '/session';
        }

        function startGame() {
            socket.emit('startGame', {
                roomID: '{{ data.roomID }}',
                numPlayers: '{{ data.numPlayers }}'
            });
        }

        function handlePlayerSelection(players, cardValue) {
            const playerList = {}
            if (cardValue == 1 || cardValue == 2 || cardValue == 3 || cardValue == 6) {
                var choices = ""
                var j = 1;
                for (var i = 0; i < players.length; i++) {
                    if (players[i].sid == socket.id || players[i]["outOfRound"] == true) continue;
                    choices += `${j} - ${players[i].name}\n`
                    playerList[j] = players[i].playerID
                    j++;
                }
            }

            if (cardValue == 5) {
                var choices = ""
                var j = 1;
                for (var i = 0; i < players.length; i++) {
                    if (players[i]["outOfRound"] == true) continue;
                    choices += `${j} - ${players[i].name}\n`
                    playerList[j] = players[i].playerID
                    j++;
                }
            }

            return [playerList, choices]
        }

        function shouldDiscard(player) {
            if (player.hand[0].value == 5 && player.hand[1].value == 7 || player.hand[0].value == 7 && player.hand[1]
                .value == 5 ||
                player.hand[0].value == 6 && player.hand[1].value == 7 || player.hand[0].value == 7 && player.hand[1]
                .value == 6) {
                return true
            }
            return false
        }
    </script>
</body>

</html>