playship_ludo_pseudo_quick
Version:
Server side neutrino plugin code for ludo game
231 lines (191 loc) • 6.04 kB
JavaScript
const fs = require('fs');
const logger = require('../utils/playshipUtils').getLogger();
const ALL_POS = {};
// home position not required
const RED_HOME_POS = [];
const BLUE_HOME_POS = [];
const GREEN_HOME_POS = [];
const YELLOW_HOME_POS = [];
const RED_PATH = [];
const RED_MAP_PATH = {};
const BLUE_PATH = [];
const BLUE_MAP_PATH = {};
const GREEN_PATH = [];
const GREEN_MAP_PATH = {};
const YELLOW_PATH = [];
const YELLOW_MAP_PATH = {};
let COLORED_AREA_LENGTH;
// No need home pos
const PIECE_TYPE_TO_HOME_POS = {
redPiece: RED_HOME_POS,
bluePiece: BLUE_HOME_POS,
greenPiece: GREEN_HOME_POS,
yellowPiece: YELLOW_HOME_POS,
};
const PIECE_TYPE_TO_PATH = {
redPiece: {path: RED_PATH, mapPath: RED_MAP_PATH},
bluePiece: {path: BLUE_PATH, mapPath: BLUE_MAP_PATH},
greenPiece: {path: GREEN_PATH, mapPath: GREEN_MAP_PATH},
yellowPiece: {path: YELLOW_PATH, mapPath: YELLOW_MAP_PATH},
};
function init() {
let boardJson = readBoardData();
// add all positions
fillUpAllPositionsWithIds(boardJson);
// optimize paths
optimizePaths(boardJson);
// no entry to heaven
/*
COLORED_AREA_LENGTH = boardJson.coloredAreaLength ||
findColoredAreaLength(boardJson) || 4;
*/
}
function findColoredAreaLength(board) {
if (board.safeZones.length > 3) {
let firstDiff = Math.abs(board.safeZones[1] - board.safeZones[0]);
let secondDiff = Math.abs(board.safeZones[2] - board.safeZones[1]);
let minDiff = Math.min(firstDiff, secondDiff);
return (minDiff + 1) /2;
}
}
function rollup(id, position) {
ALL_POS[id] = {
posKey: id,
x: parseFloat(position.x.toFixed(2)),
y: parseFloat(position.y.toFixed(2)),
z: parseFloat(position.z.toFixed(2)),
};
}
function optimizePaths(board) {
for (let i = 0; i < board.redPath.length; i++) {
RED_PATH.push(board.redPath[i]);
RED_MAP_PATH[board.redPath[i]] = i;
}
for (let i = 0; i < board.greenPath.length; i++) {
GREEN_PATH.push(board.greenPath[i]);
GREEN_MAP_PATH[board.greenPath[i]] = i;
}
for (let i = 0; i < board.yellowPath.length; i++) {
YELLOW_PATH.push(board.yellowPath[i]);
YELLOW_MAP_PATH[board.yellowPath[i]] = i;
}
for (let i = 0; i < board.bluePath.length; i++) {
BLUE_PATH.push(board.bluePath[i]);
BLUE_MAP_PATH[board.bluePath[i]] = i;
}
}
function fillUpAllPositionsWithIds(board) {
// add move points
for (let mp of board.movePoints) {
rollup(mp.id, mp.position);
}
// add home positions
for (let rs of board.redStartPoints) {
let startId = 100;
let id = startId + rs.id;
rollup(id, rs.position);
RED_HOME_POS.push(ALL_POS[id]);
ALL_POS[id].isHome = true;
}
for (let rs of board.greenStartPoints) {
let startId = 200;
let id = startId + rs.id;
rollup(id, rs.position);
GREEN_HOME_POS.push(ALL_POS[id]);
ALL_POS[id].isHome = true;
}
for (let rs of board.yellowStartPoints) {
let startId = 300;
let id = startId + rs.id;
rollup(id, rs.position);
YELLOW_HOME_POS.push(ALL_POS[id]);
ALL_POS[id].isHome = true;
}
for (let rs of board.blueStartPoints) {
let startId = 400;
let id = startId + rs.id;
rollup(id, rs.position);
BLUE_HOME_POS.push(ALL_POS[id]);
ALL_POS[id].isHome = true;
}
// add safezones
for (let sf of board.safeZones) {
ALL_POS[sf].isSafePosition = true;
}
// removed heavens heavens
ALL_POS[board.redPath[board.redPath.length - 1]].isHeaven = true;
ALL_POS[board.greenPath[board.greenPath.length - 1]].isHeaven = true;
ALL_POS[board.yellowPath[board.yellowPath.length - 1]].isHeaven = true;
ALL_POS[board.bluePath[board.bluePath.length - 1]].isHeaven = true;
}
function readBoardData() {
let data = fs.readFileSync(__dirname + '/../maps/Board.json', 'utf8');
// parse JSON string to JSON object
logger.debug('Loaded board data,\n', data);
return JSON.parse(data);
}
const nextDestination = function(pieceType, curPos, dist,game,playerId) {
let curBlock = ALL_POS[curPos];
if (!curBlock || curBlock.isHeaven) return null;
if (curBlock.isHome && dist !== 6) return null;
let path = PIECE_TYPE_TO_PATH[pieceType].path;
let mapPath = PIECE_TYPE_TO_PATH[pieceType].mapPath;
// if curblock is home block and it is a 6, move piece to starting position
if (curBlock.isHome) return ALL_POS[path[0]];
let curIndex = mapPath[curPos];
if (isNaN(curIndex)) return null; // something went wrong, cant proceed
let destIndex = curIndex + dist;
if ((destIndex + COLORED_AREA_LENGTH) >= (path.length - 1))
return ALL_POS[path[path.length - 1]];
return ALL_POS[path[destIndex]];
};
const posInfoForPosKey = function(posKey) {
return ALL_POS[posKey];
}
const pieceAllHomePos = function(pieceType) {
return PIECE_TYPE_TO_HOME_POS[pieceType];
};
const posInfoPieceInit = function(pieceType){
return ALL_POS[PIECE_TYPE_TO_PATH[pieceType].path[0]]
}
const revPosKeyFun = function(game, pos) {
if (pos.posKey) return pos.posKey;
const ALLOWED_DIFF = 0.04;
logger.warn({key: game.getId()},
'Reverse pos key function accessed, not optimal, plz check');
for (let p of Object.values(ALL_POS)) {
if (Math.abs(pos.x - p.x) > ALLOWED_DIFF ) continue;
if (Math.abs(pos.y - p.y) > ALLOWED_DIFF ) continue;
if (Math.abs(pos.z - p.z) > ALLOWED_DIFF ) continue;
return p.posKey;
}
};
const calculateDist = function(pieceType, curPos,toPos) {
let barricade = null
let mapPath = PIECE_TYPE_TO_PATH[pieceType].mapPath;
let curIndex = mapPath[curPos];
switch (pieceType){
case "redPiece" :
barricade = RED_PATH.length - 1
break;
case "bluePiece" :
barricade = BLUE_PATH.length - 1
break;
case "yellowPiece" :
barricade = YELLOW_PATH.length - 1
break;
case "greenPiece" :
barricade = GREEN_PATH.length - 1
break;
}
return curIndex + toPos - barricade
}
init();
module.exports = {
nextDestination,
revPosKeyFun,
posInfoForPosKey,
posInfoPieceInit,
pieceAllHomePos,
calculateDist
};