Skip to content

Commit c76aaa0

Browse files
committed
Urbino enhancements and a fix for a "passed validation but does not appear to be legal" error.
1 parent c06c9e2 commit c76aaa0

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

locales/en/apgames.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5185,6 +5185,7 @@
51855185
"INITIAL_INSTRUCTIONS_fresh": "Place an architect in an empty cell.",
51865186
"INITIAL_INSTRUCTIONS_inprogress": "Select an architect to move or select the size of a piece to place.",
51875187
"INVALID_PASS": "You may only pass if you have no other moves available.",
5188+
"INVALID_PIECE": "You don't have a {{piece}} in your stash to place.",
51885189
"INVALID_PLACE_CELL": "The cell {{where}} is not visible to both architects.",
51895190
"INVALID_PLACE_PIECE": {
51905191
"house": "You may not place a house here because it would create multiple blocks of one colour.",

src/games/urbino.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,9 @@ export class UrbinoGame extends GameBase {
499499
} else { // from *has* to be defined if move itself has content
500500
if (smallest === undefined) {
501501
newmove = "pass";
502+
// if you click on a different architect, switch to that one
503+
} else if ( (this.board.has(cell)) && (this.board.get(cell)![0] === 0) && (cell !== from) ) {
504+
newmove = cell;
502505
// if you click on an empty cell, assume movement
503506
} else if ( (this.board.has(from)) && (! this.board.has(cell)) ) {
504507
newmove = `${from}-${cell}`;
@@ -703,6 +706,22 @@ export class UrbinoGame extends GameBase {
703706
}
704707
return result;
705708
}
709+
// Check if player has this piece in their stash
710+
if (this.pieces[this.currplayer - 1][pSize - 1] < 1) {
711+
result.valid = false;
712+
switch (pSize) {
713+
case 1:
714+
result.message = i18next.t("apgames:validation.urbino.INVALID_PIECE", {piece: "house"});
715+
break;
716+
case 2:
717+
result.message = i18next.t("apgames:validation.urbino.INVALID_PIECE", {piece: "tower"});
718+
break;
719+
case 3:
720+
result.message = i18next.t("apgames:validation.urbino.INVALID_PIECE", {piece: "palace"});
721+
break;
722+
}
723+
return result;
724+
}
706725

707726
// we're good
708727
result.valid = true;
@@ -952,6 +971,7 @@ export class UrbinoGame extends GameBase {
952971
public findPoints(): string[] {
953972
const points: string[] = [];
954973
if (this.board.size >= 2) {
974+
// First, find all architect line-of-sight intersections (original behavior)
955975
for (let i = 0; i < 9; i++) {
956976
for (let j = 0; j < 9; j++) {
957977
this.scratchboard[i][j] = 0;
@@ -996,6 +1016,35 @@ export class UrbinoGame extends GameBase {
9961016
return points;
9971017
}
9981018

1019+
/**
1020+
* Enhanced version of findPoints that filters by all placement restrictions.
1021+
* Returns only cells where the current player can actually place a building.
1022+
*/
1023+
public findValidPlacementPoints(): string[] {
1024+
const intersectionPoints = this.findPoints();
1025+
const validPoints: string[] = [];
1026+
1027+
for (const cell of intersectionPoints) {
1028+
// Check if any piece can be placed here
1029+
let canPlaceAny = false;
1030+
for (let size = 1; size <= 3; size++) {
1031+
// Check if player has this piece available
1032+
if (this.pieces[this.currplayer - 1][size - 1] > 0) {
1033+
// Check if placement is valid (adjacency + district rules)
1034+
if (this.validPlacement(cell, size as Size, this.currplayer)) {
1035+
canPlaceAny = true;
1036+
break;
1037+
}
1038+
}
1039+
}
1040+
if (canPlaceAny) {
1041+
validPoints.push(cell);
1042+
}
1043+
}
1044+
1045+
return validPoints;
1046+
}
1047+
9991048
public state(): IUrbinoState {
10001049
return {
10011050
game: UrbinoGame.gameinfo.uid,
@@ -1101,7 +1150,7 @@ export class UrbinoGame extends GameBase {
11011150
},
11021151
pieces: pstr
11031152
};
1104-
const cells = this.findPoints().map(p => UrbinoGame.algebraic2coords(p));
1153+
const cells = this.findValidPlacementPoints().map(p => UrbinoGame.algebraic2coords(p));
11051154
if (cells.length > 0) {
11061155
const points: RowCol[] = [];
11071156
for (const cell of cells) {

0 commit comments

Comments
 (0)