Riskless/static/js/player.js

136 lines
3.1 KiB
JavaScript
Raw Normal View History

PHASE_REINFORCE = 1;
PHASE_ATTACK = 1;
PHASE_FORTIFY = 1;
2023-01-31 12:34:13 +00:00
class Player {
2023-01-29 16:47:37 +00:00
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;
2023-02-08 17:55:45 +00:00
this.resetColor();
2023-01-29 16:47:37 +00:00
}
resetTimeout() {
if (this.timeout !== null) {
2023-01-31 12:34:13 +00:00
window.clearTimeout(this.timeout);
2023-01-29 16:47:37 +00:00
}
this.timeout = window.setTimeout(() => {
2023-02-06 12:30:24 +00:00
if (players[this.id] !== undefined) {
delete players[this.id];
}
2023-02-06 13:03:25 +00:00
updateDom();
2023-01-29 16:47:37 +00:00
}, TIMEOUT);
}
2023-02-06 11:04:37 +00:00
2023-02-08 17:55:45 +00:00
/**
* Get our color as used on the board.
*/
getColor() {
return this.color;
}
resetColor() {
let randomColor = Math.random() * 360;
this.color = `hsl(${randomColor} 57% 50%)`;
}
2023-02-06 11:04:37 +00:00
/**
* 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);
2023-02-08 17:55:45 +00:00
return true;
} else {
return false;
2023-02-06 11:04:37 +00:00
}
}
2023-02-10 15:47:21 +00:00
/**
* 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) {
if (this.turnPhase === PHASE_REINFORCE) {
if (this.reinforce(data)) {
this.reinforcementsPlaced += 1;
}
if (this.reinforcementsPlaced === this.reinforcementsAvailable) {
this.turnPhase = PHASE_ATTACK;
}
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
)
);
}
2023-02-06 11:04:37 +00:00
/**
* Start a player's turn.
*/
startTurn() {
this.isPlaying = true;
this.reinforcementsPlaced = 0;
this.reinforcementsAvailable = this.additionalReinforcements();
this.turnPhase = PHASE_REINFORCE;
2023-02-06 11:04:37 +00:00
}
/**
* End player's turn
*/
endTurn() {
this.isPlaying = false;
2023-02-06 12:30:24 +00:00
this.nextPlayer().startTurn();
2023-02-06 11:04:37 +00:00
}
nextPlayer() {
let sorted = Object.values(players).sort((a, b) => (a.id < b.id ? -1 : 1));
2023-02-08 17:55:45 +00:00
let ourIndex = sorted.findIndex((player) => player.id === this.id);
2023-02-06 11:04:37 +00:00
return sorted[(ourIndex + 1) % sorted.length];
}
2023-01-29 16:47:37 +00:00
}