Update game mechanics and improve pawn movement logic; refactor connection URI and enhance server list handling
This commit is contained in:
@@ -9,7 +9,8 @@ const PawnSchema = new Schema({
|
||||
});
|
||||
|
||||
PawnSchema.methods.canMove = function (rolledNumber) {
|
||||
if (this.position === this.basePos && (rolledNumber === 6 || rolledNumber === 1)) {
|
||||
// Pawn can leave base only when a 6 is rolled
|
||||
if (this.position === this.basePos && rolledNumber === 6) {
|
||||
return true;
|
||||
}
|
||||
// (if player's pawn is near finish line) if the move does not go beyond the win line
|
||||
|
||||
+69
-16
@@ -63,12 +63,22 @@ RoomSchema.methods.beatPawns = function (position, attackingPawnColor) {
|
||||
|
||||
RoomSchema.methods.changeMovingPlayer = function () {
|
||||
if (this.winner) return;
|
||||
const playerIndex = this.players.findIndex(player => player.nowMoving === true);
|
||||
this.players[playerIndex].nowMoving = false;
|
||||
if (playerIndex + 1 === this.players.length) {
|
||||
if (!Array.isArray(this.players) || this.players.length === 0) {
|
||||
console.warn(`[room:${this._id}] changeMovingPlayer: players array is empty or null`);
|
||||
return;
|
||||
}
|
||||
const playerIndex = this.players.findIndex(player => player && player.nowMoving === true);
|
||||
if (playerIndex === -1) {
|
||||
console.warn(`[room:${this._id}] changeMovingPlayer: no player currently marked as nowMoving`);
|
||||
// Default to first player
|
||||
this.players[0].nowMoving = true;
|
||||
} else {
|
||||
this.players[playerIndex + 1].nowMoving = true;
|
||||
this.players[playerIndex].nowMoving = false;
|
||||
if (playerIndex + 1 === this.players.length) {
|
||||
this.players[0].nowMoving = true;
|
||||
} else {
|
||||
this.players[playerIndex + 1].nowMoving = true;
|
||||
}
|
||||
}
|
||||
this.nextMoveTime = Date.now() + MOVE_TIME;
|
||||
this.rolledNumber = null;
|
||||
@@ -76,6 +86,22 @@ RoomSchema.methods.changeMovingPlayer = function () {
|
||||
timeoutManager.set(makeRandomMove, MOVE_TIME, this._id.toString());
|
||||
};
|
||||
|
||||
RoomSchema.methods.resetTurnForSamePlayer = function () {
|
||||
if (this.winner) return;
|
||||
// Keep the same player moving but reset the roll and move timer
|
||||
const now = Date.now();
|
||||
const currentPlayer = this.getCurrentlyMovingPlayer();
|
||||
if (!currentPlayer) {
|
||||
console.warn(`[room:${this._id}] resetTurnForSamePlayer: No current player found!`);
|
||||
return;
|
||||
}
|
||||
this.nextMoveTime = now + MOVE_TIME;
|
||||
this.rolledNumber = null;
|
||||
console.log(`[room:${this._id}] resetTurnForSamePlayer: player=${currentPlayer.color}, now=${now}, nextMoveTime=${this.nextMoveTime}, MOVE_TIME=${MOVE_TIME}`);
|
||||
timeoutManager.clear(this._id.toString());
|
||||
timeoutManager.set(makeRandomMove, MOVE_TIME, this._id.toString());
|
||||
};
|
||||
|
||||
RoomSchema.methods.movePawn = function (pawn) {
|
||||
const newPositionOfMovedPawn = pawn.getPositionAfterMove(this.rolledNumber);
|
||||
this.changePositionOfPawn(pawn, newPositionOfMovedPawn);
|
||||
@@ -84,8 +110,9 @@ RoomSchema.methods.movePawn = function (pawn) {
|
||||
|
||||
RoomSchema.methods.getPawnsThatCanMove = function () {
|
||||
const movingPlayer = this.getCurrentlyMovingPlayer();
|
||||
if (!movingPlayer) return [];
|
||||
const playerPawns = this.getPlayerPawns(movingPlayer.color);
|
||||
return playerPawns.filter(pawn => pawn.canMove(this.rolledNumber));
|
||||
return (playerPawns || []).filter(pawn => pawn.canMove(this.rolledNumber));
|
||||
};
|
||||
|
||||
RoomSchema.methods.changePositionOfPawn = function (pawn, newPosition) {
|
||||
@@ -94,10 +121,15 @@ RoomSchema.methods.changePositionOfPawn = function (pawn, newPosition) {
|
||||
};
|
||||
|
||||
RoomSchema.methods.canStartGame = function () {
|
||||
return this.players.filter(player => player.ready).length >= 2;
|
||||
if (!Array.isArray(this.players)) return false;
|
||||
return this.players.filter(player => player && player.ready).length >= 2;
|
||||
};
|
||||
|
||||
RoomSchema.methods.startGame = function () {
|
||||
if (!Array.isArray(this.players) || this.players.length === 0) {
|
||||
console.warn(`[room:${this._id}] startGame: players array empty`);
|
||||
return;
|
||||
}
|
||||
this.started = true;
|
||||
this.nextMoveTime = Date.now() + MOVE_TIME;
|
||||
this.players.forEach(player => (player.ready = true));
|
||||
@@ -109,28 +141,30 @@ RoomSchema.methods.endGame = function (winner) {
|
||||
timeoutManager.clear(this._id.toString());
|
||||
this.rolledNumber = null;
|
||||
this.nextMoveTime = null;
|
||||
this.players.map(player => (player.nowMoving = false));
|
||||
if (Array.isArray(this.players)) this.players.forEach(player => (player.nowMoving = false));
|
||||
this.winner = winner;
|
||||
this.save();
|
||||
};
|
||||
|
||||
RoomSchema.methods.getWinner = function () {
|
||||
if (this.pawns.filter(pawn => pawn.color === 'red' && pawn.position === 73).length === 4) {
|
||||
if (!Array.isArray(this.pawns)) return null;
|
||||
if (this.pawns.filter(pawn => pawn && pawn.color === 'red' && pawn.position === 73).length === 4) {
|
||||
return 'red';
|
||||
}
|
||||
if (this.pawns.filter(pawn => pawn.color === 'blue' && pawn.position === 79).length === 4) {
|
||||
if (this.pawns.filter(pawn => pawn && pawn.color === 'blue' && pawn.position === 79).length === 4) {
|
||||
return 'blue';
|
||||
}
|
||||
if (this.pawns.filter(pawn => pawn.color === 'green' && pawn.position === 85).length === 4) {
|
||||
if (this.pawns.filter(pawn => pawn && pawn.color === 'green' && pawn.position === 85).length === 4) {
|
||||
return 'green';
|
||||
}
|
||||
if (this.pawns.filter(pawn => pawn.color === 'yellow' && pawn.position === 91).length === 4) {
|
||||
if (this.pawns.filter(pawn => pawn && pawn.color === 'yellow' && pawn.position === 91).length === 4) {
|
||||
return 'yellow';
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
RoomSchema.methods.isFull = function () {
|
||||
if (!Array.isArray(this.players)) return false;
|
||||
if (this.players.length === 4) {
|
||||
this.full = true;
|
||||
}
|
||||
@@ -138,11 +172,13 @@ RoomSchema.methods.isFull = function () {
|
||||
};
|
||||
|
||||
RoomSchema.methods.getPlayer = function (playerId) {
|
||||
return this.players.find(player => player._id.toString() === playerId.toString());
|
||||
if (!Array.isArray(this.players)) return null;
|
||||
return this.players.find(player => player && player._id && player._id.toString() === playerId.toString()) || null;
|
||||
};
|
||||
|
||||
RoomSchema.methods.addPlayer = function (name, id) {
|
||||
if (this.full) return;
|
||||
if (!Array.isArray(this.players)) this.players = [];
|
||||
this.players.push({
|
||||
sessionID: id,
|
||||
name: name,
|
||||
@@ -152,19 +188,36 @@ RoomSchema.methods.addPlayer = function (name, id) {
|
||||
};
|
||||
|
||||
RoomSchema.methods.getPawnIndex = function (pawnId) {
|
||||
return this.pawns.findIndex(pawn => pawn._id.toString() === pawnId.toString());
|
||||
if (!Array.isArray(this.pawns)) return -1;
|
||||
return this.pawns.findIndex(pawn => pawn && pawn._id && pawn._id.toString() === pawnId.toString());
|
||||
};
|
||||
|
||||
RoomSchema.methods.getPawn = function (pawnId) {
|
||||
return this.pawns.find(pawn => pawn._id.toString() === pawnId.toString());
|
||||
if (!Array.isArray(this.pawns)) return null;
|
||||
return this.pawns.find(pawn => pawn && pawn._id && pawn._id.toString() === pawnId.toString()) || null;
|
||||
};
|
||||
|
||||
RoomSchema.methods.getPlayerPawns = function (color) {
|
||||
return this.pawns.filter(pawn => pawn.color === color);
|
||||
if (!Array.isArray(this.pawns)) return [];
|
||||
return this.pawns.filter(pawn => pawn && pawn.color === color);
|
||||
};
|
||||
|
||||
RoomSchema.methods.getPawnsOnPosition = function (position) {
|
||||
if (!Array.isArray(this.pawns)) return [];
|
||||
return this.pawns.filter(pawn => pawn && pawn.position === position);
|
||||
};
|
||||
|
||||
RoomSchema.methods.isStacked = function (position) {
|
||||
return this.getPawnsOnPosition(position).length > 1;
|
||||
};
|
||||
|
||||
RoomSchema.methods.getOpponentPawnsOnPosition = function (position, color) {
|
||||
return this.getPawnsOnPosition(position).filter(pawn => pawn.color !== color);
|
||||
};
|
||||
|
||||
RoomSchema.methods.getCurrentlyMovingPlayer = function () {
|
||||
return this.players.find(player => player.nowMoving === true);
|
||||
if (!Array.isArray(this.players)) return null;
|
||||
return this.players.find(player => player && player.nowMoving === true) || null;
|
||||
};
|
||||
|
||||
const Room = mongoose.model('Room', RoomSchema);
|
||||
|
||||
Reference in New Issue
Block a user