From f82975c6385da4d24394cac5e41fff8e21491714 Mon Sep 17 00:00:00 2001 From: Eugene Toder Date: Sun, 22 Feb 2026 18:50:32 -0500 Subject: [PATCH] Remove duplication in handling puzzle modes --- functions/src/game.ts | 41 ++++++++++++++++------------------------- src/game.js | 42 +++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/functions/src/game.ts b/functions/src/game.ts index efd8687..0034421 100644 --- a/functions/src/game.ts +++ b/functions/src/game.ts @@ -170,27 +170,21 @@ function checkSet4Set(a: string, b: string, c: string, d: string) { return [a, b, c, d]; } -function findSetNormal(deck: string[], gameMode: GameMode, state: FindState) { +function* findSetNormal(deck: string[], gameMode: GameMode, state: FindState) { const deckSet = new Set(deck); const first = modes[gameMode].chain && state.lastSet!.length > 0 ? state.lastSet! : deck; - const foundSets = modes[gameMode].puzzle && state.foundSets!; for (let i = 0; i < first.length; i++) { for (let j = first === deck ? i + 1 : 0; j < deck.length; j++) { const c = conjugateCard(first[i], deck[j]); if (deckSet.has(c)) { - const set = [first[i], deck[j], c]; - if (!(foundSets && foundSets.has(set.sort().join("|")))) { - return set; - } + yield [first[i], deck[j], c]; } } } - return null; } -function findSetUltra(deck: string[], gameMode: GameMode, state: FindState) { - const foundSets = modes[gameMode].puzzle && state.foundSets!; +function* findSetUltra(deck: string[], gameMode: GameMode, state: FindState) { const cutoff = modes[gameMode].chain ? state.lastSet!.length : 0; const deckSet = new Set(deck); let first, second, prevSet; @@ -213,18 +207,14 @@ function findSetUltra(deck: string[], gameMode: GameMode, state: FindState) { c2 !== second[j] && c2 !== deck[k] ) { - const set = [first[i], second[j], deck[k], c2]; - if (!(foundSets && foundSets.has(set.sort().join("|")))) { - return set; - } + yield [first[i], second[j], deck[k], c2]; } } } } - return null; } -function findSetGhost(deck: string[], gameMode: GameMode, state: FindState) { +function* findSetGhost(deck: string[], gameMode: GameMode, state: FindState) { for (let i = 0; i < deck.length; i++) { for (let j = i + 1; j < deck.length; j++) { for (let k = j + 1; k < deck.length; k++) { @@ -239,40 +229,41 @@ function findSetGhost(deck: string[], gameMode: GameMode, state: FindState) { deck[m], deck[n] ); - if (cand) return cand; + if (cand) yield cand; } } } } } } - return null; } -function findSet4Set(deck: string[], gameMode: GameMode, state: FindState) { +function* findSet4Set(deck: string[], gameMode: GameMode, state: FindState) { const deckSet = new Set(deck); const first = modes[gameMode].chain && state.lastSet!.length > 0 ? state.lastSet! : deck; - const foundSets = modes[gameMode].puzzle && state.foundSets!; for (let i = 0; i < first.length; i++) { for (let j = i + 1; j < first.length; j++) { for (let k = first === deck ? j + 1 : 0; k < deck.length; k++) { const c = conjugateCard4Set(first[i], first[j], deck[k]); if (deckSet.has(c)) { - const set = [first[i], first[j], deck[k], c]; - if (!(foundSets && foundSets.has(set.sort().join("|")))) { - return set; - } + yield [first[i], first[j], deck[k], c]; } } } } - return null; } /** Find a set in an unordered collection of cards, if any, depending on mode. */ export function findSet(deck: string[], gameMode: GameMode, state: FindState) { - return setTypes[modes[gameMode].setType].findFn(deck, gameMode, state); + const foundSets = modes[gameMode].puzzle && state.foundSets; + const sets = setTypes[modes[gameMode].setType].findFn(deck, gameMode, state); + for (const set of sets) { + if (!(foundSets && foundSets.has(set.sort().join("|")))) { + return set; + } + } + return null; } /** Get the array of cards from a GameEvent */ diff --git a/src/game.js b/src/game.js index 7027a23..1fbf390 100644 --- a/src/game.js +++ b/src/game.js @@ -174,27 +174,21 @@ export function cardTraits(card) { }; } -function findSetNormal(deck, gameMode, state) { +function* findSetNormal(deck, gameMode, state) { const deckSet = new Set(deck); const first = modes[gameMode].chain && state.lastSet.length > 0 ? state.lastSet : deck; - const foundSets = modes[gameMode].puzzle && state.foundSets; for (let i = 0; i < first.length; i++) { for (let j = first === deck ? i + 1 : 0; j < deck.length; j++) { const c = conjugateCard(first[i], deck[j]); if (deckSet.has(c)) { - const set = [first[i], deck[j], c]; - if (!(foundSets && foundSets.has(set.sort().join("|")))) { - return set; - } + yield [first[i], deck[j], c]; } } } - return null; } -function findSetUltra(deck, gameMode, state) { - const foundSets = modes[gameMode].puzzle && state.foundSets; +function* findSetUltra(deck, gameMode, state) { const cutoff = modes[gameMode].chain ? state.lastSet.length : 0; const deckSet = new Set(deck); let first, second, prevSet; @@ -217,18 +211,14 @@ function findSetUltra(deck, gameMode, state) { c2 !== second[j] && c2 !== deck[k] ) { - const set = [first[i], second[j], deck[k], c2]; - if (!(foundSets && foundSets.has(set.sort().join("|")))) { - return set; - } + yield [first[i], second[j], deck[k], c2]; } } } } - return null; } -function findSetGhost(deck, gameMode, state) { +function* findSetGhost(deck, gameMode, state) { for (let i = 0; i < deck.length; i++) { for (let j = i + 1; j < deck.length; j++) { for (let k = j + 1; k < deck.length; k++) { @@ -243,39 +233,41 @@ function findSetGhost(deck, gameMode, state) { deck[m], deck[n] ); - if (cand) return cand; + if (cand) yield cand; } } } } } } - return null; } -function findSet4Set(deck, gameMode, state) { +function* findSet4Set(deck, gameMode, state) { const deckSet = new Set(deck); const first = modes[gameMode].chain && state.lastSet.length > 0 ? state.lastSet : deck; - const foundSets = modes[gameMode].puzzle && state.foundSets; for (let i = 0; i < first.length; i++) { for (let j = i + 1; j < first.length; j++) { for (let k = first === deck ? j + 1 : 0; k < deck.length; k++) { const c = conjugateCard4Set(first[i], first[j], deck[k]); if (deckSet.has(c)) { - const set = [first[i], first[j], deck[k], c]; - if (!(foundSets && foundSets.has(set.sort().join("|")))) { - return set; - } + yield [first[i], first[j], deck[k], c]; } } } } - return null; } +/** Find a set in an unordered collection of cards, if any, depending on mode. */ export function findSet(deck, gameMode, state) { - return setTypes[modes[gameMode].setType].findFn(deck, gameMode, state); + const foundSets = modes[gameMode].puzzle && state.foundSets; + const sets = setTypes[modes[gameMode].setType].findFn(deck, gameMode, state); + for (const set of sets) { + if (!(foundSets && foundSets.has(set.sort().join("|")))) { + return set; + } + } + return null; } export function eventFromCards(cards) {