Skip to content

Commit 78e872e

Browse files
authored
Add 4Set Jr puzzle (#174)
1 parent 83eb0e4 commit 78e872e

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

database.rules.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"mode": {
2121
".write": "auth != null && auth.uid == data.parent().child('host').val() && data.parent().child('status').val() == 'waiting' && newData.exists()",
22-
".validate": "newData.isString() && newData.val().matches(/^normal|junior|setchain|ultraset|ultrachain|ultra9|megaset|ghostset|4set|4setjr|4setjrchain|puzzle|ultra9puzzle|shuffle|memory$/)"
22+
".validate": "newData.isString() && newData.val().matches(/^normal|junior|setchain|ultraset|ultrachain|ultra9|megaset|ghostset|4set|4setjr|4setjrchain|puzzle|ultra9puzzle|4setjrpuzzle|shuffle|memory$/)"
2323
},
2424
"enableHint": {
2525
".write": "auth != null && auth.uid == data.parent().child('host').val() && data.parent().child('status').val() == 'waiting' && newData.exists()",
@@ -52,7 +52,7 @@
5252
"events": {
5353
"$eventId": {
5454
".write": "!data.exists() && newData.exists() && auth != null && root.hasChild('games/' + $gameId + '/users/' + auth.uid) && root.child('games/' + $gameId + '/status').val() == 'ingame'",
55-
".validate": "newData.hasChildren(['user', 'time', 'c1', 'c2', 'c3']) && (newData.hasChild('c4') == root.child('games/' + $gameId + '/mode').val().matches(/^ultraset|ultrachain|ultra9|ultra9puzzle|ghostset|4set|4setjr|4setjrchain$/)) && (newData.hasChildren(['c5', 'c6']) == (root.child('games/' + $gameId + '/mode').val() == 'ghostset'))",
55+
".validate": "newData.hasChildren(['user', 'time', 'c1', 'c2', 'c3']) && (newData.hasChild('c4') == root.child('games/' + $gameId + '/mode').val().matches(/^ultraset|ultrachain|ultra9|ultra9puzzle|ghostset|4set|4setjr|4setjrchain|4setjrpuzzle$/)) && (newData.hasChildren(['c5', 'c6']) == (root.child('games/' + $gameId + '/mode').val() == 'ghostset'))",
5656
"user": {
5757
".validate": "newData.isString() && newData.val() == auth.uid"
5858
},

functions/src/game.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,16 @@ function findSet4Set(deck: string[], gameMode: GameMode, state: FindState) {
253253
const deckSet = new Set(deck);
254254
const first =
255255
modes[gameMode].chain && state.lastSet!.length > 0 ? state.lastSet! : deck;
256+
const foundSets = modes[gameMode].puzzle && state.foundSets!;
256257
for (let i = 0; i < first.length; i++) {
257258
for (let j = i + 1; j < first.length; j++) {
258259
for (let k = first === deck ? j + 1 : 0; k < deck.length; k++) {
259260
const c = conjugateCard4Set(first[i], first[j], deck[k]);
260261
if (deckSet.has(c)) {
261-
return [first[i], first[j], deck[k], c];
262+
const set = [first[i], first[j], deck[k], c];
263+
if (!(foundSets && foundSets.has(set.sort().join("|")))) {
264+
return set;
265+
}
262266
}
263267
}
264268
}
@@ -478,6 +482,13 @@ export const modes = {
478482
puzzle: true,
479483
minBoardSize: 9,
480484
},
485+
"4setjrpuzzle": {
486+
setType: "4Set",
487+
traits: 3,
488+
chain: 0,
489+
puzzle: true,
490+
minBoardSize: 11,
491+
},
481492
shuffle: {
482493
setType: "Set",
483494
traits: 4,

src/game.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,16 @@ function findSet4Set(deck, gameMode, state) {
257257
const deckSet = new Set(deck);
258258
const first =
259259
modes[gameMode].chain && state.lastSet.length > 0 ? state.lastSet : deck;
260+
const foundSets = modes[gameMode].puzzle && state.foundSets;
260261
for (let i = 0; i < first.length; i++) {
261262
for (let j = i + 1; j < first.length; j++) {
262263
for (let k = first === deck ? j + 1 : 0; k < deck.length; k++) {
263264
const c = conjugateCard4Set(first[i], first[j], deck[k]);
264265
if (deckSet.has(c)) {
265-
return [first[i], first[j], deck[k], c];
266+
const set = [first[i], first[j], deck[k], c];
267+
if (!(foundSets && foundSets.has(set.sort().join("|")))) {
268+
return set;
269+
}
266270
}
267271
}
268272
}
@@ -609,6 +613,16 @@ export const modes = {
609613
puzzle: true,
610614
minBoardSize: 9,
611615
},
616+
"4setjrpuzzle": {
617+
name: "4Set Jr-Puzzle",
618+
color: "indigo",
619+
description: "Find all 4Sets on the board before moving to the next board.",
620+
setType: "4Set",
621+
traits: 3,
622+
chain: 0,
623+
puzzle: true,
624+
minBoardSize: 11,
625+
},
612626
shuffle: {
613627
name: "Shuffle",
614628
color: "blue",

src/game.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,16 @@ describe("findSet()", () => {
218218
verify4Set(findSet(["0000", "0102", "0210", "0003"], "4setjrchain", state));
219219
verify4Set(findSet(["0000", "0102", "0210", "3201"], "4setjrchain", state));
220220
});
221+
222+
it("can find puzzle 4sets", () => {
223+
const board = ["0000", "0102", "0210", "0312", "1111", "1013", "1203"];
224+
const state = { foundSets: new Set() };
225+
for (let i = 0; i < 7; i++) {
226+
const set = findSet(board, "4setjrpuzzle", state);
227+
verify4Set(set);
228+
expect(state.foundSets.has(set.slice().sort().join("|"))).toBe(false);
229+
state.foundSets.add(set.slice().sort().join("|"));
230+
}
231+
expect(findSet(board, "4setjrpuzzle", state)).toBe(null);
232+
});
221233
});

0 commit comments

Comments
 (0)