diff --git a/static/css/style.css b/static/css/style.css index 7b895a4..8db7af3 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3,6 +3,7 @@ right: 0; top: 0; padding: 12px; + z-index: 2; } #ready { diff --git a/static/js/dom.js b/static/js/dom.js index 148fda7..d04b629 100644 --- a/static/js/dom.js +++ b/static/js/dom.js @@ -1,5 +1,15 @@ function unlockMapDom() { - document.querySelectorAll(".action").forEach((e) => e.classList.remove("hidden")); + Object.values(REGIONS).forEach((region) => { + if (!allRegionsClaimed() && region.owner === null) { + document + .querySelector(`.node[data-name=${region.name}] .action`) + .classList.remove("hidden"); + } else if (region.owner === us) { + document + .querySelector(`.node[data-name=${region.name}] .action`) + .classList.remove("hidden"); + } + }); } function lockMapDom() { @@ -23,6 +33,10 @@ function updateMapDom() { lockMapDom(); } + if (allRegionsClaimed()) { + document.querySelectorAll(".action").forEach((e) => (e.textContent = "Reinf.")); + } + for (let region of Object.values(REGIONS)) { const element = document.querySelector(`.node[data-name=${region.name}]`); element.querySelector(".strength").textContent = region.strength || ""; diff --git a/static/js/index.js b/static/js/index.js index f464100..621c481 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -91,6 +91,10 @@ document.addEventListener("DOMContentLoaded", () => { if (currentPlayer().reinforce(data)) { currentPlayer().endTurn(); } + } else { + if (currentPlayer().act(data)) { + currentPlayer().endTurn(); + } } updateDom(); diff --git a/static/js/player.js b/static/js/player.js index 2d2be07..431b0c4 100644 --- a/static/js/player.js +++ b/static/js/player.js @@ -1,10 +1,19 @@ +PHASE_REINFORCE = 1; +PHASE_ATTACK = 1; +PHASE_FORTIFY = 1; + 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(); } @@ -66,11 +75,47 @@ class Player { } } + /** + * 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 + ) + ); + } + /** * Start a player's turn. */ startTurn() { this.isPlaying = true; + this.reinforcementsPlaced = 0; + this.reinforcementsAvailable = this.additionalReinforcements(); + this.turnPhase = PHASE_REINFORCE; } /**