189 lines
4.5 KiB
JavaScript
189 lines
4.5 KiB
JavaScript
const PHASE_REINFORCE = 1;
|
|
const PHASE_ATTACK = 2;
|
|
const PHASE_FORTIFY = 3;
|
|
|
|
class Player {
|
|
constructor(id, name) {
|
|
this.name = name;
|
|
this.timeout = null;
|
|
this.id = id;
|
|
this.ready = false;
|
|
|
|
// Data which is reset every turn
|
|
this.isPlaying = false;
|
|
this.reinforcementsPlaced = 0;
|
|
this.reinforcementsAvailable = 0;
|
|
this.turnPhase = PHASE_REINFORCE;
|
|
|
|
this.resetColor();
|
|
}
|
|
|
|
resetTimeout() {
|
|
if (this.timeout !== null) {
|
|
window.clearTimeout(this.timeout);
|
|
}
|
|
|
|
this.timeout = window.setTimeout(() => {
|
|
if (players[this.id] !== undefined) {
|
|
delete players[this.id];
|
|
}
|
|
updateDom();
|
|
}, TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* Get our color as used on the board.
|
|
*/
|
|
getColor() {
|
|
return this.color;
|
|
}
|
|
|
|
resetColor() {
|
|
let randomColor = Math.random() * 360;
|
|
this.color = `hsl(${randomColor} 57% 50%)`;
|
|
}
|
|
|
|
/**
|
|
* Claim a region of the map.
|
|
*
|
|
* @param data Data received via socket.
|
|
*/
|
|
claim(data) {
|
|
let region = Region.getRegion(data.region);
|
|
|
|
if (region.owner === null) {
|
|
region.claim(this);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reinforce a region of the map.
|
|
*
|
|
* @param data Data received via socket.
|
|
*/
|
|
reinforce(data) {
|
|
let region = Region.getRegion(data.region);
|
|
|
|
if (region.owner === this) {
|
|
region.reinforce(1);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process a generic action packet representing a player's move.
|
|
*
|
|
* @param data Data received via socket
|
|
* @returns {boolean} Whether this player's turn has ended or not.
|
|
*/
|
|
act(data) {
|
|
console.log(`player: ${this.id}`);
|
|
console.log(data);
|
|
|
|
if (this.turnPhase === PHASE_REINFORCE) {
|
|
if (this.reinforce(data)) {
|
|
this.reinforcementsPlaced += 1;
|
|
}
|
|
|
|
if (this.reinforcementsPlaced === this.reinforcementsAvailable) {
|
|
this.turnPhase = PHASE_ATTACK;
|
|
}
|
|
|
|
return false;
|
|
} else {
|
|
// End turn prematurely.
|
|
if (data.action === "END") {
|
|
return true;
|
|
}
|
|
|
|
if (this.turnPhase === PHASE_ATTACK && data.action === "ATTACK") {
|
|
if (this.attack(data)) {
|
|
this.turnPhase = PHASE_FORTIFY;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
this.turnPhase = PHASE_FORTIFY;
|
|
|
|
if (data.action === "FORTIFY") {
|
|
return this.fortify(data);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Process an action which is to attack another region.
|
|
*
|
|
* @param data Data received via socket
|
|
*/
|
|
attack(data) {}
|
|
|
|
/**
|
|
* Process an action which is to attack another region.
|
|
*
|
|
* @param data Data received via socket
|
|
*/
|
|
fortify(data) {
|
|
let sender = Region.getRegion(data.startRegion);
|
|
let receiver = Region.getRegion(data.endRegion);
|
|
let strength = parseInt(data.strength);
|
|
|
|
if (
|
|
sender.owner === this &&
|
|
receiver.owner === this &&
|
|
sender.strength > strength
|
|
) {
|
|
receiver.reinforce(strength);
|
|
sender.strength -= strength;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate the number of additional reinforcements to gain on this turn.
|
|
*/
|
|
additionalReinforcements() {
|
|
return Math.min(
|
|
3,
|
|
Math.floor(
|
|
Object.values(REGIONS).filter((region) => region.owner === this).length /
|
|
3
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Start a player's turn.
|
|
*/
|
|
startTurn() {
|
|
this.isPlaying = true;
|
|
this.reinforcementsPlaced = 0;
|
|
this.reinforcementsAvailable = this.additionalReinforcements();
|
|
this.turnPhase = PHASE_REINFORCE;
|
|
}
|
|
|
|
/**
|
|
* End player's turn
|
|
*/
|
|
endTurn() {
|
|
this.isPlaying = false;
|
|
this.nextPlayer().startTurn();
|
|
}
|
|
|
|
nextPlayer() {
|
|
let sorted = Object.values(players).sort((a, b) => (a.id < b.id ? -1 : 1));
|
|
let ourIndex = sorted.findIndex((player) => player.id === this.id);
|
|
|
|
return sorted[(ourIndex + 1) % sorted.length];
|
|
}
|
|
}
|