<!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>