Merz leck Eier: MTG troll site
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
125
app/Game.tsx
Normal file
125
app/Game.tsx
Normal file
@@ -0,0 +1,125 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { CardView } from "./CardView";
|
||||
import { COMMANDER, DECK, type Card } from "./cards";
|
||||
|
||||
const shuffle = <T,>(a: T[]) => [...a].sort(() => Math.random() - 0.5);
|
||||
|
||||
const LOG_LINES = [
|
||||
"Die Umfragewerte sinken. Merz macht eine Pressekonferenz über Bierdeckel.",
|
||||
"Merz tappt Sauerland. Niemand ist überrascht.",
|
||||
"Das Volk wirkt „Leck Eier“. Es ist sehr effektiv.",
|
||||
"Merz versucht zu mulliganen, aber die Koalition sagt nein.",
|
||||
"BlackRock ruft an. Merz geht natürlich ran.",
|
||||
"Merz zieht eine Karte. Es ist wieder ein Wahlversprechen. Er wirft es ab.",
|
||||
];
|
||||
|
||||
export function Game() {
|
||||
const [library, setLibrary] = useState<Card[]>([]);
|
||||
const [hand, setHand] = useState<Card[]>([]);
|
||||
const [grave, setGrave] = useState<Card[]>([]);
|
||||
const [polls, setPolls] = useState(25);
|
||||
const [eggs, setEggs] = useState(0);
|
||||
const [log, setLog] = useState<string[]>(["Merz, Leck Eier betritt das Schlachtfeld. Aus einem Privatjet."]);
|
||||
|
||||
useEffect(() => {
|
||||
setLibrary(shuffle(DECK));
|
||||
try {
|
||||
setEggs(Number(localStorage.getItem("eggs") ?? 0));
|
||||
} catch {}
|
||||
}, []);
|
||||
|
||||
const say = (line: string) => setLog((l) => [line, ...l].slice(0, 6));
|
||||
|
||||
function draw() {
|
||||
if (library.length === 0) {
|
||||
say("Deine Bibliothek ist leer. Wie das Rentenkonzept.");
|
||||
return;
|
||||
}
|
||||
const [top, ...rest] = library;
|
||||
setLibrary(rest);
|
||||
setHand((h) => [...h, top]);
|
||||
say(`Du ziehst „${top.name}“.`);
|
||||
}
|
||||
|
||||
function cast(i: number) {
|
||||
const card = hand[i];
|
||||
setHand((h) => h.filter((_, j) => j !== i));
|
||||
setGrave((g) => [card, ...g]);
|
||||
const dmg = card.name === "Leck Eier" ? 10 : Math.ceil(Math.random() * 4);
|
||||
setPolls((p) => Math.max(0, p - dmg));
|
||||
say(`Du wirkst „${card.name}“. Merz verliert ${dmg}% Zustimmung.`);
|
||||
}
|
||||
|
||||
function mulligan() {
|
||||
setLibrary(shuffle(DECK));
|
||||
setHand([]);
|
||||
setGrave([]);
|
||||
setPolls(25);
|
||||
say("Mulligan! Neue Hand, gleicher Kanzler.");
|
||||
}
|
||||
|
||||
function lick() {
|
||||
const n = eggs + 1;
|
||||
setEggs(n);
|
||||
try {
|
||||
localStorage.setItem("eggs", String(n));
|
||||
} catch {}
|
||||
say(LOG_LINES[Math.floor(Math.random() * LOG_LINES.length)]);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="board">
|
||||
<div className="commander">
|
||||
<div className="label">Commander</div>
|
||||
<CardView card={COMMANDER} big />
|
||||
<div className="life">
|
||||
<span>Umfragewerte</span>
|
||||
<strong className={polls === 0 ? "dead" : ""}>{polls}%</strong>
|
||||
<div className="meter">
|
||||
<div style={{ width: `${(polls / 25) * 100}%` }} />
|
||||
</div>
|
||||
{polls === 0 && <p className="win">🏆 Du hast gewonnen. Neuwahlen!</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="side">
|
||||
<div className="buttons">
|
||||
<button onClick={draw}>🃏 Karte ziehen ({library.length})</button>
|
||||
<button onClick={mulligan} className="ghost">
|
||||
🔄 Mulligan
|
||||
</button>
|
||||
<button onClick={lick} className="egg">
|
||||
🥚 Leck Eier ({eggs})
|
||||
</button>
|
||||
</div>
|
||||
<ol className="log">
|
||||
{log.map((l, i) => (
|
||||
<li key={i + l}>{l}</li>
|
||||
))}
|
||||
</ol>
|
||||
<div className="grave">
|
||||
⚰️ Friedhof: {grave.length ? grave.map((c) => c.name).join(", ") : "leer (wie die Staatskasse)"}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Deine Hand {hand.length > 0 && <small>— klick eine Karte zum Wirken</small>}</h2>
|
||||
{hand.length === 0 ? (
|
||||
<p className="empty">Noch keine Karten. Zieh eine, bevor Merz es privatisiert.</p>
|
||||
) : (
|
||||
<div className="hand">
|
||||
{hand.map((c, i) => (
|
||||
<button key={i + c.name} className="card-btn" onClick={() => cast(i)}>
|
||||
<CardView card={c} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user