Skip to content

Commit 8026a77

Browse files
committed
Tablero: Abba variant for testing
1 parent f5faea9 commit 8026a77

File tree

2 files changed

+53
-36
lines changed

2 files changed

+53
-36
lines changed

locales/en/apgames.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,10 @@
13721372
"5-10": {
13731373
"name": "Compressed range (5–10)",
13741374
"description": "By adding 4 to the value of each centre space, the ratio of highest space to lowest is compressed from 6:1 to 2:1. This incentivizes more active competition for lower spaces."
1375+
},
1376+
"abba": {
1377+
"name": "Balanced start",
1378+
"description": "On the first move of the game, the player only rolls one die."
13751379
}
13761380
},
13771381
"tafl": {

src/games/tablero.ts

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export type playerid = 1|2;
1212
export interface IMoveState extends IIndividualState {
1313
currplayer: playerid;
1414
board: Map<string, playerid[]>;
15-
roll: [number,number];
15+
roll: [number,number]|[number];
1616
pieces: [number,number];
1717
lastmove?: string;
1818
bumped?: playerid;
@@ -47,7 +47,7 @@ export class TableroGame extends GameBase {
4747
urls: ["https://crabfragmentlabs.com/"],
4848
},
4949
],
50-
variants: [{uid: "5-10", group: "scoring"}],
50+
variants: [{uid: "5-10", group: "scoring"}, {uid: "abba"}],
5151
categories: ["goal>score>eog", "mechanic>place", "mechanic>move", "mechanic>coopt", "mechanic>random>play", "mechanic>stack", "board>shape>rect", "board>connect>rect", "components>simple>1per"],
5252
flags: ["limited-pieces", "perspective", "scores", "automove", "no-explore", "custom-rotation"]
5353
};
@@ -83,7 +83,7 @@ export class TableroGame extends GameBase {
8383
public currplayer: playerid = 1;
8484
public board!: Map<string, playerid[]>;
8585
public gameover = false;
86-
public roll!: [number,number];
86+
public roll!: [number,number]|[number];
8787
public bumped?: playerid;
8888
public pieces!: [number,number];
8989
public winner: playerid[] = [];
@@ -101,7 +101,10 @@ export class TableroGame extends GameBase {
101101
this.variants = [...variants];
102102
}
103103
const d1 = randomInt(6);
104-
const d2= randomInt(6);
104+
let d2: number|undefined;
105+
if (!this.variants.includes("abba")) {
106+
d2 = randomInt(6);
107+
}
105108
const board = new Map<string, playerid[]>();
106109
const fresh: IMoveState = {
107110
_version: TableroGame.gameinfo.version,
@@ -110,9 +113,9 @@ export class TableroGame extends GameBase {
110113
currplayer: 1,
111114
board,
112115
pieces: [12,12],
113-
roll: [d1, d2],
116+
roll: d2 === undefined ? [d1] : [d1, d2],
114117
};
115-
this.results = [{type: "roll", values: [d1,d2]}];
118+
this.results = [{type: "roll", values: d2 === undefined ? [d1] : [d1,d2]}];
116119
this.stack = [fresh];
117120
} else {
118121
if (typeof state === "string") {
@@ -157,37 +160,42 @@ export class TableroGame extends GameBase {
157160
first.push(...this.getFirstMoves(num).filter(m => m !== "bump"));
158161
}
159162

160-
// then for each initial move, get possible second moves
161163
let moves: string[] = [];
162-
for (const moveFirst of first) {
163-
const d6First = TableroGame.move2d6(moveFirst);
164-
let d6Second: number;
165-
if (this.roll[0] === this.roll[1]) {
166-
d6Second = d6First;
167-
} else {
168-
d6Second = this.roll.find(n => n !== d6First)!;
169-
}
170-
// copy game, make the move, then get possible follow-ups
171-
const cloned = TableroGame.clone(this);
172-
// set trusted to avoid infinite recursion
173-
cloned.move(moveFirst, {partial: true, trusted: true});
174-
const second = cloned.getFirstMoves(d6Second);
175-
for (const sec of second) {
176-
moves.push(`${moveFirst},${sec}`);
164+
// then, for each initial move, get possible second moves
165+
// unless this is the first move of an abba game
166+
if (this.roll.length > 1) {
167+
for (const moveFirst of first) {
168+
const d6First = TableroGame.move2d6(moveFirst);
169+
let d6Second: number;
170+
if (this.roll[0] === this.roll[1]) {
171+
d6Second = d6First;
172+
} else {
173+
d6Second = this.roll.find(n => n !== d6First)!;
174+
}
175+
// copy game, make the move, then get possible follow-ups
176+
const cloned = TableroGame.clone(this);
177+
// set trusted to avoid infinite recursion
178+
cloned.move(moveFirst, {partial: true, trusted: true});
179+
const second = cloned.getFirstMoves(d6Second);
180+
for (const sec of second) {
181+
moves.push(`${moveFirst},${sec}`);
182+
}
177183
}
178-
}
179184

180-
// if doubles, add taking options and remove any bump options
181-
if (this.roll[0] === this.roll[1]) {
182-
for (const [cell, stack] of this.board.entries()) {
183-
if (stack[stack.length - 1] === this.currplayer) {
184-
moves.push(`-${cell}`);
185+
// if doubles, add taking options and remove any bump options
186+
if (this.roll[0] === this.roll[1]) {
187+
for (const [cell, stack] of this.board.entries()) {
188+
if (stack[stack.length - 1] === this.currplayer) {
189+
moves.push(`-${cell}`);
190+
}
191+
}
192+
// if there are any removal options, you can't bump
193+
if (moves.filter(m => m.startsWith("-")).length > 0) {
194+
moves = moves.filter(m => ! m.includes("bump"))
185195
}
186196
}
187-
// if there are any removal options, you can't bump
188-
if (moves.filter(m => m.startsWith("-")).length > 0) {
189-
moves = moves.filter(m => ! m.includes("bump"))
190-
}
197+
} else {
198+
moves = [...first];
191199
}
192200

193201
// if *none* of the dice can be used, then `moves` will be empty
@@ -624,7 +632,7 @@ export class TableroGame extends GameBase {
624632

625633
// If we've gotten here, all submoves are valid.
626634
// But how many submoves did we get? Is the move really complete?
627-
if ( (moves.length === 2) || (m === "bump") || (m.startsWith("-")) ) {
635+
if ( moves.length === this.roll.length || m === "bump" || m.startsWith("-") ) {
628636
// final check against move list
629637
if (! origMoves.includes(m)) {
630638
result.valid = false;
@@ -1008,15 +1016,15 @@ export class TableroGame extends GameBase {
10081016
opacity: this.emulated ? 0 : 1,
10091017
},
10101018
D2: {
1011-
name: `d6-${this.roll[1]}`,
1019+
name: `d6-${this.roll.length > 1 ? this.roll[1] : 1}`,
10121020
opacity: this.emulated ? 0 : 1,
10131021
}
10141022
},
10151023
pieces: pstr,
10161024
areas: [
10171025
{
10181026
type: "key",
1019-
list: [
1027+
list: this.roll.length > 1 ? [
10201028
{
10211029
piece: "D1",
10221030
name: ""
@@ -1025,6 +1033,11 @@ export class TableroGame extends GameBase {
10251033
piece: "D2",
10261034
name: ""
10271035
}
1036+
] : [
1037+
{
1038+
piece: "D1",
1039+
name: ""
1040+
}
10281041
],
10291042
position: "right",
10301043
clickable: false,
@@ -1059,7 +1072,7 @@ export class TableroGame extends GameBase {
10591072
}
10601073
rep.areas!.push({
10611074
type: "pieces",
1062-
pieces: ["PD1","PD2"],
1075+
pieces: prevRoll.length > 1 ? ["PD1","PD2"] : ["PD1"],
10631076
label: i18next.t("apgames:validation.tablero.LABEL_PREVIOUS") || "local",
10641077
});
10651078
}

0 commit comments

Comments
 (0)