mirror of
https://github.com/MaciejkaG/statki.git
synced 2024-11-30 03:42:55 +01:00
Major update
- UI/UX improvements - Multiple bug fixes and improvements
This commit is contained in:
parent
7cfbfa1109
commit
b956120312
94
index.js
94
index.js
@ -447,6 +447,7 @@ io.on('connection', async (socket) => {
|
||||
hostId: opp.request.session.id,
|
||||
state: "pregame",
|
||||
startTs: (new Date()).getTime() / 1000,
|
||||
ready: [false, false],
|
||||
boards: [
|
||||
{ // typ 2 to trójmasztowiec pozycja i obrót na planszy które pola zostały trafione
|
||||
ships: [], // zawiera np. {type: 2, posX: 3, posY: 4, rot: 2, hits: [false, false, true]}
|
||||
@ -528,29 +529,10 @@ io.on('connection', async (socket) => {
|
||||
}
|
||||
}
|
||||
|
||||
let UTCTs = Math.floor((new Date()).getTime() / 1000 + 90);
|
||||
let UTCTs = Math.floor((new Date()).getTime() / 1000 + 180);
|
||||
io.to(playerGame.id).emit('turn update', { turn: 0, phase: "preparation", timerToUTC: UTCTs });
|
||||
GInfo.timer(playerGame.id, 90, async () => {
|
||||
const members = [...roomMemberIterator(playerGame.id)];
|
||||
for (let i = 0; i < members.length; i++) {
|
||||
const sid = members[i][0];
|
||||
const socket = io.sockets.sockets.get(sid);
|
||||
|
||||
let placedShips = await GInfo.depleteShips(socket);
|
||||
placedShips.forEach(shipData => {
|
||||
socket.emit("placed ship", shipData)
|
||||
});
|
||||
|
||||
if (placedShips.length > 0) {
|
||||
const locale = new Lang(session.langs);
|
||||
socket.emit("toast", locale.t("board.Your remaining ships have been randomly placed"))
|
||||
}
|
||||
}
|
||||
|
||||
GInfo.endPrepPhase(socket);
|
||||
GInfo.timer(playerGame.id, 30, () => {
|
||||
AFKEnd(playerGame.id);
|
||||
});
|
||||
GInfo.timer(playerGame.id, 180, async () => {
|
||||
finishPrepPhase(socket, playerGame);
|
||||
});
|
||||
|
||||
await redis.json.set(`game:${playerGame.id}`, '$.state', "preparation");
|
||||
@ -563,6 +545,50 @@ io.on('connection', async (socket) => {
|
||||
}
|
||||
}
|
||||
|
||||
socket.on('ready', async (callback) => {
|
||||
const playerGame = await GInfo.getPlayerGameData(socket);
|
||||
let timeLeft = await GInfo.timerLeft(playerGame.id);
|
||||
|
||||
if (timeLeft > 170) {
|
||||
const locale = new Lang(session.langs);
|
||||
socket.emit('toast', locale.t("board.You cannot ready up so early"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (playerGame && playerGame.data.state === 'preparation') {
|
||||
await GInfo.setReady(socket);
|
||||
const playerGame = await GInfo.getPlayerGameData(socket);
|
||||
|
||||
if (playerGame.data.ready[0] && playerGame.data.ready[1]) {
|
||||
// Both set ready
|
||||
await GInfo.resetTimer(playerGame.id);
|
||||
|
||||
await finishPrepPhase(socket, playerGame);
|
||||
} else if (playerGame.data.ready[0] || playerGame.data.ready[1]) {
|
||||
// One player set ready
|
||||
|
||||
const members = [...roomMemberIterator(playerGame.id)];
|
||||
for (let i = 0; i < members.length; i++) {
|
||||
const sid = members[i][0];
|
||||
const pSocket = io.sockets.sockets.get(sid);
|
||||
if (pSocket.session.id !== socket.session.id) {
|
||||
const locale = new Lang(pSocket.session.langs);
|
||||
|
||||
pSocket.emit("toast", locale.t("board.Your opponent is ready"))
|
||||
}
|
||||
}
|
||||
|
||||
let UTCTs = Math.floor((new Date()).getTime() / 1000 + Math.max(timeLeft / 2.5, 15));
|
||||
io.to(playerGame.id).emit('turn update', { turn: 0, phase: "preparation", timerToUTC: UTCTs });
|
||||
await GInfo.timer(playerGame.id, Math.max(timeLeft / 2.5, 15), async () => {
|
||||
await finishPrepPhase(socket, playerGame);
|
||||
});
|
||||
} // else if (playerGame.data.ready[1]) {
|
||||
// // Guest set ready
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('place ship', async (type, posX, posY, rot) => {
|
||||
const playerGame = await GInfo.getPlayerGameData(socket);
|
||||
|
||||
@ -736,3 +762,27 @@ function checkFlag(key) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function finishPrepPhase(socket, playerGame) {
|
||||
await GInfo.endPrepPhase(socket);
|
||||
|
||||
const members = [...roomMemberIterator(playerGame.id)];
|
||||
for (let i = 0; i < members.length; i++) {
|
||||
const sid = members[i][0];
|
||||
const socket = io.sockets.sockets.get(sid);
|
||||
|
||||
let placedShips = await GInfo.depleteShips(socket);
|
||||
placedShips.forEach(shipData => {
|
||||
socket.emit("placed ship", shipData)
|
||||
});
|
||||
|
||||
if (placedShips.length > 0) {
|
||||
const locale = new Lang(socket.session.langs);
|
||||
socket.emit("toast", locale.t("board.Your remaining ships have been randomly placed"))
|
||||
}
|
||||
}
|
||||
|
||||
GInfo.timer(playerGame.id, 30, () => {
|
||||
AFKEnd(playerGame.id);
|
||||
});
|
||||
}
|
11
lang/en.json
11
lang/en.json
@ -103,6 +103,15 @@
|
||||
"Four-masted": "Four-masted",
|
||||
"Available:": "Available:",
|
||||
|
||||
"Sunk ships": "Sunk ships",
|
||||
"Single-mastedPlu": "Single-masted:",
|
||||
"Two-mastedPlu": "Two-masted:",
|
||||
"Three-mastedPlu": "Three-masted:",
|
||||
"Four-mastedPlu": "Four-masted:",
|
||||
"Your accuracy": "Your accuracy",
|
||||
|
||||
"Ready up": "Ready up",
|
||||
|
||||
"Controls": "Controls",
|
||||
"Change ship": "Change ship",
|
||||
"Rotate ship": "Rotate ship",
|
||||
@ -116,6 +125,8 @@
|
||||
"You have ran out of ships of that type": "You have ran out of ships of that type",
|
||||
"You have already shot at this field": "You have already shot at this field",
|
||||
"Your remaining ships have been randomly placed": "Your remaining ships have been automatically placed",
|
||||
"Your opponent is ready": "Your opponent is ready.\nTime for preparation has been reduced",
|
||||
"You cannot ready up so early": "You cannot ready up so early!",
|
||||
|
||||
"Victory": "Victory",
|
||||
"Defeat": "Defeat"
|
||||
|
11
lang/pl.json
11
lang/pl.json
@ -104,6 +104,15 @@
|
||||
"Four-masted": "Czteromasztowiec",
|
||||
"Available:": "Dostępne:",
|
||||
|
||||
"Sunk ships": "Zatopione statki",
|
||||
"Single-mastedPlu": "Jednomasztowce:",
|
||||
"Two-mastedPlu": "Dwumasztowce:",
|
||||
"Three-mastedPlu": "Trójmasztowce:",
|
||||
"Four-mastedPlu": "Czteromasztowce:",
|
||||
"Your accuracy": "Twoja celność",
|
||||
|
||||
"Ready up": "Gotowy",
|
||||
|
||||
"Controls": "Sterowanie",
|
||||
"Change ship": "Zmień statek",
|
||||
"Rotate ship": "Obróć statek",
|
||||
@ -117,6 +126,8 @@
|
||||
"You have ran out of ships of that type": "Skończyły ci się statki tego typu",
|
||||
"You have already shot at this field": "Już strzelałeś w to pole",
|
||||
"Your remaining ships have been randomly placed": "Twoje pozostałe statki zostały automatycznie rozstawione",
|
||||
"Your opponent is ready": "Twój przeciwnik jest gotowy.\nCzas na przygotowania został skrócony",
|
||||
"You cannot ready up so early": "Nie możesz zgłosić gotowości tak wcześnie!",
|
||||
|
||||
"Victory": "Zwycięstwo",
|
||||
"Defeat": "Porażka"
|
||||
|
@ -176,6 +176,7 @@ h1,h2,h3,h4,h5,h6 {
|
||||
}
|
||||
|
||||
.ownBoardInfo {
|
||||
height: 11rem;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
@ -208,7 +209,7 @@ h1,h2,h3,h4,h5,h6 {
|
||||
to {transform: translateX(0);opacity:1;}
|
||||
}
|
||||
|
||||
#selectedShip.changing {
|
||||
#selectedShip.changing, .ownBoardInfo.changing {
|
||||
opacity: 0;
|
||||
animation: changingOut 1 0.2s ease;
|
||||
}
|
||||
@ -309,7 +310,7 @@ h1,h2,h3,h4,h5,h6 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobileControls button {
|
||||
.mobileControls button, .readyButton {
|
||||
padding: 0.5rem 2rem;
|
||||
font-size: 1rem;
|
||||
background-color: black;
|
||||
@ -322,3 +323,30 @@ h1,h2,h3,h4,h5,h6 {
|
||||
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.readyButton:hover {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.lateBoardInfo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ownBoardInfo #accuracy {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.ownBoardInfo #accuracy.animatingDown {
|
||||
color: var(--ship-invalid);
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.ownBoardInfo #accuracy.animatingUp {
|
||||
color: var(--ship-valid);
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.shipnote {
|
||||
font-weight: bold;
|
||||
}
|
@ -125,16 +125,12 @@ $(".controlsOwnBoard").css("opacity", 1);
|
||||
|
||||
function switchBoards() {
|
||||
if (postPrep) {
|
||||
if (ownBoardIsActive) { // Aktywna jest plansza użytkownika
|
||||
if (ownBoardIsActive) { // Aktywna jest plansza przeciwnika
|
||||
$("#secondaryBoard").removeClass("secondary");
|
||||
$("#board").addClass("secondary");
|
||||
$(".ownBoardInfo").css("opacity", 0);
|
||||
$(".controlsOwnBoard").css("opacity", 0.3);
|
||||
} else { // Aktywna jest plansza przeciwnika
|
||||
} else { // Aktywna jest plansza gracza
|
||||
$("#board").removeClass("secondary");
|
||||
$("#secondaryBoard").addClass("secondary");
|
||||
$(".ownBoardInfo").css("opacity", 1);
|
||||
$(".controlsOwnBoard").css("opacity", 1);
|
||||
}
|
||||
|
||||
ownBoardIsActive = !ownBoardIsActive;
|
||||
|
@ -5,6 +5,11 @@ var timerDestination = null;
|
||||
var gamePhase = 'pregame';
|
||||
var occupiedFields = [];
|
||||
|
||||
var shipsSunk = [0, 0, 0, 0];
|
||||
|
||||
var hits = 0;
|
||||
var misses = 0;
|
||||
|
||||
var lastTimeClick = 0;
|
||||
|
||||
if ($(window).width() <= 820) {
|
||||
@ -48,8 +53,6 @@ $('#board .field').on('click', function () {
|
||||
if (new Date().getTime() / 1000 - lastTimeClick > 0.3) {
|
||||
if ($(window).width() > 820) {
|
||||
socket.emit("place ship", selectedShip, $(this).data('pos-x'), $(this).data('pos-y'), shipRotation);
|
||||
|
||||
navigator.vibrate(200);
|
||||
lastTimeClick = new Date().getTime() / 1000;
|
||||
}
|
||||
}
|
||||
@ -66,8 +69,6 @@ $('#secondaryBoard .field').on('click', function () {
|
||||
if (new Date().getTime() / 1000 - lastTimeClick > 0.3) {
|
||||
if ($(window).width() > 820) {
|
||||
socket.emit("shoot", $(this).data('pos-x'), $(this).data('pos-y'));
|
||||
|
||||
navigator.vibrate(200);
|
||||
lastTimeClick = new Date().getTime() / 1000;
|
||||
}
|
||||
}
|
||||
@ -143,6 +144,8 @@ socket.on("shot hit", (victimIdx, posX, posY) => {
|
||||
bsc.setField(posX, posY, "hit");
|
||||
} else {
|
||||
bsc.setFieldEnemy(posX, posY, "hit");
|
||||
hits++;
|
||||
updateAccuracy(getAccuracy());
|
||||
}
|
||||
});
|
||||
|
||||
@ -151,6 +154,8 @@ socket.on("shot missed", (victimIdx, posX, posY) => {
|
||||
bsc.setField(posX, posY, "miss");
|
||||
} else {
|
||||
bsc.setFieldEnemy(posX, posY, "miss");
|
||||
misses++;
|
||||
updateAccuracy(getAccuracy());
|
||||
}
|
||||
});
|
||||
|
||||
@ -186,6 +191,9 @@ socket.on("ship sunk", (victimIdx, ship) => {
|
||||
bsc.setFieldEnemy(ship.posX + multips[0] * i, ship.posY + multips[1] * i, "sunken");
|
||||
}, i * 150);
|
||||
}
|
||||
|
||||
shipsSunk[ship.type]++;
|
||||
updateShipsSunk();
|
||||
}
|
||||
});
|
||||
|
||||
@ -246,6 +254,17 @@ socket.on('turn update', (turnData) => {
|
||||
$("#whosTurn").html(window.locale["Preparation phase"]);
|
||||
$(".boardSwitch").css("opacity", 0.3);
|
||||
} else {
|
||||
if (!postPrep) {
|
||||
$(".controlsOwnBoard").css("opacity", 0.3);
|
||||
|
||||
$(".ownBoardInfo").addClass("changing");
|
||||
setTimeout(() => {
|
||||
$(".ownBoardInfo").html($(".lateBoardInfo").html());
|
||||
|
||||
$(".ownBoardInfo").removeClass("changing");
|
||||
}, 200);
|
||||
}
|
||||
|
||||
postPrep = true;
|
||||
myTurn = turnData.turn === playerIdx;
|
||||
turnData.turn === playerIdx ? $("#whosTurn").html(window.locale["Your turn"]) : $("#whosTurn").html(window.locale["Opponents turn"]);
|
||||
@ -256,6 +275,71 @@ socket.on('turn update', (turnData) => {
|
||||
gamePhase = turnData.phase;
|
||||
});
|
||||
|
||||
function updateLateInfo() {
|
||||
if (postPrep) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var currentAccuracy = 0;
|
||||
|
||||
function updateAccuracy(val) {
|
||||
var obj = $(".ownBoardInfo #accuracy").get(0);
|
||||
|
||||
const start = currentAccuracy !== null ? currentAccuracy : val;
|
||||
|
||||
const range = val - start;
|
||||
var minTimer = 50;
|
||||
var stepTime = Math.abs(Math.floor(1000 / range));
|
||||
|
||||
stepTime = Math.max(stepTime, minTimer);
|
||||
|
||||
var startTime = new Date().getTime();
|
||||
var endTime = startTime + 1000;
|
||||
var timer;
|
||||
|
||||
if (val < currentAccuracy) {
|
||||
$(".ownBoardInfo #accuracy").addClass("animatingDown");
|
||||
} else {
|
||||
$(".ownBoardInfo #accuracy").addClass("animatingUp");
|
||||
}
|
||||
|
||||
currentAccuracy = val;
|
||||
|
||||
const run = () => {
|
||||
var now = new Date().getTime();
|
||||
var remaining = Math.max((endTime - now) / 1000, 0);
|
||||
var value = Math.round(val - (remaining * range));
|
||||
obj.innerHTML = value + "%";
|
||||
if (value == val) {
|
||||
obj.innerHTML = Math.round(value) + "%";
|
||||
$(".ownBoardInfo #accuracy").removeClass("animatingDown animatingUp");
|
||||
|
||||
clearInterval(timer);
|
||||
}
|
||||
};
|
||||
|
||||
timer = setInterval(run, stepTime);
|
||||
run();
|
||||
}
|
||||
|
||||
function getAccuracy() {
|
||||
return hits / (misses + hits) * 100;
|
||||
}
|
||||
|
||||
function updateShipsSunk() {
|
||||
$("#singlemasted").html(shipsSunk[0]);
|
||||
$("#twomasted").html(shipsSunk[1]);
|
||||
$("#threemasted").html(shipsSunk[2]);
|
||||
$("#fourmasted").html(shipsSunk[3]);
|
||||
}
|
||||
|
||||
function readyUp() {
|
||||
socket.emit("ready", () => {
|
||||
$(".readyButton").css({ pointerEvents: 'none', opacity: 0.3 });
|
||||
});
|
||||
}
|
||||
|
||||
socket.on('player left', () => {
|
||||
window.location.replace("/");
|
||||
});
|
241
test.js
Normal file
241
test.js
Normal file
@ -0,0 +1,241 @@
|
||||
function findEmptyFields(grid, len) {
|
||||
const rowPlacements = [];
|
||||
|
||||
// Helper function to check if a row can be placed horizontally at a given position
|
||||
function canPlaceHorizontally(x, y) {
|
||||
console.log(x, y);
|
||||
// console.log(x + len)
|
||||
// console.log(x + len >= grid.length)
|
||||
if (x + len >= grid[0].length) {
|
||||
return false; // Ship exceeds board boundaries
|
||||
}
|
||||
for (let i = x; i < x + len; i++) {
|
||||
if (grid[i][y]) {
|
||||
return false; // One of ship's fields is already occupied
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper function to check if a row can be placed vertically at a given position
|
||||
function canPlaceVertically(x, y) {
|
||||
// console.log(y + len)
|
||||
// console.log(y + len >= grid.length)
|
||||
if (y + len >= grid.length) {
|
||||
return false; // Ship exceeds board boundaries
|
||||
}
|
||||
for (let i = y; i < y + len; i++) {
|
||||
if (grid[x][i]) {
|
||||
return false; // One of ship's fields is already occupied
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (let i = 0; i < grid.length; i++) {
|
||||
for (let j = 0; j < grid[0].length; j++) {
|
||||
if (grid[j][i] === false) {
|
||||
if (canPlaceHorizontally(j, i)) {
|
||||
rowPlacements.push({ posX: j, posY: i, rot: 0 });
|
||||
}
|
||||
|
||||
if (canPlaceVertically(j, i)) {
|
||||
rowPlacements.push({ posX: j, posY: i, rot: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rowPlacements;
|
||||
}
|
||||
|
||||
let data = {
|
||||
hostId: "123456",
|
||||
state: "action",
|
||||
boards: [
|
||||
{
|
||||
ships: [
|
||||
{ type: 3, posX: 3, posY: 4, rot: 0, hits: [false, false, false] },
|
||||
],
|
||||
shots: [],
|
||||
},
|
||||
{
|
||||
ships: [],
|
||||
shots: [],
|
||||
}
|
||||
],
|
||||
nextPlayer: 0,
|
||||
}
|
||||
|
||||
// checkHit(data, 1, 0, 0);
|
||||
|
||||
// console.log(validateShipPosition(type, posX, posY, rot));
|
||||
|
||||
let boardRender = [];
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
var array = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
array.push(false);
|
||||
}
|
||||
boardRender.push(array);
|
||||
}
|
||||
|
||||
data.boards[0].ships.forEach(ship => {
|
||||
let multips;
|
||||
|
||||
switch (ship.rot) {
|
||||
case 0:
|
||||
multips = [1, 0];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
multips = [0, 1];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
multips = [-1, 0];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
multips = [0, -1];
|
||||
break;
|
||||
}
|
||||
|
||||
for (let i = 0; i <= ship.type; i++) {
|
||||
boardRender[ship.posX + multips[0] * i][ship.posY + multips[1] * i] = true;
|
||||
}
|
||||
});
|
||||
|
||||
// const rot = 0;
|
||||
const type = 3;
|
||||
|
||||
// let multips;
|
||||
|
||||
// switch (rot) {
|
||||
// case 0:
|
||||
// multips = [1, 0];
|
||||
// break;
|
||||
|
||||
// case 1:
|
||||
// multips = [0, 1];
|
||||
// break;
|
||||
|
||||
// case 2:
|
||||
// multips = [-1, 0];
|
||||
// break;
|
||||
|
||||
// case 3:
|
||||
// multips = [0, -1];
|
||||
// break;
|
||||
// }
|
||||
|
||||
boardRender = [
|
||||
[
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true, false, true,
|
||||
true
|
||||
],
|
||||
[
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true, false, true,
|
||||
true
|
||||
],
|
||||
[
|
||||
false, true, true,
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true
|
||||
],
|
||||
[
|
||||
false, true, true,
|
||||
true, false, false,
|
||||
true, true, true,
|
||||
false
|
||||
],
|
||||
[
|
||||
false, false, false,
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
false
|
||||
],
|
||||
[
|
||||
false, false, false,
|
||||
true, true, true,
|
||||
true, true, false,
|
||||
false
|
||||
],
|
||||
[
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true
|
||||
],
|
||||
[
|
||||
true, true, true,
|
||||
true, false, false,
|
||||
false, true, true,
|
||||
true
|
||||
],
|
||||
[
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true, true, true,
|
||||
true
|
||||
],
|
||||
[
|
||||
false, false, false,
|
||||
true, true, true,
|
||||
true, false, false,
|
||||
false
|
||||
]
|
||||
];
|
||||
|
||||
let search = findEmptyFields(boardRender, 4);
|
||||
for (let y = 0; y < 10; y++) {
|
||||
let row = "";
|
||||
for (let x = 0; x < 10; x++) {
|
||||
row += `${boardRender[x][y] ? "\x1b[31m" : "\x1b[32m"}${boardRender[x][y]}\x1b[0m\t`;
|
||||
}
|
||||
console.log(row);
|
||||
}
|
||||
console.log(search);
|
||||
|
||||
const rPos = search[Math.floor(Math.random() * search.length)];
|
||||
|
||||
switch (rPos.rot) {
|
||||
case 0:
|
||||
multips = [1, 0];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
multips = [0, 1];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
multips = [-1, 0];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
multips = [0, -1];
|
||||
break;
|
||||
}
|
||||
|
||||
for (let i = 0; i <= type; i++) {
|
||||
console.log(`boardRender[${rPos.posX + multips[0] * i}][${rPos.posY + multips[1] * i}]`)
|
||||
boardRender[rPos.posX + multips[0] * i][rPos.posY + multips[1] * i] = true;
|
||||
}
|
||||
|
||||
for (let y = 0; y < 10; y++) {
|
||||
let row = "";
|
||||
for (let x = 0; x < 10; x++) {
|
||||
row += `${boardRender[x][y] ? "\x1b[31m" : "\x1b[32m"}${boardRender[x][y]}\x1b[0m\t`;
|
||||
}
|
||||
console.log(row);
|
||||
}
|
||||
|
||||
// console.log();
|
||||
// console.log(findAllRowsOfXTrueValues(matrix, 3, 1));
|
||||
// console.log(findAllRowsOfXTrueValues(matrix, 3, 2));
|
@ -5,8 +5,8 @@ export class GameInfo {
|
||||
}
|
||||
|
||||
async timer(tId, time, callback) {
|
||||
await this.redis.set(`timer:${tId}`, new Date().getTime() / 1000);
|
||||
let localLastUpdate = await this.redis.get(`timer:${tId}`);
|
||||
await this.redis.json.set(`timer:${tId}`, '$', { lastUpdate: new Date().getTime() / 1000, end: new Date().getTime() / 1000 + time });
|
||||
let localLastUpdate = await this.redis.json.get(`timer:${tId}`, { path: ".lastUpdate" });
|
||||
|
||||
let timeout = setTimeout(callback, time * 1000);
|
||||
|
||||
@ -17,7 +17,7 @@ export class GameInfo {
|
||||
return;
|
||||
}
|
||||
|
||||
let lastUpdate = await this.redis.get(`timer:${tId}`);
|
||||
let lastUpdate = await this.redis.json.get(`timer:${tId}`, { path: ".lastUpdate" });
|
||||
if (localLastUpdate != lastUpdate) {
|
||||
// timer has been reset
|
||||
clearTimeout(timeout);
|
||||
@ -27,9 +27,15 @@ export class GameInfo {
|
||||
}, 200);
|
||||
}
|
||||
|
||||
async timerLeft(tId) {
|
||||
let end = await this.redis.json.get(`timer:${tId}`, { path: ".end" });
|
||||
let left = end - new Date().getTime() / 1000;
|
||||
return left;
|
||||
}
|
||||
|
||||
async resetTimer(tId) {
|
||||
let lastUpdate = await this.redis.get(`timer:${tId}`);
|
||||
await this.redis.set(`timer:${tId}`, -lastUpdate);
|
||||
let lastUpdate = await this.redis.json.get(`timer:${tId}`, { path: ".end" });
|
||||
await this.redis.json.set(`timer:${tId}`, '.lastUpdate', -lastUpdate);
|
||||
}
|
||||
|
||||
async isPlayerInGame(socket) {
|
||||
@ -159,13 +165,17 @@ export class GameInfo {
|
||||
let availableShipsOfType = availableShips[i];
|
||||
for (let j = 0; j < availableShipsOfType; j++) {
|
||||
playerShips = (await this.redis.json.get(key, { path: `.boards[${playerIdx}].ships` }));
|
||||
|
||||
let print = "";
|
||||
for (let y = 0; y < 10; y++) {
|
||||
let row = "";
|
||||
for (let x = 0; x < 10; x++) {
|
||||
row += `${boardRender[x][y] ? "\x1b[31m" : "\x1b[32m"}${boardRender[x][y]}\x1b[0m\t`;
|
||||
}
|
||||
print += row+"\n";
|
||||
}
|
||||
const search = findEmptyFields(boardRender, i+1);
|
||||
|
||||
const search = findEmptyFields(boardRender, i + 1);
|
||||
|
||||
const rPos = search[Math.floor(Math.random() * search.length)];
|
||||
|
||||
@ -275,6 +285,16 @@ export class GameInfo {
|
||||
await this.redis.json.set(key, `.boards[${enemyIdx}]`, playerBoard);
|
||||
return { status: 1, ship: shotShip };
|
||||
}
|
||||
|
||||
async setReady(socket) {
|
||||
const gameId = socket.session.activeGame;
|
||||
const key = `game:${gameId}`;
|
||||
const hostId = (await this.redis.json.get(key, { path: '.hostId' }));
|
||||
|
||||
const playerIdx = socket.request.session.id === hostId ? 0 : 1;
|
||||
|
||||
await this.redis.json.set(key, `.ready[${playerIdx}]`, true);
|
||||
}
|
||||
}
|
||||
|
||||
export function isPlayerInRoom(socket) {
|
||||
@ -423,16 +443,18 @@ export function checkTurn(data, playerId) {
|
||||
}
|
||||
|
||||
function findEmptyFields(grid, len) {
|
||||
const rowPlacements = [];
|
||||
const shipPlacements = [];
|
||||
|
||||
// Helper function to check if a row can be placed horizontally at a given position
|
||||
function canPlaceHorizontally(x, y) {
|
||||
if (x + len >= grid[0].length) {
|
||||
return false; // Ship exceeds board boundaries
|
||||
// Check if the ship exceeds the board boundaries horizontally
|
||||
if (x + len > grid.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = x; i <= x + len; i++) {
|
||||
// Check if any field within the ship's length is already occupied
|
||||
for (let i = x; i < x + len; i++) {
|
||||
if (grid[i][y]) {
|
||||
return false; // One of ship's fields is already occupied
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -440,32 +462,35 @@ function findEmptyFields(grid, len) {
|
||||
|
||||
// Helper function to check if a row can be placed vertically at a given position
|
||||
function canPlaceVertically(x, y) {
|
||||
if (y + len >= grid.length) {
|
||||
return false; // Ship exceeds board boundaries
|
||||
// Check if the ship exceeds the board boundaries vertically
|
||||
if (y + len > grid[0].length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = y; i <= y + len; i++) {
|
||||
// Check if any field within the ship's length is already occupied
|
||||
for (let i = y; i < y + len; i++) {
|
||||
if (grid[x][i]) {
|
||||
return false; // One of ship's fields is already occupied
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Loop through the grid to find empty places
|
||||
for (let i = 0; i < grid.length; i++) {
|
||||
for (let j = 0; j < grid[0].length; j++) {
|
||||
if (grid[j][i] === false) {
|
||||
if (canPlaceHorizontally(j, i)) {
|
||||
rowPlacements.push({ posX: j, posY: i, rot: 0 });
|
||||
if (!grid[i][j]) { // Check if the current position is empty
|
||||
if (canPlaceHorizontally(i, j)) {
|
||||
shipPlacements.push({ posX: i, posY: j, rot: 0 });
|
||||
}
|
||||
|
||||
if (canPlaceVertically(j, i)) {
|
||||
rowPlacements.push({ posX: j, posY: i, rot: 1 });
|
||||
if (canPlaceVertically(i, j)) {
|
||||
shipPlacements.push({ posX: i, posY: j, rot: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rowPlacements;
|
||||
return shipPlacements;
|
||||
}
|
||||
|
||||
function clamp(n, min, max) {
|
||||
|
@ -9,16 +9,19 @@ export class Lang {
|
||||
constructor(langs) {
|
||||
const languagesPath = path.join(__dirname, '../lang');
|
||||
this.allText = null;
|
||||
for (let i = 0; i < langs.length; i++) {
|
||||
const lang = langs[i];
|
||||
|
||||
if (fs.readdirSync(languagesPath).includes(`${lang}.json`)) {
|
||||
try {
|
||||
this.allText = JSON.parse(fs.readFileSync(path.join(languagesPath, `${lang}.json`), 'utf8'));
|
||||
this.lang = lang;
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (langs && langs.length > 0) {
|
||||
for (let i = 0; i < langs.length; i++) {
|
||||
const lang = langs[i];
|
||||
|
||||
if (fs.readdirSync(languagesPath).includes(`${lang}.json`)) {
|
||||
try {
|
||||
this.allText = JSON.parse(fs.readFileSync(path.join(languagesPath, `${lang}.json`), 'utf8'));
|
||||
this.lang = lang;
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,17 @@
|
||||
<h2 class="dynamic" id="selectedShip">{{ t 'board.Single-masted' }}</h2>
|
||||
<h3>{{ t 'board.Available:' }} <span class="dynamic danger" id="shipsLeft">-</span></h3>
|
||||
</div>
|
||||
<div class="lateBoardInfo">
|
||||
<h3>{{ t 'board.Sunk ships' }}</h3>
|
||||
<p>
|
||||
{{ t 'board.Single-mastedPlu' }} <span class="dynamic shipnote" id="singlemasted">0</span><br>
|
||||
{{ t 'board.Two-mastedPlu' }} <span class="dynamic shipnote" id="twomasted">0</span><br>
|
||||
{{ t 'board.Three-mastedPlu' }} <span class="dynamic shipnote" id="threemasted">0</span><br>
|
||||
{{ t 'board.Four-mastedPlu' }} <span class="dynamic shipnote" id="fourmasted">0</span><br>
|
||||
</p>
|
||||
<h3>{{ t 'board.Your accuracy' }}</h3>
|
||||
<h2 id="accuracy">-</h2>
|
||||
</div>
|
||||
<span class="break"></span>
|
||||
<div class="controls">
|
||||
<h2>{{ t 'board.Controls' }}</h2>
|
||||
@ -29,6 +40,7 @@
|
||||
<button class="boardSwitch" onclick="switchBoards()">{{ t 'board.Change boards' }}</button>
|
||||
</div>
|
||||
<span class="break"></span>
|
||||
<button class="readyButton" onclick="readyUp()">{{ t 'board.Ready up' }}</button>
|
||||
<h3><span class="dynamic" id="whosTurn"></span></h3>
|
||||
<h2 class="important" id="timer">∞</h2>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user