Skip to content

Commit e31d65a

Browse files
committed
Breaking fix to ersatz double decktet display issues
1 parent 4080d5d commit e31d65a

File tree

1 file changed

+79
-57
lines changed

1 file changed

+79
-57
lines changed

src/games/deckfish.ts

Lines changed: 79 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export class DeckfishGame extends GameBase {
4242
name: "Deckfish",
4343
uid: "deckfish",
4444
playercounts: [2],
45-
version: "20250724",
45+
//version: "20250724",
46+
version: "20250906",
4647
dateAdded: "2025-07-24",
4748
// i18next.t("apgames:descriptions.deckfish")
4849
description: "apgames:descriptions.deckfish",
@@ -120,21 +121,8 @@ export class DeckfishGame extends GameBase {
120121
this.variants = [...variants];
121122
}
122123

123-
// init deck as array of uids b/c Deck does not support a double deck,
124-
//and we don't do anything complicated with cards anyway.
125-
let deck: string[] = [];
126-
127-
const cards = [...cardsBasic, ...cardsExtended];
128-
const deckOfClass = new Deck(cards);
129-
const origSize = deckOfClass.size;
130-
for (let c=0; c<origSize; c++) {
131-
const [card] = deckOfClass.draw();
132-
deck.push(card.uid);
133-
if (this.variants.includes("double")) {
134-
if (card.rank.name !== "Crown")
135-
deck.push(card.uid);
136-
}
137-
}
124+
// init deck
125+
let deck = this.getDeck();
138126
deck = shuffle(deck);
139127

140128
// init board
@@ -227,6 +215,28 @@ export class DeckfishGame extends GameBase {
227215
return [6,7,7];
228216
}
229217

218+
public getDeck(): string[] {
219+
//deck is not Deck but an array of modified uids
220+
//b/c Deck does not support a double deck,
221+
//and we don't do anything complicated with cards anyway.
222+
const deck: string[] = [];
223+
224+
const cards = [...cardsBasic, ...cardsExtended];
225+
const deckOfClass = new Deck(cards);
226+
const origSize = deckOfClass.size;
227+
228+
for (let c=0; c<origSize; c++) {
229+
const [card] = deckOfClass.draw();
230+
deck.push(card.uid + "_0");
231+
232+
if (this.variants.includes("double")) {
233+
if (card.rank.name !== "Crown")
234+
deck.push(card.uid + "_1");
235+
}
236+
}
237+
return deck;
238+
}
239+
230240
/* helper functions for general gameplay */
231241

232242
public canMoveFrom(cell: string): boolean {
@@ -284,22 +294,32 @@ export class DeckfishGame extends GameBase {
284294
}
285295

286296
public getCardFromCell(cell: string): Card {
297+
return this.getCardFromID(this.getIDFromCell(cell))!;
298+
}
299+
300+
public getIDFromCell(cell: string): string {
287301
if (this.board.has(cell)) {
288-
return this.getCardFromUID(this.board.get(cell)!);
302+
return this.board.get(cell)!;
289303
} else if (cell[0] === "m") {
290304
//The market is always fully populated.
291-
return this.getCardFromUID(this.market[this.algebraic2coord(cell)]!);
305+
return this.market[this.algebraic2coord(cell)]!;
292306
} else {
293-
//To keep things defined, we return the Excuse.
294307
throw new Error(`The cell has no card: ${cell}.`);
295-
//return this.getCardFromUID("0");
296308
}
297309
}
298310

311+
public getCardFromID(id: string): Card {
312+
return this.getCardFromUID(this.getUIDFromID(id));
313+
}
314+
299315
public getCardFromUID(uid: string): Card {
300316
return Card.deserialize(uid)!;
301317
}
302318

319+
public getUIDFromID(id: string): string {
320+
return id.split("_")[0];
321+
}
322+
303323
/* end helper functions for general gameplay */
304324

305325
/* suit-based movement logic */
@@ -837,10 +857,11 @@ export class DeckfishGame extends GameBase {
837857
result.message = i18next.t("apgames:validation.deckfish.VALID_PLACEMENT");
838858
} else {
839859
result.valid = false;
840-
if (this.variants.includes("double"))
841-
result.message = i18next.t("apgames:validation.deckfish.INVALID_PLACEMENT_DOUBLE");
842-
else
843-
result.message = i18next.t("apgames:validation.deckfish.INVALID_PLACEMENT");
860+
if (this.variants.includes("double"))
861+
result.message = i18next.t("apgames:validation.deckfish.INVALID_PLACEMENT_DOUBLE");
862+
else
863+
result.message = i18next.t("apgames:validation.deckfish.INVALID_PLACEMENT");
864+
844865
}
845866
return result;
846867
}
@@ -953,35 +974,36 @@ export class DeckfishGame extends GameBase {
953974
// eslint-disable-next-line prefer-const
954975
let [frm, to] = mv.split("-");
955976

956-
const card = this.getCardFromCell(frm);
957-
if (card === undefined)
977+
const cardID = this.getIDFromCell(frm);
978+
if (cardID === undefined)
958979
throw new Error(`Could not load the card at ${frm}.`);
959980

960-
this.highlights.push(card.uid);
981+
this.highlights.push(cardID);
961982

962983
if (to !== undefined && to.length > 0) {
963984
//Remove the card.
964985

965-
this.highlights.push(card.uid);
986+
this.highlights.push(cardID);
966987
if (!partial)
967988
this.board.delete(frm);
968989

969-
this.results.push({type: "move", from: frm, to: to, what: card.uid});
990+
this.results.push({type: "move", from: frm, to: to, what: this.getUIDFromID(cardID)});
970991

971992
//Move the piece from
972993
this.occupied.delete(frm);
973994
//In the wyrms case, must also bounce another piece out of the way.
974995
if (this.occupied.has(to)) {
975996
const bounceCell = this.bounce(frm, to);
976997
this.results.push({type: "eject", from: to, to: bounceCell});
977-
const bounceCard = this.getCardFromCell(bounceCell);
978-
this.highlights.push(bounceCard.uid);
998+
const bounceCardID = this.getIDFromCell(bounceCell);
999+
this.highlights.push(bounceCardID);
9791000
}
9801001

9811002
//Move the piece to
9821003
this.occupied.set(to, this.currplayer);
9831004

984-
//Score the card.
1005+
//Score the card.
1006+
const card = this.getCardFromID(cardID);
9851007
const newSuits = card.suits.map(s => s.uid as Suit);
9861008
newSuits.forEach(s => {
9871009
this.collected[this.currplayer - 1][suitOrder.indexOf(s)]++;
@@ -999,7 +1021,7 @@ export class DeckfishGame extends GameBase {
9991021
this.highlights.push(swapCard);
10001022
this.market[this.market.indexOf(marketCard)] = swapCard!;
10011023
this.board.set(swapCell, marketCard);
1002-
this.results.push({type: "swap", what: marketCard, with: swapCard, where: swapCell});
1024+
this.results.push({type: "swap", what: this.getUIDFromID(marketCard), with: this.getUIDFromID(swapCard), where: swapCell});
10031025
} else {
10041026
//TODO
10051027
}
@@ -1010,10 +1032,10 @@ export class DeckfishGame extends GameBase {
10101032
this.results.push({type: "place", where: frm});
10111033
} else {
10121034
//Partial move already illustrated, though a bit flakily.
1013-
//Highlight potential targets.
1014-
const potentialTargets = this.myMoves(frm);
1015-
potentialTargets.forEach(t =>
1016-
this.highlights.push(this.board.get(t)!)!);
1035+
//Highlight potential targets.
1036+
const potentialTargets = this.myMoves(frm);
1037+
potentialTargets.forEach(t =>
1038+
this.highlights.push(this.board.get(t)!)!);
10171039
}
10181040
}
10191041
}
@@ -1163,11 +1185,11 @@ export class DeckfishGame extends GameBase {
11631185
if (this.board.size > 0) {
11641186
for (const [cell, c] of this.board.entries()) {
11651187
const [x,y] = this.algebraic2coords(cell);
1166-
const card = this.getCardFromUID(c);
1188+
//const card = this.getCardFromID(c);
11671189

11681190
markers.push({
11691191
type: "glyph",
1170-
glyph: "c" + card.uid,
1192+
glyph: "c" + c,
11711193
points: [{row: y, col: x}],
11721194
});
11731195
}
@@ -1187,9 +1209,8 @@ export class DeckfishGame extends GameBase {
11871209
}
11881210
*/
11891211

1190-
// build legend of ALL cards
1191-
const allcards = [...cardsBasic, ...cardsExtended];
1192-
1212+
// build legend of ALL cards, from card ids.
1213+
const allcards = this.getDeck();
11931214
const legend: ILegendObj = {};
11941215

11951216
let lastMarketCard = "";
@@ -1204,21 +1225,22 @@ export class DeckfishGame extends GameBase {
12041225
occupiedCards.set(this.board.get(cell)!,player);
12051226
});
12061227

1207-
for (const card of allcards) {
1208-
const border = (this.highlights.indexOf(card.uid) > -1 || card.uid === lastMarketCard);
1209-
if (occupiedCards.has(card.uid)) {
1210-
const player = occupiedCards.get(card.uid);
1211-
legend["c" + card.uid] = card.toGlyph({border: border, fill: player, opacity: 0.2});
1212-
} else if (this.highlights.indexOf(card.uid) > -1 || this.market.indexOf(card.uid) > -1) {
1213-
legend["c" + card.uid] = card.toGlyph({border: border});
1228+
allcards.forEach(cardID => {
1229+
const card = this.getCardFromID(cardID);
1230+
const border = (this.highlights.indexOf(cardID) > -1 || cardID === lastMarketCard);
1231+
if (occupiedCards.has(cardID)) {
1232+
const player = occupiedCards.get(cardID);
1233+
legend["c" + cardID] = card.toGlyph({border: border, fill: player, opacity: 0.2});
1234+
} else if (this.highlights.indexOf(cardID) > -1 || this.market.indexOf(cardID) > -1) {
1235+
legend["c" + cardID] = card.toGlyph({border: border});
12141236
} else if (this.mode === "place" && card.rank.name === "Ace") {
1215-
legend["c" + card.uid] = card.toGlyph({border: border});
1237+
legend["c" + cardID] = card.toGlyph({border: border});
12161238
} else if (this.mode === "place" && card.rank.name === "Crown" && ! this.variants.includes("double")) {
1217-
legend["c" + card.uid] = card.toGlyph({border: border});
1239+
legend["c" + cardID] = card.toGlyph({border: border});
12181240
} else {
1219-
legend["c" + card.uid] = card.toGlyph({border: border, fill: "#888", opacity: 0.2});
1220-
}
1221-
}
1241+
legend["c" + cardID] = card.toGlyph({border: border, fill: "#888", opacity: 0.2});
1242+
}
1243+
});
12221244

12231245
for (const suit of suits) {
12241246
legend[suit.uid] = {
@@ -1246,7 +1268,7 @@ export class DeckfishGame extends GameBase {
12461268

12471269
//market
12481270
if (this.market.length > 0) {
1249-
const marketCards = this.market.map(uid => Card.deserialize(uid)!).map(c => "c" + c.uid) as [string, ...string[]];
1271+
const marketCards = this.market.map(id => "c" + id) as [string, ...string[]];
12501272

12511273
areas.push({
12521274
type: "pieces",
@@ -1261,10 +1283,10 @@ export class DeckfishGame extends GameBase {
12611283
for (let p = 1; p <= this.numplayers; p++) {
12621284
const captive = this.collected[p-1].reduce((partialSum, a) => partialSum + a, 0);
12631285
if (captive > 0) {
1264-
const indexBySize = this.collected[p-1].map((val, idx) => idx).sort((a, b) => this.collected[p-1][a] - this.collected[p-1][b]);
1286+
const indexBySize = this.collected[p-1].map((val, idx) => idx).sort((a, b) => this.collected[p-1][a] - this.collected[p-1][b]);
12651287
const captives: string[] = [];
12661288
indexBySize.forEach(idx => {
1267-
const cnt = this.collected[p-1][idx];
1289+
const cnt = this.collected[p-1][idx];
12681290
if (cnt > 0) {
12691291
for (let c = 0; c<cnt; c++)
12701292
captives.push(suitOrder[idx]);

0 commit comments

Comments
 (0)