From 5c327cd8d835ef60724088d38ef200b11ff83147 Mon Sep 17 00:00:00 2001 From: Gulum Date: Sat, 6 Jun 2026 21:32:20 +0200 Subject: [PATCH] =?UTF-8?q?GEN-4=20REW=20erweitert:=20alle=203=20C-Kombi?= =?UTF-8?q?=20+=20pp=20=3D=20REW=20(Julian=20best=C3=A4tigt)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cReduced(c) = cchm || ch; REW wenn cReduced(c0) && cReduced(c1) && pp (cchm/cchm, cchm/ch, ch/ch alle REW; mind. ein volles C = NICHT REW) - Counterproof-Test: C/cchm + pp und C/ch + pp = nicht REW - Frozen-Round-Trip-Test: PEW (ch/ch+pp) explizit ausgenommen (intentional shadow durch REW-Check per Julian-Regel; PEW bleibt Dropdown-Name) Gate: build ✓ eslint ✓ vitest 95/95 ✓ e2e 148/148 ✓ --- .../src/genetics/__tests__/genetics.test.ts | 19 ++++++++++++++++--- gerbil-manager-web/src/genetics/catalog.ts | 13 ++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/gerbil-manager-web/src/genetics/__tests__/genetics.test.ts b/gerbil-manager-web/src/genetics/__tests__/genetics.test.ts index 46f767e..7180a70 100644 --- a/gerbil-manager-web/src/genetics/__tests__/genetics.test.ts +++ b/gerbil-manager-web/src/genetics/__tests__/genetics.test.ts @@ -187,7 +187,13 @@ describe('Farbschlag catalog', () => { it('frozen contract names round-trip to themselves (DB-key guard)', () => { // The first 18 are the frozen ColorVariety keys — their representative // genotype MUST resolve back to their own name, never a later variety. + // GEN-4 exception: 'Pink Eyed White (PEW)' (ch/ch+pp) now computes 'REW' + // because the REW engine check (both C-alleles reduced + pp) fires first. + // PEW stays in the catalog as a user-pickable import name; its computed + // farbschlag is intentionally 'REW' per Julian's extended rule. + const REW_SHADOWED = new Set(['Pink Eyed White (PEW)']) for (const entry of BASE_COLORS.slice(0, FROZEN_COUNT)) { + if (REW_SHADOWED.has(entry.name)) continue expect(genotypeToFarbschlag(representativeGenotype(entry))).toBe(entry.name) } }) @@ -538,14 +544,21 @@ describe('GEN-4: Dilute prefix, REW, no-bare-Fuchs', () => { expect(name('aa CC dd EE GG pp spsp rere')).toBe('Dilute Platin') }) - it('REW: cchm/cchm + pp = REW regardless of A/D/E/G', () => { + it('REW: both C alleles reduced (no full C) + pp = REW — all three cases (Julian confirmed)', () => { + // hom cchm/cchm + pp expect(name('AA cchmcchm DD EE GG pp spsp rere')).toBe('REW') // CP-Gold expect(name('AA cchmcchm DD ee GG pp spsp rere')).toBe('REW') // CP-Goldfuchs expect(name('AA cchmcchm DD EE gg pp spsp rere')).toBe('REW') // CP-Elfenbein expect(name('AA cchmcchm DD ee gg pp spsp rere')).toBe('REW') // CP-Apricot expect(name('AA cchmcchm dd EE GG pp spsp rere')).toBe('REW') // CP-dd Gold - // cchm/ch (het) + pp is NOT REW (only homozygous cchm/cchm qualifies) - expect(name('AA cchmch DD EE GG pp spsp rere')).not.toBe('REW') + // het cchm/ch + pp (Julian: also REW) + expect(name('AA cchmch DD EE GG pp spsp rere')).toBe('REW') + // ch/ch + pp (Julian: also REW — subsumes PEW) + expect(name('AA chch DD EE GG pp spsp rere')).toBe('REW') + expect(name('aa chch DD EE GG pp spsp rere')).toBe('REW') + // Counterproof: full C present → NOT REW (residual pigment) + expect(name('AA Ccchm DD EE GG pp spsp rere')).not.toBe('REW') // Cc[chm] + pp = Gold-like + expect(name('AA Cch DD EE GG pp spsp rere')).not.toBe('REW') // Cc[h] + pp }) it('bare Fuchs never appears — dilute-fox combinations are named specifically', () => { diff --git a/gerbil-manager-web/src/genetics/catalog.ts b/gerbil-manager-web/src/genetics/catalog.ts index 4c6c930..786f3f9 100644 --- a/gerbil-manager-web/src/genetics/catalog.ts +++ b/gerbil-manager-web/src/genetics/catalog.ts @@ -253,13 +253,16 @@ export function farbschlagFor(g: Genotype): FarbschlagMatch { if (locusToken(g, 'Sp') === 'Sp') modifiers.push('Schecke') if (locusToken(g, 'Re') === 'Re') modifiers.push('Rex') - // GEN-4 REW check: homozygous colourpoint (cchm/cchm) + pink-eyed (pp) = REW. - // This combination removes both fur pigment (C locus) and eye pigment (P locus) - // regardless of A/D/E/G. Examples: CP-Gold, CP-Goldfuchs, CP-Elfenbein, CP-Apricot. - // Flagged to god for confirmation (condition: cchm×cchm + p×p). + // GEN-4 REW check (Julian confirmed + extended): both C alleles reduced (no full 'C') + // AND pink-eyed (pp) = REW (Rotaugenweiß), A/D/E/G-independent. + // cchm/cchm + pp → REW (CP varieties with pink-eye) + // cchm/ch + pp → REW (het colourpoint + pink-eye) + // ch/ch + pp → REW (this also subsumes the frozen 'Pink Eyed White (PEW)' entry) + // Counterproof: at least one full 'C' + pp → NOT REW (residual pigment remains). const [c0, c1] = resolvedPair(g, 'C') const [p0, p1] = resolvedPair(g, 'P') - if (c0 === 'cchm' && c1 === 'cchm' && p0 === 'p' && p1 === 'p') { + const cReduced = (c: string) => c === 'cchm' || c === 'ch' + if (cReduced(c0) && cReduced(c1) && p0 === 'p' && p1 === 'p') { const name = ['REW', ...modifiers].join(' ') return { name, base: null, unknown: false } }