added moving pawn when player miss a turn
This commit is contained in:
parent
6114d370e9
commit
d0b12137b5
@ -1,109 +1,88 @@
|
|||||||
const RoomModel = require('../schemas/room');
|
const Room = require('../schemas/room');
|
||||||
const { getPawnPositionAfterMove } = require('../utils/functions');
|
const { getPawnPositionAfterMove } = require('../utils/functions');
|
||||||
|
|
||||||
module.exports = (io, socket) => {
|
module.exports = (io, socket) => {
|
||||||
const req = socket.request;
|
const req = socket.request;
|
||||||
|
|
||||||
const getRoom = async () => {
|
const handleMovePawn = async pawnId => {
|
||||||
return await RoomModel.findOne({ _id: req.session.roomId }).exec();
|
const room = await getRoom();
|
||||||
|
const pawn = room.getPawn(pawnId);
|
||||||
|
if (isMoveValid(pawn, room)) {
|
||||||
|
const newPositionOfMovedPawn = getPawnPositionAfterMove(room.rolledNumber, pawn);
|
||||||
|
room.changePositionOfPawn(pawn, newPositionOfMovedPawn);
|
||||||
|
room.beatPawns(newPositionOfMovedPawn, req.session.color);
|
||||||
|
handleChangeOfPlayer(room);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateRoom = async room => {
|
const handleRollDice = async () => {
|
||||||
return await RoomModel.findOneAndUpdate({ _id: req.session.roomId }, room).exec();
|
const rolledNumber = rollDice();
|
||||||
|
const room = await updateRoom({ rolledNumber: rolledNumber });
|
||||||
|
if (!canPlayerMove(room, rolledNumber)) {
|
||||||
|
handleChangeOfPlayer(room);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendToPlayersRolledNumber = rolledNumber => {
|
const rollDice = () => {
|
||||||
io.to(req.session.roomId.toString()).emit('game:roll', rolledNumber);
|
|
||||||
};
|
|
||||||
|
|
||||||
const sendToPlayersData = room => {
|
|
||||||
io.to(req.session.roomId.toString()).emit('room:data', JSON.stringify(room));
|
|
||||||
};
|
|
||||||
|
|
||||||
const rollDice = async () => {
|
|
||||||
const rolledNumber = Math.ceil(Math.random() * 6);
|
const rolledNumber = Math.ceil(Math.random() * 6);
|
||||||
sendToPlayersRolledNumber(rolledNumber);
|
sendToPlayersRolledNumber(rolledNumber);
|
||||||
let room = await updateRoom({ rolledNumber: rolledNumber });
|
return rolledNumber;
|
||||||
if (!canPlayerMove(room, rolledNumber)) {
|
|
||||||
room = changeMovingPlayer(room);
|
|
||||||
await updateRoom(room);
|
|
||||||
sendToPlayersData(room);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const canPlayerMove = (room, rolledNumber) => {
|
const canPlayerMove = (room, rolledNumber) => {
|
||||||
let isMovePossible = false;
|
const playerPawns = room.getPlayerPawns(req.session.color);
|
||||||
const playerPawns = room.pawns.filter(pawn => pawn.color === req.session.color);
|
|
||||||
for (const pawn of playerPawns) {
|
for (const pawn of playerPawns) {
|
||||||
// (if player's pawn is in base) if the rolled number is 1,6
|
if (pawn.canMove(rolledNumber)) return true;
|
||||||
if (pawn.position === pawn.basePos && (rolledNumber === 6 || rolledNumber === 1)) {
|
|
||||||
isMovePossible = true;
|
|
||||||
}
|
}
|
||||||
// (if player's pawn is near finish line) if the move does not go beyond the win line
|
return false;
|
||||||
if (pawn.position !== getPawnPositionAfterMove(rolledNumber, pawn) && pawn.position !== pawn.basePos) {
|
|
||||||
isMovePossible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isMovePossible;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isMoveValid = async (pawn, room) => {
|
const isMoveValid = (pawn, room) => {
|
||||||
if (req.session.color !== pawn.color) {
|
if (req.session.color !== pawn.color) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
currentlyMovingPlayer = room.players.filter(player => player.nowMoving === true);
|
if (req.session.playerId !== room.getCurrentlyMovingPlayer()._id.toString()) {
|
||||||
if (req.session.playerId !== currentlyMovingPlayer._id) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const skipPlayerTurn = async () => {
|
const handleChangeOfPlayer = async room => {
|
||||||
let room = await getRoom();
|
room.changeMovingPlayer();
|
||||||
room = changeMovingPlayer(room);
|
room.timeoutID = setTimeout(makeRandomMove, 15000, room);
|
||||||
await updateRoom(room);
|
await updateRoom(room);
|
||||||
sendToPlayersData(room);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const movePawn = async ({ pawnId }) => {
|
const makeRandomMove = async room => {
|
||||||
let room = await getRoom();
|
if (room.rolledNumber === null) room.rolledNumber = rollDice();
|
||||||
const indexOfPawn = room.pawns.findIndex(pawn => pawn._id == pawnId);
|
const pawnsThatCanMove = room.getPawnsThatCanMove()
|
||||||
if (!isMoveValid(room.pawns[indexOfPawn], room)) return;
|
if (pawnsThatCanMove.length > 0) {
|
||||||
const newPositionOfMovedPawn = getPawnPositionAfterMove(room.rolledNumber, room.pawns[indexOfPawn]);
|
const randomPawn = pawnsThatCanMove[Math.floor(Math.random() * pawnsThatCanMove.length)];
|
||||||
room.pawns[indexOfPawn].position = newPositionOfMovedPawn;
|
room.movePawn(randomPawn);
|
||||||
room = beatPawns(newPositionOfMovedPawn, room);
|
|
||||||
room = changeMovingPlayer(room);
|
|
||||||
await updateRoom(room);
|
|
||||||
sendToPlayersData(room);
|
|
||||||
};
|
|
||||||
|
|
||||||
const beatPawns = (position, room) => {
|
|
||||||
const pawnsInTheSamePosition = room.pawns.filter(pawn => pawn.position === position);
|
|
||||||
pawnsInTheSamePosition.forEach(pawn => {
|
|
||||||
if (pawn.color !== req.session.color) {
|
|
||||||
const index = room.pawns.findIndex(i => i._id === pawn._id);
|
|
||||||
room.pawns[index].position = room.pawns[index].basePos;
|
|
||||||
}
|
}
|
||||||
|
await handleChangeOfPlayer(room);
|
||||||
|
};
|
||||||
|
|
||||||
|
Room.watch().on('change', async () => {
|
||||||
|
sendToPlayersData(await getRoom());
|
||||||
});
|
});
|
||||||
return room;
|
|
||||||
|
const getRoom = async () => {
|
||||||
|
return await Room.findOne({ _id: req.session.roomId }).exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeMovingPlayer = room => {
|
const updateRoom = async room => {
|
||||||
if (room.timeoutID) clearTimeout(room.timeoutID);
|
return await Room.findOneAndUpdate({ _id: req.session.roomId }, room).exec();
|
||||||
const playerIndex = room.players.findIndex(player => player.nowMoving === true);
|
|
||||||
room.players[playerIndex].nowMoving = false;
|
|
||||||
if (playerIndex + 1 === room.players.length) {
|
|
||||||
room.players[0].nowMoving = true;
|
|
||||||
} else {
|
|
||||||
room.players[playerIndex + 1].nowMoving = true;
|
|
||||||
}
|
|
||||||
room.nextMoveTime = Date.now() + 15000;
|
|
||||||
room.rolledNumber = null;
|
|
||||||
room.timeoutID = setTimeout(skipPlayerTurn, 15000);
|
|
||||||
return room;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.on('game:roll', rollDice);
|
const sendToPlayersRolledNumber = rolledNumber => {
|
||||||
socket.on('game:move', movePawn);
|
io.to(req.session.roomId).emit('game:roll', rolledNumber);
|
||||||
socket.on('game:skip', skipPlayerTurn);
|
};
|
||||||
|
|
||||||
|
const sendToPlayersData = room => {
|
||||||
|
io.to(req.session.roomId).emit('room:data', JSON.stringify(room));
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.on('game:roll', handleRollDice);
|
||||||
|
socket.on('game:move', handleMovePawn);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -70,8 +70,8 @@ module.exports = (io, socket) => {
|
|||||||
req.session.reload(err => {
|
req.session.reload(err => {
|
||||||
if (err) return socket.disconnect();
|
if (err) return socket.disconnect();
|
||||||
// Saving session data
|
// Saving session data
|
||||||
req.session.roomId = room._id;
|
req.session.roomId = room._id.toString();
|
||||||
req.session.playerId = room.players[0]._id;
|
req.session.playerId = room.players[0]._id.toString();
|
||||||
req.session.color = room.players[0].color;
|
req.session.color = room.players[0].color;
|
||||||
req.session.save();
|
req.session.save();
|
||||||
// Sending data to the user, after which player will be redirected to the game
|
// Sending data to the user, after which player will be redirected to the game
|
||||||
@ -108,8 +108,8 @@ module.exports = (io, socket) => {
|
|||||||
req.session.reload(err => {
|
req.session.reload(err => {
|
||||||
if (err) return socket.disconnect();
|
if (err) return socket.disconnect();
|
||||||
// Saving session data
|
// Saving session data
|
||||||
req.session.roomId = room._id;
|
req.session.roomId = room._id.toString();
|
||||||
req.session.playerId = updatedRoom.players[updatedRoom.players.length - 1]._id;
|
req.session.playerId = updatedRoom.players[updatedRoom.players.length - 1]._id.toString();
|
||||||
req.session.color = colors[updatedRoom.players.length - 1];
|
req.session.color = colors[updatedRoom.players.length - 1];
|
||||||
req.session.save();
|
req.session.save();
|
||||||
socket.join(room._id.toString());
|
socket.join(room._id.toString());
|
||||||
|
|||||||
@ -28,7 +28,7 @@ module.exports = (io, socket) => {
|
|||||||
}
|
}
|
||||||
room.nextMoveTime = Date.now() + 15000;
|
room.nextMoveTime = Date.now() + 15000;
|
||||||
RoomModel.findOneAndUpdate({ _id: req.session.roomId }, room, function (err, updatedRoom) {
|
RoomModel.findOneAndUpdate({ _id: req.session.roomId }, room, function (err, updatedRoom) {
|
||||||
io.to(req.session.roomId.toString()).emit('room:data', JSON.stringify(updatedRoom));
|
io.to(req.session.roomId).emit('room:data', JSON.stringify(updatedRoom));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
24
backend/schemas/pawn.js
Normal file
24
backend/schemas/pawn.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const { getPawnPositionAfterMove } = require('../utils/functions');
|
||||||
|
|
||||||
|
const PawnSchema = new Schema({
|
||||||
|
color: String,
|
||||||
|
basePos: Number,
|
||||||
|
position: Number,
|
||||||
|
});
|
||||||
|
|
||||||
|
PawnSchema.methods.canMove = function (rolledNumber) {
|
||||||
|
if (this.position === this.basePos && (rolledNumber === 6 || rolledNumber === 1)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// (if player's pawn is near finish line) if the move does not go beyond the win line
|
||||||
|
if (this.position !== getPawnPositionAfterMove(rolledNumber, this) && this.position !== this.basePos) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = PawnSchema;
|
||||||
12
backend/schemas/player.js
Normal file
12
backend/schemas/player.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const PlayerSchema = new Schema({
|
||||||
|
name: String,
|
||||||
|
color: String,
|
||||||
|
ready: { type: Boolean, default: false },
|
||||||
|
nowMoving: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = PlayerSchema;
|
||||||
@ -1,31 +1,76 @@
|
|||||||
var mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const { getPawnPositionAfterMove } = require('../utils/functions');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
const PawnSchema = require('./pawn');
|
||||||
|
const PlayerSchema = require('./player');
|
||||||
|
|
||||||
var Schema = mongoose.Schema;
|
const RoomSchema = new Schema({
|
||||||
|
|
||||||
var RoomSchema = new Schema({
|
|
||||||
createDate: Date,
|
createDate: Date,
|
||||||
started: { type: Boolean, default: false },
|
started: { type: Boolean, default: false },
|
||||||
full: { type: Boolean, default: false },
|
full: { type: Boolean, default: false },
|
||||||
nextMoveTime: Number,
|
nextMoveTime: Number,
|
||||||
timeoutID: Number,
|
timeoutID: Number,
|
||||||
rolledNumber: Number,
|
rolledNumber: Number,
|
||||||
players: [
|
players: [PlayerSchema],
|
||||||
{
|
pawns: [PawnSchema],
|
||||||
name: String,
|
|
||||||
color: String,
|
|
||||||
ready: { type: Boolean, default: false },
|
|
||||||
nowMoving: { type: Boolean, default: false },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
pawns: [
|
|
||||||
{
|
|
||||||
color: String,
|
|
||||||
basePos: Number,
|
|
||||||
position: Number,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var RoomModel = mongoose.model('RoomModel', RoomSchema);
|
RoomSchema.methods.beatPawns = function (position, attackingPawnColor) {
|
||||||
|
const pawnsOnPosition = this.pawns.filter(pawn => pawn.position === position);
|
||||||
|
pawnsOnPosition.forEach(pawn => {
|
||||||
|
if (pawn.color !== attackingPawnColor) {
|
||||||
|
const index = this.getPawnIndex(pawn._id);
|
||||||
|
this.pawns[index].position = this.pawns[index].basePos;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.changeMovingPlayer = function () {
|
||||||
|
const playerIndex = this.players.findIndex(player => player.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() + 15000;
|
||||||
|
this.rolledNumber = null;
|
||||||
|
if (this.timeoutID) clearTimeout(this.timeoutID);
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.movePawn = function (pawn) {
|
||||||
|
const newPositionOfMovedPawn = getPawnPositionAfterMove(this.rolledNumber, pawn);
|
||||||
|
this.changePositionOfPawn(pawn, newPositionOfMovedPawn);
|
||||||
|
this.beatPawns(newPositionOfMovedPawn, pawn.color);
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.getPawnsThatCanMove = function () {
|
||||||
|
const movingPlayer = this.getCurrentlyMovingPlayer();
|
||||||
|
const playerPawns = this.getPlayerPawns(movingPlayer.color);
|
||||||
|
return playerPawns.filter(pawn => pawn.canMove(this.rolledNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomSchema.methods.changePositionOfPawn = function (pawn, newPosition) {
|
||||||
|
const pawnIndex = this.getPawnIndex(pawn._id);
|
||||||
|
this.pawns[pawnIndex].position = newPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.getPawnIndex = function (pawnId) {
|
||||||
|
return this.pawns.findIndex(pawn => pawn._id.toString() === pawnId.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.getPawn = function (pawnId) {
|
||||||
|
return this.pawns.find(pawn => pawn._id.toString() === pawnId.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.getPlayerPawns = function (color) {
|
||||||
|
return this.pawns.filter(pawn => pawn.color === color);
|
||||||
|
};
|
||||||
|
|
||||||
|
RoomSchema.methods.getCurrentlyMovingPlayer = function () {
|
||||||
|
return this.players.find(player => player.nowMoving === true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const RoomModel = mongoose.model('Room', RoomSchema);
|
||||||
|
|
||||||
module.exports = RoomModel;
|
module.exports = RoomModel;
|
||||||
|
|||||||
@ -78,7 +78,7 @@ const Map = ({ pawns, nowMoving, rolledNumber }) => {
|
|||||||
y = event.clientY - rect.top;
|
y = event.clientY - rect.top;
|
||||||
for (const pawn of pawns) {
|
for (const pawn of pawns) {
|
||||||
if (ctx.isPointInPath(pawn.circle, x, y)) {
|
if (ctx.isPointInPath(pawn.circle, x, y)) {
|
||||||
socket.emit('game:move', { pawnId: pawn._id });
|
socket.emit('game:move', pawn._id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setHintPawn(null);
|
setHintPawn(null);
|
||||||
@ -212,9 +212,6 @@ const Map = ({ pawns, nowMoving, rolledNumber }) => {
|
|||||||
socket.on('game:move', () => {
|
socket.on('game:move', () => {
|
||||||
setHintPawn(null);
|
setHintPawn(null);
|
||||||
});
|
});
|
||||||
socket.on('game:skip', () => {
|
|
||||||
setHintPawn(null);
|
|
||||||
});
|
|
||||||
socket.on('game:roll', () => {
|
socket.on('game:roll', () => {
|
||||||
setHintPawn(null);
|
setHintPawn(null);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user