Weltkueche: 6 Zutaten mit fest verdrahteter Herkunft (Thomas-Vorgaben)

Kein Automatismus mehr - Zutat hat feste Laenderliste (correct) + feste
Distraktoren, die das Spiel 1:1 ausliest. Vorrang vor Consumer/Heimat.
- greyerzer (NEU, "Greyerzer & Vacherin"): Schweiz+Frankreich -> ersetzt den
  mozzarella-Hack im Fondue (Signatur entfernt, Rezept nannte Gruyere+Vacherin
  schon korrekt).
- hefe: Oesterreich+Frankreich | lamm: Neuseeland+UK (Import, nicht Griechenland)
  tomaten: Niederlande+Spanien | schmand: Oesterreich+Deutschland
  fischsauce: Thailand+Vietnam (nicht Italien).
game.html: schlanker Auslese-Zweig fuer `correct`/`distractors` (isWorldIngredient
+ ING-Build + Aufloesungstext). admin spiegelt als "Feste Herkunft".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 00:35:24 +02:00
parent d7dd3f9de5
commit 13f14c26a8
4 changed files with 116 additions and 7 deletions
+7 -1
View File
@@ -99,6 +99,12 @@ function classify(ingKey, heimat, isSig){
var ing = PM[ingKey]; if (!ing) return null;
var producers = ing.producers || {};
var keys = Object.keys(producers).filter(function(c){ return C[c]; });
// ── FEST VERDRAHTETE HERKUNFT: feste Länderliste + feste Distraktoren.
if (ing.correct && ing.correct.length) {
var fc = ing.correct.filter(function(c){ return C[c]; });
var fd = (ing.distractors||[]).filter(function(c){ return C[c] && fc.indexOf(c)<0; });
return { correct: fc, distractors: fd, branch:'fest', grav:function(){return 0;} };
}
// ── CONSUMER-REGEL (Teil B): Grundzutat, im Land des Users heimisch → kommt aus
// dem Land des Users (unabhängig vom Gericht-Land). Signaturzutaten ausgenommen.
if (!isSig && ing.heimisch && ing.heimisch.indexOf(WK_USER) >= 0 && C[WK_USER]) {
@@ -175,7 +181,7 @@ function render(){
if (onlyWarn && !warn) return;
var okChips = cl.correct.map(function(c){ return ctyChip(c,'ok',k,heimat,true); }).join('');
var distChips = cl.distractors.slice(0,6).map(function(c){ return ctyChip(c,'dist',k,heimat,false); }).join('');
rows += '<tr><td class="ing-nm">'+(PM[k].ic||'')+' '+(PM[k].nm||k)+'<small>'+(cl.branch==='consumer'?'🛒 Consumer-Regel (User-Land)':(cl.branch==='heimat'?'Heimat-Regel':'Welt-Zutat'))+'</small></td>'
rows += '<tr><td class="ing-nm">'+(PM[k].ic||'')+' '+(PM[k].nm||k)+'<small>'+(cl.branch==='fest'?'📌 Feste Herkunft':(cl.branch==='consumer'?'🛒 Consumer-Regel (User-Land)':(cl.branch==='heimat'?'Heimat-Regel':'Welt-Zutat')))+'</small></td>'
+ '<td><div class="colhead">richtig</div>'+(okChips||'—')+warn+'</td>'
+ '<td><div class="colhead">Distraktoren (Pool)</div>'+(distChips||'—')+'</td></tr>';
});
+2 -4
View File
@@ -780,7 +780,7 @@
"pfeffer",
"muskat",
"knoblauch",
"mozzarella"
"greyerzer"
],
"pantry": [],
"recipe": {
@@ -817,9 +817,7 @@
"diff_note": "Käse-Verhältnis + Achter-Rührtechnik (nie Kreis) — Detail entscheidet",
"id": "schweizer-kaesefondue",
"heimat": "schweiz",
"signature": {
"mozzarella": "Schweizer Bergkäse"
}
"signature": {}
},
"zuercher-geschnetzeltes": {
"name": "Zürcher Geschnetzeltes mit Rösti",
@@ -2856,6 +2856,35 @@
],
"fact": "Irische Butter ist oft gelber als deutsche — weil die Kühe das ganze Jahr auf der Weide stehen und mehr Beta-Carotin aufnehmen."
},
"greyerzer": {
"nm": "Greyerzer & Vacherin",
"art": "der",
"ic": "🧀",
"producers": {
"schweiz": {
"t": 32000,
"market": "eu",
"note": "Gruyère AOP + Vacherin Fribourgeois AOP"
},
"frankreich": {
"t": 6000,
"market": "eu",
"note": "Gruyère français IGP"
}
},
"correct": [
"schweiz",
"frankreich"
],
"distractors": [
"deutschland",
"oesterreich",
"italien",
"niederlande",
"daenemark"
],
"fact": "Echtes Käsefondue ist Moitié-Moitié’ — halb Greyerzer (Gruyère AOP), halb Vacherin Fribourgeois AOP. Beide sind Schweizer Bergkäse mit geschützter Herkunft; Gruyère wird auch im französischen Jura hergestellt (IGP)."
},
"feta": {
"nm": "Feta (Käse)",
"art": "der",
@@ -3040,6 +3069,17 @@
"fact": "Aus 5 L Milch wird etwa 1 kg Topfen. Wichtige Eiweißquelle für Sportler:innen."
},
"schmand": {
"correct": [
"oesterreich",
"deutschland"
],
"distractors": [
"polen",
"tschechien",
"niederlande",
"frankreich",
"daenemark"
],
"nm": "Schmand / Saure Sahne",
"art": "der",
"ic": "🥛",
@@ -3171,6 +3211,17 @@
"fact": "Bei einem traditionellen Wiener Schnitzel kommt das Kalbfleisch fast immer aus dem nahen Umfeld (AT, DE, NL)."
},
"lamm": {
"correct": [
"neuseeland",
"uk"
],
"distractors": [
"griechenland",
"tuerkei",
"frankreich",
"spanien",
"deutschland"
],
"nm": "Lammfleisch",
"art": "das",
"ic": "🐑",
@@ -3583,6 +3634,17 @@
]
},
"fischsauce": {
"correct": [
"thailand",
"vietnam"
],
"distractors": [
"philippinen",
"italien",
"china",
"japan",
"indien"
],
"nm": "Fischsauce",
"art": "die",
"ic": "🐟",
@@ -3730,6 +3792,17 @@
"fact": "Echter Wasabi ist extrem selten und teuer — in den meisten Sushi-Restaurants wird Meerrettich mit grüner Farbe als Ersatz verwendet."
},
"tomaten": {
"correct": [
"niederlande",
"spanien"
],
"distractors": [
"griechenland",
"italien",
"tuerkei",
"marokko",
"aegypten"
],
"nm": "Tomaten",
"art": "die",
"ic": "🍅",
@@ -4371,6 +4444,17 @@
"fact": "Champignons brauchen kein Tageslicht — sie wachsen in dunklen Hallen auf Stroh-Mist-Kompost."
},
"hefe": {
"correct": [
"oesterreich",
"frankreich"
],
"distractors": [
"italien",
"spanien",
"griechenland",
"polen",
"tuerkei"
],
"nm": "Hefe",
"art": "die",
"ic": "🫧",
+23 -2
View File
@@ -538,7 +538,8 @@ async function loadWeltkuecheData() {
more: v.more || '',
heimisch: v.heimisch || null, // Teil B: Länder mit Eigenanteil ≥ ⅓ (Consumer-Anker)
market: v.market || null, // Teil B: kuratierte Markt-Zweitlieferanten
distractors: v.distractors || null // Teil B: explizite Distraktor-Länder
distractors: v.distractors || null, // explizite Distraktor-Länder
correct: v.correct || null // fest verdrahtete Herkunft (feste Länderliste)
};
});
DISHES = Object.entries(dishesJ)
@@ -979,6 +980,7 @@ function worldIngCount(dish){
* wird im Game als "lokal verfügbar" angezeigt, aber nicht erforscht. */
function isWorldIngredient(key) {
const ing = ING[key]; if (!ing) return false;
if (ing.correct && ing.correct.length) return true; // fest verdrahtete Herkunft: wird abgefragt
if (ing.heimisch && ing.heimisch.length) return true; // Consumer-Grundzutat (Teil B): wird immer abgefragt
const real = Object.values(ing.producers || {}).filter(p => p.t && p.t > 0);
return real.length >= 3;
@@ -1068,6 +1070,22 @@ function buildTaskFor(ingKey) {
if (_taskCache[ingKey]) return _taskCache[ingKey];
const ing = ING[ingKey];
if (!ing) return null;
// ── FEST VERDRAHTETE HERKUNFT: Zutat hat eine feste Länderliste (`correct`)
// + feste Distraktoren (`distractors`). Gilt immer — kein Automatismus,
// einfach genau die vorgegebene Liste. Hat Vorrang vor allem anderen.
if (ing.correct && ing.correct.length) {
const correct = ing.correct.filter(c => C[c]);
let pool = (ing.distractors || []).filter(c => C[c] && !correct.includes(c));
if (pool.length < 5 - correct.length) {
pool = pool.concat(impossibleCountries(correct, [...pool, ...Object.keys(ing.producers || {})]));
}
shuffleInPlace(pool);
const distr = pool.slice(0, Math.max(0, 5 - correct.length));
const choices = [...correct, ...distr];
shuffleInPlace(choices);
_taskCache[ingKey] = { correct, choices, possible: new Set(), fixed: true };
return _taskCache[ingKey];
}
// ── CONSUMER-REGEL (Teil B): Eine Grundzutat, die im Land des USERS heimisch
// ist (Eigenanteil ≥ ~⅓), kauft man dort, wo man einkauft — im eigenen Land,
// UNABHÄNGIG davon, aus welchem Land das Gericht stammt. (Das Ei in der
@@ -1588,7 +1606,10 @@ function showSolved(ing,pts,bonus){
const factLine = ing.fact ? `<div class="more-line"><b>Wusstest du?</b> ${esc(ing.fact)}</div>` : '';
// Heimat-Regel: erklären, warum die Region die Antwort ist (nicht der größte Produzent)
const _userN = task.user && C[task.user] ? (C[task.user].f + ' ' + C[task.user].n) : 'bei uns';
const sigLine = task.consumer
const _fixN = task.fixed ? task.correct.map(k => C[k] ? (C[k].f + ' ' + C[k].n) : k).join(' & ') : '';
const sigLine = task.fixed
? `<div class="more-line" style="background:#eef5ec;border-left:3px solid #4a7c4e">🌍 <b>${esc(ing.nm)}</b> kommt bei uns typisch aus <b>${_fixN}</b>.</div>`
: task.consumer
? `<div class="more-line" style="background:#eef5ec;border-left:3px solid #4a7c4e">🛒 Eine <b>Grundzutat</b> — die kaufst du <b>dort, wo du einkaufst</b>: im eigenen Land (${_userN}). Reicht die heimische Menge nicht, kommt ein naher Nachbar dazu. Nur was bei uns gar nicht wächst, reist von weit her — und was ein Gericht <b>besonders</b> macht, holt man aus der Herkunftsregion.</div>`
: (task.signature && C[task.heimat])
? (task.label