Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion locales/en/apgames.json
Original file line number Diff line number Diff line change
Expand Up @@ -5092,7 +5092,8 @@
"TOO_MANY": "You may not place more than two tiles."
},
"product": {
"INSTRUCTIONS": "Players place, on empty hexes, two stones of either color. The only exception is on the first turn, where the first player places just one stone of either color.",
"INITIAL_INSTRUCTIONS": "At the start, place one stone of either color. Click current friendly stone to flip color, click again to empty hex.",
"INSTRUCTIONS": "Players place, on empty hexes, two stones of either color. Click current friendly stone to flip color, click again to empty hex.",
"INCOMPLETE_TURN": "To complete the turn you need two placements.",
"INVALID_PLACEMENT": "Unable to interpret the move notation: {{move}}.",
"NORMALISE": "The move needs to be normalised. Try {{normalised}}.",
Expand Down
22 changes: 14 additions & 8 deletions src/games/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ export class ProductGame extends GameBase {
newmove = `${this.currplayer}${cell}`;
} else {
const moves : string[] = move.split(",");
newmove = this.processMoves(moves, cell, this.currplayer).sort((a, b) => this.sort(a, b)).join(",");
newmove = this.processMoves(moves, cell, this.currplayer)
.sort((a, b) => this.sort(a, b))
.join(",");
}
const result = this.validateMove(newmove) as IClickResult;
if (!result.valid) {
Expand Down Expand Up @@ -306,7 +308,11 @@ export class ProductGame extends GameBase {
result.valid = true;
result.complete = -1;
result.canrender = true;
result.message = i18next.t("apgames:validation.product.INSTRUCTIONS", {count: nMovesTurn});
if (this.stack.length == 1) {
result.message = i18next.t("apgames:validation.product.INITIAL_INSTRUCTIONS");
} else {
result.message = i18next.t("apgames:validation.product.INSTRUCTIONS");
}
return result;
}

Expand All @@ -316,7 +322,7 @@ export class ProductGame extends GameBase {

if (moves.length > nMovesTurn) {
result.valid = false;
result.message = i18next.t("apgames:validation.product.TOO_MANY_MOVES", {count: nMovesTurn});
result.message = i18next.t("apgames:validation.product.TOO_MANY_MOVES");
return result;
}

Expand All @@ -325,9 +331,9 @@ export class ProductGame extends GameBase {
try {
for (const move of moves) {
currentMove = move.slice(1);
const [, y] = this.graph.algebraic2coords(currentMove);
// `algebraic2coords` does not check if the cell is on the board fully.
if (y < 0) { throw new Error("Invalid cell."); }
if (! (this.graph.listCells() as string []).includes(currentMove)) {
throw new Error("Invalid cell.");
}
}
} catch {
result.valid = false;
Expand All @@ -338,7 +344,7 @@ export class ProductGame extends GameBase {
// Is is an empty cell?
let notEmpty;
for (const move of moves) {
if (this.board.has(move.slice(1))) { notEmpty = move; break; }
if (this.board.has(move.slice(1))) { notEmpty = move.slice(1); break; }
}
if (notEmpty) {
result.valid = false;
Expand All @@ -347,7 +353,7 @@ export class ProductGame extends GameBase {
}

// possible to use moves() list to validate, but regex is (kind of?) fun
const regex = new RegExp(`^\\d[a-z]\\d+(,\\d[a-z]\\d+)?$`);
const regex = new RegExp(`^[12][a-z]\\d+(,[12][a-z]\\d+)?$`);
if (!regex.test(m)) {
result.valid = false;
result.message = i18next.t("apgames:validation.product.INVALID_PLACEMENT", {move: m});
Expand Down