{"id":4378,"date":"2024-11-15T12:02:38","date_gmt":"2024-11-15T11:02:38","guid":{"rendered":"https:\/\/fahrtauglich.ch\/?page_id=4378"},"modified":"2026-10-12T12:43:32","modified_gmt":"2026-10-12T10:43:32","slug":"bimaru","status":"publish","type":"page","link":"https:\/\/fahrtauglich.ch\/fr\/praxisportal\/bimaru\/","title":{"rendered":"Bimaru online"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"4378\" class=\"elementor elementor-4378\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-279daf0 e-flex e-con-boxed e-con e-parent\" data-id=\"279daf0\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1f2f64f elementor-widget elementor-widget-html\" data-id=\"1f2f64f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!--\r\n    Bimaru \u2014 fahrtauglich.ch\/praxisportal\/bimaru\/\r\n    Einbau: Inhalt dieser Datei vollstaendig in EIN Elementor-HTML-Widget einfuegen.\r\n    Das Snippet deckt die ganze Seite zwischen Header und Footer ab (Titel,\r\n    Einleitung mit Link auf trainmybrain.ch, Spiel, Spielanleitung, Texte, Quelle).\r\n    Alle uebrigen Elementor-Widgets der Seite werden geloescht. Kein\r\n    <html>\/<head>\/<body>: Header und Footer liefert das Theme.\r\n\r\n    Spiellogik unveraendert aus trainmybrain-bimaru.html (Generator mit\r\n    Eindeutigkeitsgarantie, Loeser, automatische Schiffsformen, Flottenkontrolle).\r\n    Geprueft 2026-10-12: 450 Raetsel, alle mit einem unabhaengigen Loeser\r\n    (ganze Schiffe platzieren) eindeutig; Median 15-20 ms pro Raetsel.\r\n    Ergaenzt: Bedienung per Tastatur (Pfeiltasten, Enter\/Leertaste).\r\n\r\n    Optik: fahrtauglich.ch \u2014 Poppins, Gelb #FFBF00, Flaechen #F3F5F8, Pill-Buttons.\r\n    Alles CSS haengt an #ftbm, damit nichts in die Elementor-Seite durchschlaegt.\r\n-->\r\n<style>\r\n    #ftbm {\r\n        --ftbm-gelb: #FFBF00;\r\n        --ftbm-gelb-dunkel: #E6AB00;\r\n        --ftbm-gelb-hell: #FFF4CC;\r\n        --ftbm-schwarz: #000000;\r\n        --ftbm-text: #1F2937;\r\n        --ftbm-text-2: #4B5563;\r\n        --ftbm-flaeche: #F3F5F8;\r\n        --ftbm-linie: #C8D5DC;\r\n        --ftbm-gruen: #047857;\r\n        --ftbm-schiff: #374151;\r\n\r\n        font-family: 'Poppins', sans-serif;\r\n        color: var(--ftbm-text);\r\n        line-height: 1.5;\r\n        width: 100%;\r\n        max-width: 850px;\r\n        margin: 20px auto 60px;\r\n        box-sizing: border-box;\r\n    }\r\n    #ftbm *, #ftbm *::before, #ftbm *::after { box-sizing: border-box; }\r\n    #ftbm [hidden] { display: none !important; }\r\n\r\n    \/* ===== Seitenkopf \u2014 Masse wie die bisherigen Elementor-Widgets ===== *\/\r\n    #ftbm .ftbm-titel { margin: 0; font-family: inherit; font-size: 48px; font-weight: 600; line-height: 1.2; letter-spacing: 0; text-align: center; color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-intro { max-width: 760px; margin: 50px auto 0; font-size: 20px; font-weight: 300; line-height: 1.5; text-align: center; color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-intro a, #ftbm .ftbm-box a {\r\n        color: var(--ftbm-schwarz); font-weight: 400;\r\n        text-decoration: underline; text-decoration-color: var(--ftbm-gelb); text-decoration-thickness: 3px; text-underline-offset: 3px;\r\n        overflow-wrap: anywhere;\r\n    }\r\n    #ftbm .ftbm-intro a:hover, #ftbm .ftbm-box a:hover, #ftbm .ftbm-intro a:focus, #ftbm .ftbm-box a:focus { color: var(--ftbm-schwarz); background: rgba(255, 191, 0, 0.18); }\r\n    #ftbm a:focus-visible { outline: 3px solid var(--ftbm-schwarz); outline-offset: 2px; }\r\n\r\n    \/* ===== Spielbereich ===== *\/\r\n    #ftbm .ftbm-spiel { max-width: 680px; margin: 34px auto 0; text-align: center; }\r\n    #ftbm .ftbm-karte {\r\n        position: relative;\r\n        overflow: hidden;\r\n        overflow: clip;   \/* clip: Fokus auf ein Feld darf den Karteninhalt nicht verschieben *\/\r\n        background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\r\n        border: 2px solid #dee2e6;\r\n        border-radius: 20px;\r\n        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);\r\n        padding: 30px;\r\n    }\r\n    #ftbm .ftbm-karte::before {\r\n        content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;\r\n        background: radial-gradient(circle, rgba(52, 58, 64, 0.05) 1px, transparent 1px);\r\n        background-size: 30px 30px; animation: ftbm-hintergrund 25s linear infinite; z-index: 0; pointer-events: none;\r\n    }\r\n    @keyframes ftbm-hintergrund { 0% { transform: translate(0, 0) rotate(0deg); } 100% { transform: translate(-30px, -30px) rotate(360deg); } }\r\n    #ftbm .ftbm-inhalt { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 18px; }\r\n\r\n    \/* Schwierigkeit (Segment wie Buchstabensalat) *\/\r\n    #ftbm .ftbm-feld-label { display: block; margin-bottom: 6px; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 1px; color: var(--ftbm-text-2); }\r\n    #ftbm .ftbm-stufen { display: inline-flex; padding: 3px; background: #ffffff; border: 2px solid var(--ftbm-schwarz); border-radius: 100px; }\r\n    #ftbm .ftbm-stufe {\r\n        -webkit-appearance: none; appearance: none; margin: 0;\r\n        min-height: 40px; padding: 6px 18px; background: transparent; border: none; border-radius: 100px;\r\n        font-family: inherit; font-size: 0.95rem; font-weight: 500; color: var(--ftbm-schwarz); cursor: pointer;\r\n    }\r\n    #ftbm .ftbm-stufe:hover, #ftbm .ftbm-stufe:focus { background: var(--ftbm-flaeche); color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-stufe[aria-pressed=\"true\"] { background: var(--ftbm-gelb); color: var(--ftbm-schwarz); }\r\n\r\n    \/* Raster 11 x 11: erste Zeile\/Spalte = Zahlen *\/\r\n    #ftbm .ftbm-brett { width: 100%; display: flex; justify-content: center; }\r\n    #ftbm .ftbm-raster {\r\n        display: grid;\r\n        grid-template-columns: repeat(11, 1fr);\r\n        grid-template-rows: repeat(11, 1fr);\r\n        width: 100%;\r\n        max-width: 484px;\r\n        aspect-ratio: 1;\r\n        padding: 6px;\r\n        gap: 2px;\r\n        background: rgba(255, 255, 255, 0.85);\r\n        border: 1px solid rgba(0, 0, 0, 0.05);\r\n        border-radius: 15px;\r\n        box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);\r\n    }\r\n    #ftbm .empty-cell, #ftbm .hint-cell, #ftbm .batalla-cell {\r\n        min-width: 0; min-height: 0; position: relative;\r\n        display: flex; align-items: center; justify-content: center;\r\n        font-size: clamp(0.72rem, 2.6vw, 1rem);\r\n    }\r\n    #ftbm .hint-cell {\r\n        background: var(--ftbm-flaeche); border-radius: 6px;\r\n        font-weight: 600; color: var(--ftbm-schwarz);\r\n        transition: background 0.15s ease, color 0.15s ease;\r\n    }\r\n    \/* Live-Rueckmeldung: Zahl erreicht (gruen) bzw. ueberschritten (rot) *\/\r\n    #ftbm .hint-cell.erfuellt { background: #D1FAE5; color: var(--ftbm-gruen); }\r\n    #ftbm .hint-cell.zuviel   { background: #FEE2E2; color: #B91C1C; }\r\n    #ftbm .batalla-cell {\r\n        -webkit-appearance: none; appearance: none; margin: 0; padding: 0;\r\n        width: 100%; height: 100%;\r\n        background: #ffffff; border: 1px solid var(--ftbm-linie); border-radius: 6px;\r\n        font-family: inherit; color: var(--ftbm-text); cursor: pointer;\r\n        touch-action: manipulation; -webkit-tap-highlight-color: transparent;\r\n        transition: background 0.12s ease;\r\n    }\r\n    #ftbm .batalla-cell:hover { background: var(--ftbm-flaeche); }\r\n    #ftbm .batalla-cell:focus-visible { outline: 3px solid var(--ftbm-schwarz); outline-offset: 1px; z-index: 1; }\r\n    \/* Vorgaben: fest, gelb hinterlegt *\/\r\n    #ftbm .batalla-cell.highlighted, #ftbm .batalla-cell.highlighted:hover { background: var(--ftbm-gelb-hell); border-color: var(--ftbm-gelb-dunkel); cursor: default; }\r\n    #ftbm .batalla-cell.water { color: #2563EB; }\r\n    \/* Schiffsteile \u2014 Groesse relativ zur Zelle *\/\r\n    #ftbm .ship-part { width: 72%; height: 72%; background: var(--ftbm-schiff); border-radius: 4px; }\r\n    #ftbm .ship-part.ship-start  { border-radius: 50% 0 0 50%; width: 84%; }\r\n    #ftbm .ship-part.ship-end    { border-radius: 0 50% 50% 0; width: 84%; }\r\n    #ftbm .ship-part.ship-top    { border-radius: 50% 50% 0 0; height: 84%; }\r\n    #ftbm .ship-part.ship-bottom { border-radius: 0 0 50% 50%; height: 84%; }\r\n    #ftbm .ship-part.ship-middle { border-radius: 3px; width: 84%; height: 84%; }\r\n    #ftbm .ship-part.ship-single { border-radius: 50%; width: 62%; height: 62%; }\r\n    \/* Noch unbestimmtes Teil: Form folgt, sobald die Enden feststehen *\/\r\n    #ftbm .ship-part.ship-generic { background: #6B7280; outline: 2px dashed rgba(255, 255, 255, 0.6); outline-offset: -4px; }\r\n\r\n    \/* Flotte *\/\r\n    #ftbm .ftbm-flotte-box { background: rgba(255, 255, 255, 0.85); border: 1px solid rgba(0, 0, 0, 0.05); border-radius: 12px; padding: 12px 16px; }\r\n    #ftbm .ftbm-flotte { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px; }\r\n    #ftbm .ship { display: flex; align-items: center; gap: 2px; transition: opacity 0.2s ease; }\r\n    #ftbm .ship.gefunden { opacity: 0.4; }\r\n    #ftbm .ship.gefunden .part { background: var(--ftbm-gruen); }\r\n    #ftbm .part { width: 22px; height: 22px; background: var(--ftbm-schiff); border-radius: 4px; }\r\n    #ftbm .part.ship-start  { border-radius: 50% 0 0 50%; }\r\n    #ftbm .part.ship-end    { border-radius: 0 50% 50% 0; }\r\n    #ftbm .part.ship-single { border-radius: 50%; width: 18px; height: 18px; }\r\n\r\n    #ftbm .ftbm-meldung { min-height: 1.5em; margin: 0; font-size: 1rem; font-weight: 500; color: var(--ftbm-text); }\r\n    #ftbm .ftbm-meldung.erfolg { color: var(--ftbm-gruen); }\r\n\r\n    \/* ===== Buttons (Pill-Stil der fahrtauglich.ch-Buttons) ===== *\/\r\n    #ftbm .ftbm-kontrollen { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; }\r\n    #ftbm .ftbm-knopf {\r\n        -webkit-appearance: none; appearance: none; margin: 0;\r\n        display: inline-flex; align-items: center; justify-content: center;\r\n        min-height: 48px; padding: 10px 26px;\r\n        background: var(--ftbm-gelb); border: 2px solid var(--ftbm-gelb); border-radius: 100px; box-shadow: none;\r\n        font-family: inherit; font-size: 1rem; font-weight: 500; line-height: 1.2; text-transform: none; text-decoration: none;\r\n        color: var(--ftbm-schwarz); cursor: pointer;\r\n        transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;\r\n    }\r\n    #ftbm .ftbm-knopf:hover, #ftbm .ftbm-knopf:focus { background: var(--ftbm-gelb-dunkel); border-color: var(--ftbm-gelb-dunkel); color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-knopf:hover { transform: translateY(-1px); }\r\n    #ftbm .ftbm-knopf-hell { background: #ffffff; border-color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-knopf-hell:hover, #ftbm .ftbm-knopf-hell:focus { background: var(--ftbm-flaeche); border-color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-knopf:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }\r\n    #ftbm .ftbm-knopf:focus-visible, #ftbm .ftbm-stufe:focus-visible,\r\n    #ftbm .ftbm-modal-schliessen:focus-visible, #ftbm summary:focus-visible { outline: 3px solid var(--ftbm-schwarz); outline-offset: 2px; }\r\n\r\n    \/* ===== Spielanleitung ===== *\/\r\n    #ftbm .ftbm-anleitung { margin-top: 24px; text-align: left; background: #ffffff; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.25); padding: 15px 18px; }\r\n    #ftbm .ftbm-anleitung summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 4px 0; font-size: 1.15rem; font-weight: 600; color: var(--ftbm-schwarz); user-select: none; }\r\n    #ftbm .ftbm-anleitung summary::-webkit-details-marker { display: none; }\r\n    #ftbm .ftbm-chev { width: 20px; height: 20px; flex: 0 0 auto; transition: transform 0.2s ease; }\r\n    #ftbm .ftbm-anleitung[open] .ftbm-chev { transform: rotate(180deg); }\r\n    #ftbm .ftbm-anleitung-liste { list-style: none; margin: 12px 0 4px; padding: 0; display: grid; gap: 8px; }\r\n    #ftbm .ftbm-anleitung-liste li { margin: 0; padding: 10px 14px; background: var(--ftbm-flaeche); border-left: 3px solid var(--ftbm-gelb); border-radius: 6px; font-size: 0.95rem; font-weight: 300; line-height: 1.55; color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-anleitung-liste li strong { font-weight: 600; }\r\n\r\n    \/* ===== Textabschnitte (Kartenstil der bisherigen Textboxen) ===== *\/\r\n    #ftbm .ftbm-abschnitt { margin-top: 70px; }\r\n    #ftbm .ftbm-abschnitt h2 { margin: 0 0 20px; font-family: inherit; font-size: 36px; font-weight: 600; line-height: 1.2; letter-spacing: 0; text-transform: none; text-align: center; color: var(--ftbm-schwarz); }\r\n    #ftbm .ftbm-box { background: #ffffff; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); padding: 15px 20px; font-size: 22px; font-weight: 300; line-height: 1.5; color: var(--ftbm-schwarz); text-align: left; }\r\n    #ftbm .ftbm-box p { margin: 0 0 14px; }\r\n    #ftbm .ftbm-box p:last-child { margin-bottom: 0; }\r\n    #ftbm .ftbm-box strong { font-weight: 500; }\r\n    #ftbm .ftbm-tipps { margin: 0; padding-left: 1.2em; }\r\n    #ftbm .ftbm-tipps li { margin: 0 0 14px; padding-left: 0.2em; }\r\n    #ftbm .ftbm-tipps li:last-child { margin-bottom: 0; }\r\n    #ftbm .ftbm-tipps li::marker { color: var(--ftbm-gelb-dunkel); }\r\n    #ftbm .ftbm-tipps strong { display: block; }\r\n    #ftbm .ftbm-nutzen { list-style: none; margin: 6px 0 0; padding: 0; }\r\n    #ftbm .ftbm-nutzen li { display: grid; grid-template-columns: 2.4em 1fr; gap: 0 0.6em; padding: 14px 0; border-top: 1px solid var(--ftbm-linie); }\r\n    #ftbm .ftbm-nutzen li:last-child { border-bottom: 1px solid var(--ftbm-linie); }\r\n    #ftbm .ftbm-nutzen-nr { font-weight: 600; line-height: 1.5; color: var(--ftbm-gelb-dunkel); }\r\n    #ftbm .ftbm-nutzen strong { display: block; }\r\n    #ftbm .ftbm-quellen-titel { margin-top: 20px !important; font-weight: 500; }\r\n    #ftbm .ftbm-quellen { list-style: none; margin: 0; padding: 0; font-size: 0.8em; }\r\n\r\n    \/* ===== Dialog ===== *\/\r\n    #ftbm .ftbm-modal { position: fixed; inset: 0; z-index: 100000; display: none; align-items: center; justify-content: center; padding: 20px; }\r\n    #ftbm .ftbm-modal.active { display: flex; }\r\n    #ftbm .ftbm-modal-hintergrund { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(5px); }\r\n    #ftbm .ftbm-modal-inhalt { position: relative; width: 100%; max-width: 420px; max-height: 85vh; overflow-y: auto; background: #ffffff; border-radius: 15px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); padding: 32px 28px 28px; text-align: center; animation: ftbm-modal-ein 0.25s ease; }\r\n    @keyframes ftbm-modal-ein { from { opacity: 0; transform: scale(0.96) translateY(12px); } to { opacity: 1; transform: none; } }\r\n    #ftbm .ftbm-modal-schliessen { -webkit-appearance: none; appearance: none; position: absolute; top: 8px; right: 8px; width: 44px; height: 44px; margin: 0; padding: 0; display: flex; align-items: center; justify-content: center; background: none; border: none; border-radius: 50%; font-family: inherit; font-size: 28px; line-height: 1; color: #6B7280; cursor: pointer; }\r\n    #ftbm .ftbm-modal-schliessen:hover, #ftbm .ftbm-modal-schliessen:focus { background: var(--ftbm-flaeche); color: #374151; }\r\n    #ftbm .ftbm-modal h2 { margin: 0 0 8px; font-family: inherit; font-size: 1.75rem; font-weight: 600; line-height: 1.2; color: var(--ftbm-text); }\r\n    #ftbm .ftbm-modal p { margin: 0 0 6px; color: var(--ftbm-text-2); }\r\n    #ftbm .ftbm-ergebnis { margin: 16px 0 18px; }\r\n    #ftbm .ftbm-ergebnis strong { display: block; font-size: 2rem; font-weight: 700; line-height: 1.1; color: var(--ftbm-schwarz); font-variant-numeric: tabular-nums; }\r\n    #ftbm .ftbm-ergebnis span { font-size: 0.85rem; color: var(--ftbm-text-2); }\r\n\r\n    #ftbm .ftbm-sr { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }\r\n\r\n    \/* ===== Responsive (Elementor: Tablet <= 1024px, Handy <= 767px) ===== *\/\r\n    @media (max-width: 1024px) {\r\n        #ftbm .ftbm-titel { font-size: 45px; }\r\n        #ftbm .ftbm-intro { font-size: 16px; margin-top: 30px; }\r\n        #ftbm .ftbm-box   { font-size: 16px; }\r\n    }\r\n    @media (max-width: 768px) {\r\n        #ftbm { max-width: 95%; }\r\n        #ftbm .ftbm-karte { padding: 20px; }\r\n    }\r\n    @media (max-width: 767px) {\r\n        #ftbm .ftbm-titel { font-size: 28px; }\r\n        #ftbm .ftbm-intro { margin-top: 20px; }\r\n        #ftbm .ftbm-spiel { margin-top: 24px; }\r\n        #ftbm .ftbm-abschnitt { margin-top: 50px; }\r\n        #ftbm .ftbm-abschnitt h2 { font-size: 28px; }\r\n        #ftbm .ftbm-box { padding: 15px; }\r\n    }\r\n    @media (max-width: 520px) {\r\n        #ftbm .ftbm-karte  { padding: 14px 6px; border-radius: 16px; }\r\n        #ftbm .ftbm-inhalt { gap: 14px; }\r\n        #ftbm .ftbm-raster { padding: 4px; gap: 1px; }\r\n        #ftbm .hint-cell, #ftbm .batalla-cell { border-radius: 3px; }\r\n        #ftbm .ftbm-stufen { width: 100%; }\r\n        #ftbm .ftbm-stufe  { flex: 1; padding: 6px 8px; }\r\n        #ftbm .ftbm-kontrollen { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; }\r\n        #ftbm .ftbm-kontrollen .ftbm-knopf:first-child { grid-column: 1 \/ -1; }\r\n        #ftbm .ftbm-knopf { padding: 10px 12px; font-size: 0.95rem; }\r\n        #ftbm .part { width: 16px; height: 16px; }\r\n        #ftbm .part.ship-single { width: 13px; height: 13px; }\r\n        #ftbm .ftbm-flotte { gap: 8px; }\r\n    }\r\n    @media (prefers-reduced-motion: reduce) {\r\n        #ftbm *, #ftbm *::before, #ftbm *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }\r\n    }\r\n<\/style>\r\n\r\n<div id=\"ftbm\">\r\n\r\n    <div class=\"ftbm-sr\" aria-live=\"polite\" aria-atomic=\"true\" id=\"ftbm-sr\"><\/div>\r\n\r\n    <h1 class=\"ftbm-titel\">Bimaru<\/h1>\r\n\r\n    <p class=\"ftbm-intro\">Platzieren Sie die Flotte im 10 \u00d7 10-Raster, nur mit Logik, ohne Raten. Weitere Spiele f\u00fcr Ged\u00e4chtnis, Konzentration und Logik finden Sie auf <a href=\"https:\/\/trainmybrain.ch\/\">trainmybrain.ch<\/a>, unserer Plattform f\u00fcr kognitive Spiele.<\/p>\r\n\r\n    <div class=\"ftbm-spiel\">\r\n\r\n        <section class=\"ftbm-karte\" aria-label=\"Bimaru Spielbereich\">\r\n            <div class=\"ftbm-inhalt\">\r\n\r\n                <div>\r\n                    <span class=\"ftbm-feld-label\" id=\"ftbm-stufe-label\">Schwierigkeit<\/span>\r\n                    <div class=\"ftbm-stufen\" role=\"group\" aria-labelledby=\"ftbm-stufe-label\">\r\n                        <button type=\"button\" class=\"ftbm-stufe\" data-stufe=\"leicht\" aria-pressed=\"false\">Leicht<\/button>\r\n                        <button type=\"button\" class=\"ftbm-stufe\" data-stufe=\"mittel\" aria-pressed=\"true\">Mittel<\/button>\r\n                        <button type=\"button\" class=\"ftbm-stufe\" data-stufe=\"schwer\" aria-pressed=\"false\">Schwer<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"ftbm-brett\">\r\n                    <div class=\"ftbm-raster\" id=\"ftbm-raster\" role=\"grid\" aria-label=\"Bimaru Spielraster\"><\/div>\r\n                <\/div>\r\n\r\n                <div class=\"ftbm-flotte-box\">\r\n                    <span class=\"ftbm-feld-label\">Flotte<\/span>\r\n                    <div class=\"ftbm-flotte\" id=\"ftbm-flotte\" aria-label=\"Flotte: 1 Schlachtschiff, 2 Kreuzer, 3 Zerst\u00f6rer, 4 U-Boote\"><\/div>\r\n                <\/div>\r\n\r\n                <p class=\"ftbm-meldung\" id=\"ftbm-meldung\" aria-live=\"polite\"><\/p>\r\n\r\n                <div class=\"ftbm-kontrollen\">\r\n                    <button type=\"button\" id=\"ftbm-neu\" class=\"ftbm-knopf\">Neues Bimaru<\/button>\r\n                    <button type=\"button\" id=\"ftbm-neustart\" class=\"ftbm-knopf ftbm-knopf-hell\">Neustart<\/button>\r\n                    <button type=\"button\" id=\"ftbm-loesung\" class=\"ftbm-knopf ftbm-knopf-hell\">L\u00f6sung zeigen<\/button>\r\n                <\/div>\r\n\r\n            <\/div>\r\n        <\/section>\r\n\r\n        <details class=\"ftbm-anleitung\" id=\"ftbm-anleitung\">\r\n            <summary>\r\n                Spielanleitung\r\n                <svg class=\"ftbm-chev\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg>\r\n            <\/summary>\r\n            <ul class=\"ftbm-anleitung-liste\">\r\n                <li><strong>Ziel:<\/strong> Platzieren Sie die ganze Flotte im Raster: 1 Schlachtschiff (4 Felder), 2 Kreuzer (3), 3 Zerst\u00f6rer (2) und 4 U-Boote (1). Jedes R\u00e4tsel hat genau eine L\u00f6sung und ist ohne Raten l\u00f6sbar.<\/li>\r\n                <li><strong>Zahlen:<\/strong> Die Zahlen links und oben sagen, wie viele Schiffsteile in der Zeile bzw. Spalte liegen. Sie werden gr\u00fcn, sobald die Zahl erreicht ist, und rot, wenn zu viele Teile gesetzt sind.<\/li>\r\n                <li><strong>Regeln:<\/strong> Schiffe liegen waagerecht oder senkrecht und ber\u00fchren sich nie, auch nicht \u00fcber Eck.<\/li>\r\n                <li><strong>Vorgaben:<\/strong> Gelb hinterlegte Felder sind vorgegeben: Wasser (\ud83c\udf0a) oder ein Schiffsteil mit seiner Form, also U-Boot (Kreis), Schiffsende (abgerundet) oder Mittelst\u00fcck (eckig).<\/li>\r\n                <li><strong>Felder setzen:<\/strong> Jeder Klick wechselt: leer \u2192 Wasser \u2192 Schiffsteil \u2192 leer. Die Form ergibt sich automatisch. Gestrichelt bleibt ein Teil, solange das Schiff noch weitergehen k\u00f6nnte.<\/li>\r\n                <li><strong>Flotte:<\/strong> Ein Schiff wird abgehakt, sobald es abgeschlossen ist. Nicht jedes Wasserfeld muss markiert werden: Felder in einer erf\u00fcllten Zeile oder Spalte gelten als Wasser.<\/li>\r\n                <li><strong>Schwierigkeit:<\/strong> Bestimmt, wie viele Felder zus\u00e4tzlich vorgegeben sind. \u00abSchwer\u00bb zeigt nur, was f\u00fcr eine eindeutige L\u00f6sung n\u00f6tig ist.<\/li>\r\n                <li><strong>Mit der Tastatur:<\/strong> Mit Tab ins Raster, mit den Pfeiltasten von Feld zu Feld. Enter oder Leertaste wechselt den Zustand.<\/li>\r\n            <\/ul>\r\n        <\/details>\r\n\r\n    <\/div><!-- \/.ftbm-spiel -->\r\n\r\n    <!-- ===== Wie funktioniert Bimaru? ===== -->\r\n    <section class=\"ftbm-abschnitt\" aria-labelledby=\"ftbm-h-regeln\">\r\n        <h2 id=\"ftbm-h-regeln\">Wie funktioniert Bimaru?<\/h2>\r\n        <div class=\"ftbm-box\">\r\n            <p>Bimaru ist ein Logikr\u00e4tsel auf einem Raster von 10 \u00d7 10 Feldern. Darin versteckt ist eine Flotte aus zehn Schiffen: ein Schlachtschiff (4 Felder), zwei Kreuzer (je 3), drei Zerst\u00f6rer (je 2) und vier U-Boote (je 1). Zusammen belegen sie 20 der 100 Felder.<\/p>\r\n            <p>Die Zahlen am Rand verraten, wie viele Schiffsteile in jeder Zeile und Spalte liegen. Die Schiffe stehen waagerecht oder senkrecht und ber\u00fchren sich nie, <strong>auch nicht diagonal<\/strong>. Einige Felder sind vorgegeben, als Wasser oder als Schiffsteil mit erkennbarer Form.<\/p>\r\n            <p>Jedes R\u00e4tsel hat genau eine L\u00f6sung, die sich Schritt f\u00fcr Schritt erschliessen l\u00e4sst. Bimaru l\u00e4uft im Browser, kostenlos und ohne Anmeldung. Mit \u00abNeues Bimaru\u00bb erhalten Sie jederzeit ein neues R\u00e4tsel.<\/p>\r\n        <\/div>\r\n    <\/section>\r\n\r\n    <!-- ===== Nutzen ===== -->\r\n    <section class=\"ftbm-abschnitt\" aria-labelledby=\"ftbm-h-nutzen\">\r\n        <h2 id=\"ftbm-h-nutzen\">Was ist der Nutzen von Bimaru?<\/h2>\r\n        <div class=\"ftbm-box\">\r\n            <p>Bimaru ist ein unterhaltsames Logikr\u00e4tsel und fordert dabei mehrere F\u00e4higkeiten:<\/p>\r\n            <ol class=\"ftbm-nutzen\">\r\n                <li><span class=\"ftbm-nutzen-nr\" aria-hidden=\"true\">01<\/span><div><strong>Logisches Schlussfolgern<\/strong>Aus Zahlen und Regeln folgt, wo Wasser sein muss und wo ein Schiff liegt. Jeder Schritt baut auf dem vorherigen auf.<\/div><\/li>\r\n                <li><span class=\"ftbm-nutzen-nr\" aria-hidden=\"true\">02<\/span><div><strong>Planen<\/strong>Wer fr\u00fch \u00fcberlegt, wo das Schlachtschiff \u00fcberhaupt Platz hat, kommt schneller voran als mit Probieren.<\/div><\/li>\r\n                <li><span class=\"ftbm-nutzen-nr\" aria-hidden=\"true\">03<\/span><div><strong>R\u00e4umliches Vorstellen<\/strong>Schiffe, ihre Abstandszonen und die Zeilen- und Spaltensummen m\u00fcssen gleichzeitig im Blick bleiben.<\/div><\/li>\r\n                <li><span class=\"ftbm-nutzen-nr\" aria-hidden=\"true\">04<\/span><div><strong>Konzentration<\/strong>Ein falsch gesetztes Feld zieht Folgefehler nach sich. Sorgf\u00e4ltiges Arbeiten zahlt sich aus.<\/div><\/li>\r\n            <\/ol>\r\n        <\/div>\r\n    <\/section>\r\n\r\n    <!-- ===== Tipps ===== -->\r\n    <section class=\"ftbm-abschnitt\" aria-labelledby=\"ftbm-h-tipps\">\r\n        <h2 id=\"ftbm-h-tipps\">Bimaru-Tipps: Strategien zum L\u00f6sen<\/h2>\r\n        <div class=\"ftbm-box\">\r\n            <ul class=\"ftbm-tipps\">\r\n                <li><strong>Mit den Nullen beginnen<\/strong>Steht am Rand eine 0, ist die ganze Zeile oder Spalte Wasser. Markieren Sie sie zuerst, das schr\u00e4nkt den Rest stark ein.<\/li>\r\n                <li><strong>Volle Zeilen erkennen<\/strong>Entspricht die Zahl genau der Anzahl noch freier Felder, sind alle diese Felder Schiffsteile.<\/li>\r\n                <li><strong>Rund um Schiffe ist Wasser<\/strong>Um jedes Schiffsteil herum liegt diagonal immer Wasser. Neben einem fertigen Schiff ist rundum alles Wasser.<\/li>\r\n                <li><strong>Die Vorgaben lesen<\/strong>Ein abgerundetes Ende zeigt die Richtung des Schiffs, ein Mittelst\u00fcck verlangt Teile auf beiden Seiten, ein Kreis ist ein U-Boot mit Wasser ringsum.<\/li>\r\n                <li><strong>Das Schlachtschiff fr\u00fch suchen<\/strong>F\u00fcr vier Felder in einer Reihe gibt es meist nur wenige Pl\u00e4tze. Pr\u00fcfen Sie Zeilen und Spalten mit hohen Zahlen.<\/li>\r\n            <\/ul>\r\n        <\/div>\r\n    <\/section>\r\n\r\n    <!-- ===== Hintergrund ===== -->\r\n    <section class=\"ftbm-abschnitt\" aria-labelledby=\"ftbm-h-hintergrund\">\r\n        <h2 id=\"ftbm-h-hintergrund\">Hintergrund<\/h2>\r\n        <div class=\"ftbm-box\">\r\n            <p>Das R\u00e4tsel stammt aus Argentinien: Jaime Poniachik ver\u00f6ffentlichte es 1982 in der Zeitschrift \u00abHumor &amp; Juegos\u00bb unter dem Namen \u00abBatalla Naval\u00bb (Seeschlacht). Die Idee lehnt sich an das bekannte Spiel \u00abSchiffe versenken\u00bb an, kommt aber ohne Gegner und ohne Gl\u00fcck aus.<\/p>\r\n            <p>International bekannt wurde das R\u00e4tsel 1992 an der ersten R\u00e4tsel-Weltmeisterschaft in New York. Heute erscheint es unter vielen Namen, im deutschsprachigen Raum meist als \u00abBimaru\u00bb.<\/p>\r\n            <p class=\"ftbm-quellen-titel\">Quelle<\/p>\r\n            <ul class=\"ftbm-quellen\">\r\n                <li>Battleship (puzzle). In: Wikipedia, englischsprachige Ausgabe. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Battleship_(puzzle)\" target=\"_blank\" rel=\"noopener\">https:\/\/en.wikipedia.org\/wiki\/Battleship_(puzzle)<\/a><\/li>\r\n            <\/ul>\r\n        <\/div>\r\n    <\/section>\r\n\r\n    <!-- Dialog: Raetsel geloest -->\r\n    <div class=\"ftbm-modal\" id=\"ftbm-modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"ftbm-modal-titel\">\r\n        <div class=\"ftbm-modal-hintergrund\"><\/div>\r\n        <div class=\"ftbm-modal-inhalt\">\r\n            <button type=\"button\" class=\"ftbm-modal-schliessen\" aria-label=\"Schliessen\">\u00d7<\/button>\r\n            <h2 id=\"ftbm-modal-titel\">Geschafft!<\/h2>\r\n            <p>Sie haben alle Schiffe richtig platziert.<\/p>\r\n            <div class=\"ftbm-ergebnis\"><strong id=\"ftbm-modal-zeit\">0:00<\/strong><span>Zeit<\/span><\/div>\r\n            <button type=\"button\" id=\"ftbm-modal-neu\" class=\"ftbm-knopf\">Neues Bimaru<\/button>\r\n        <\/div>\r\n    <\/div>\r\n\r\n<\/div>\r\n\r\n<script>\r\n(function () {\r\n    'use strict';\r\n\r\n    if (document.readyState === 'loading') {\r\n        document.addEventListener('DOMContentLoaded', ftbmStart);\r\n    } else {\r\n        ftbmStart();\r\n    }\r\n\r\n    function ftbmStart() {\r\n        const root = document.getElementById('ftbm');\r\n        if (!root || root.dataset.ftbmBereit) return;\r\n        root.dataset.ftbmBereit = '1';\r\n\r\n        \/\/ \u2550\u2550\u2550 Spiellogik aus trainmybrain-bimaru.html (unveraendert uebernommen) \u2550\u2550\u2550\r\n        const GRID = 10;\r\n        \/\/ Standardflotte: 1 Schlachtschiff (4), 2 Kreuzer (3), 3 Zerst\u00f6rer (2), 4 U-Boote (1)\r\n        const FLOTTE      = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1];\r\n        const FLOTTE_SOLL = { 4: 1, 3: 2, 2: 3, 1: 4 };\r\n        const FLOTTE_NAME = { 4: 'Schlachtschiff', 3: 'Kreuzer', 2: 'Zerst\u00f6rer', 1: 'U-Boot' };\r\n\r\n        \/\/ Zellzust\u00e4nde \u2014 identisch f\u00fcr Spielergitter, Hinweise und L\u00f6ser\r\n        const LEER = 0, WASSER = 1, SCHIFF = 2;\r\n\r\n        \/\/ Der Generator deckt zuerst diese Zahl Schiffszellen auf, dann so viele\r\n        \/\/ weitere Zellen, bis das R\u00e4tsel eindeutig ist (gemessen: \u2300 ~10 Hinweise).\r\n        const HINWEIS_START_SCHIFF = 5;\r\n        \/\/ Zus\u00e4tzliche Hinweise je Stufe, bevorzugt Schiffsteile\r\n        const ZUSATZ_HINWEISE = { leicht: 8, mittel: 4, schwer: 0 };\r\n        \/\/ Ung\u00fcnstige Flotten werden verworfen statt die Oberfl\u00e4che zu blockieren\r\n        const ZEITBUDGET_MS = 1000;\r\n\r\n        \/\/ \u2500\u2500 Zustand \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        let loesung    = [];   \/\/ 0\/1 je Zelle\r\n        let rowCounts  = [];\r\n        let colCounts  = [];\r\n        let hinweise   = [];   \/\/ LEER = keiner | WASSER | SCHIFF (gesperrte Vorgaben)\r\n        let spielGrid  = [];   \/\/ LEER | WASSER | SCHIFF (Spielereingabe; Vorgaben inklusive)\r\n        let stufe      = 'mittel';\r\n        let geloest    = false;\r\n        let zellen     = [];   \/\/ [y][x] \u2192 Element\r\n\r\n        const gridContainer = document.getElementById('ftbm-raster');\r\n        const spielmeldung  = document.getElementById('ftbm-sr');\r\n\r\n        \/\/ \u2500\u2500 Helfer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        function mischen(arr) {\r\n            for (let i = arr.length - 1; i > 0; i--) {\r\n                const j = Math.floor(Math.random() * (i + 1));\r\n                [arr[i], arr[j]] = [arr[j], arr[i]];\r\n            }\r\n            return arr;\r\n        }\r\n        const leeresGitter = (wert) => Array.from({ length: GRID }, () => Array(GRID).fill(wert));\r\n        const kopie        = (g) => g.map(r => [...r]);\r\n        const imGitter     = (x, y) => x >= 0 && x < GRID && y >= 0 && y < GRID;\r\n\r\n        \/\/ \u2500\u2500 Flotte erzeugen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Zuf\u00e4llige g\u00fcltige Flotte: keine Ber\u00fchrung, auch nicht diagonal.\r\n        function kannPlatzieren(g, x, y, size, waag) {\r\n            for (let i = 0; i < size; i++) {\r\n                const xi = x + (waag ? i : 0), yi = y + (waag ? 0 : i);\r\n                if (!imGitter(xi, yi) || g[yi][xi]) return false;\r\n                for (let dx = -1; dx <= 1; dx++) for (let dy = -1; dy <= 1; dy++) {\r\n                    const nx = xi + dx, ny = yi + dy;\r\n                    if (imGitter(nx, ny) && g[ny][nx]) return false;\r\n                }\r\n            }\r\n            return true;\r\n        }\r\n\r\n        function erzeugeFlotte() {\r\n            for (let versuch = 0; versuch < 100; versuch++) {\r\n                const g = leeresGitter(0);\r\n                let ok = true;\r\n                for (const size of FLOTTE) {\r\n                    let platziert = false;\r\n                    for (let a = 0; a < 300 && !platziert; a++) {\r\n                        const waag = Math.random() < 0.5;\r\n                        const x = Math.floor(Math.random() * (waag ? GRID - size + 1 : GRID));\r\n                        const y = Math.floor(Math.random() * (waag ? GRID : GRID - size + 1));\r\n                        if (kannPlatzieren(g, x, y, size, waag)) {\r\n                            for (let i = 0; i < size; i++) g[y + (waag ? 0 : i)][x + (waag ? i : 0)] = 1;\r\n                            platziert = true;\r\n                        }\r\n                    }\r\n                    if (!platziert) { ok = false; break; }\r\n                }\r\n                if (ok) return g;\r\n            }\r\n            return null;\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Schiffe aus einem Gitter lesen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Liefert die geraden Schiffsl\u00e4ufe (maximale Folgen von SCHIFF-Zellen).\r\n        \/\/ istSchiff(x,y) abstrahiert die Darstellung (L\u00f6ser: 2, L\u00f6sung: 1).\r\n        function lieseSchiffe(istSchiff) {\r\n            const gesehen = leeresGitter(false);\r\n            const schiffe = [];\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) {\r\n                if (!istSchiff(x, y) || gesehen[y][x]) continue;\r\n                const waag = x < GRID - 1 && istSchiff(x + 1, y);\r\n                let laenge = 1, cx = x, cy = y;\r\n                gesehen[y][x] = true;\r\n                if (waag) { while (cx < GRID - 1 && istSchiff(cx + 1, y)) { cx++; laenge++; gesehen[y][cx] = true; } }\r\n                else      { while (cy < GRID - 1 && istSchiff(x, cy + 1)) { cy++; laenge++; gesehen[cy][x] = true; } }\r\n                schiffe.push({ x, y, x2: cx, y2: cy, laenge, waag });\r\n            }\r\n            return schiffe;\r\n        }\r\n\r\n        \/\/ Ber\u00fchrung (auch diagonal) zwischen verschiedenen Schiffen?\r\n        function beruehrungVorhanden(istSchiff) {\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) {\r\n                if (!istSchiff(x, y)) continue;\r\n                \/\/ diagonal darf nie ein Schiff liegen\r\n                for (const [dx, dy] of [[1, 1], [1, -1]]) {\r\n                    if (imGitter(x + dx, y + dy) && istSchiff(x + dx, y + dy)) return true;\r\n                }\r\n                \/\/ waagrecht UND senkrecht zugleich = Abzweigung = Ber\u00fchrung\r\n                const h = (imGitter(x - 1, y) && istSchiff(x - 1, y)) || (imGitter(x + 1, y) && istSchiff(x + 1, y));\r\n                const v = (imGitter(x, y - 1) && istSchiff(x, y - 1)) || (imGitter(x, y + 1) && istSchiff(x, y + 1));\r\n                if (h && v) return true;\r\n            }\r\n            return false;\r\n        }\r\n\r\n        \/\/ \u2500\u2500 L\u00f6ser: zellbasiert mit Ausbreitung \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Findet bis zu `limit` L\u00f6sungen. Der fr\u00fchere Generator pr\u00fcfte nie, ob\r\n        \/\/ ein R\u00e4tsel eindeutig ist \u2014 gemessen war es KEINES. Dieser L\u00f6ser ist die\r\n        \/\/ Grundlage der Eindeutigkeitsgarantie und f\u00fcr die Regelpr\u00fcfung.\r\n        function loeseBimaru(rows, cols, fix, limit) {\r\n            const sols = [];\r\n            const start = leeresGitter(LEER);\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) start[y][x] = fix[y][x];\r\n\r\n            function ausbreiten(g) {\r\n                let geaendert = true;\r\n                while (geaendert) {\r\n                    geaendert = false;\r\n                    \/\/ Zeilen\r\n                    for (let y = 0; y < GRID; y++) {\r\n                        let s = 0, u = 0;\r\n                        for (let x = 0; x < GRID; x++) { if (g[y][x] === SCHIFF) s++; else if (g[y][x] === LEER) u++; }\r\n                        if (s > rows[y] || s + u < rows[y]) return false;\r\n                        if (u && s === rows[y])          { for (let x = 0; x < GRID; x++) if (g[y][x] === LEER) g[y][x] = WASSER; geaendert = true; }\r\n                        else if (u && s + u === rows[y]) { for (let x = 0; x < GRID; x++) if (g[y][x] === LEER) g[y][x] = SCHIFF; geaendert = true; }\r\n                    }\r\n                    \/\/ Spalten\r\n                    for (let x = 0; x < GRID; x++) {\r\n                        let s = 0, u = 0;\r\n                        for (let y = 0; y < GRID; y++) { if (g[y][x] === SCHIFF) s++; else if (g[y][x] === LEER) u++; }\r\n                        if (s > cols[x] || s + u < cols[x]) return false;\r\n                        if (u && s === cols[x])          { for (let y = 0; y < GRID; y++) if (g[y][x] === LEER) g[y][x] = WASSER; geaendert = true; }\r\n                        else if (u && s + u === cols[x]) { for (let y = 0; y < GRID; y++) if (g[y][x] === LEER) g[y][x] = SCHIFF; geaendert = true; }\r\n                    }\r\n                    \/\/ Umgebung von Schiffsteilen\r\n                    for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) {\r\n                        if (g[y][x] !== SCHIFF) continue;\r\n                        for (const [dx, dy] of [[-1, -1], [1, -1], [-1, 1], [1, 1]]) {\r\n                            const nx = x + dx, ny = y + dy;\r\n                            if (!imGitter(nx, ny)) continue;\r\n                            if (g[ny][nx] === SCHIFF) return false;\r\n                            if (g[ny][nx] === LEER) { g[ny][nx] = WASSER; geaendert = true; }\r\n                        }\r\n                        const h = (x > 0 && g[y][x - 1] === SCHIFF) || (x < GRID - 1 && g[y][x + 1] === SCHIFF);\r\n                        const v = (y > 0 && g[y - 1][x] === SCHIFF) || (y < GRID - 1 && g[y + 1][x] === SCHIFF);\r\n                        if (h && v) return false;\r\n                        if (h) for (const ny of [y - 1, y + 1]) if (ny >= 0 && ny < GRID) {\r\n                            if (g[ny][x] === SCHIFF) return false;\r\n                            if (g[ny][x] === LEER) { g[ny][x] = WASSER; geaendert = true; }\r\n                        }\r\n                        if (v) for (const nx of [x - 1, x + 1]) if (nx >= 0 && nx < GRID) {\r\n                            if (g[y][nx] === SCHIFF) return false;\r\n                            if (g[y][nx] === LEER) { g[y][nx] = WASSER; geaendert = true; }\r\n                        }\r\n                    }\r\n                }\r\n                return true;\r\n            }\r\n\r\n            \/\/ Flottenpr\u00fcfung: unterwegs nur Obergrenzen, am Ende exakt.\r\n            function flotteOk(g, fertig) {\r\n                const istS = (x, y) => g[y][x] === SCHIFF;\r\n                const ist = { 4: 0, 3: 0, 2: 0, 1: 0 };\r\n                let offene = 0;\r\n                for (const s of lieseSchiffe(istS)) {\r\n                    if (s.laenge > 4) return false;\r\n                    \/\/ abgeschlossen = in L\u00e4ngsrichtung beidseitig Wasser\/Rand, bei L\u00e4nge 1 rundum\r\n                    const frei = (x, y) => !imGitter(x, y) || g[y][x] !== LEER;\r\n                    let abgeschlossen;\r\n                    if (s.laenge === 1) {\r\n                        abgeschlossen = frei(s.x - 1, s.y) && frei(s.x + 1, s.y) && frei(s.x, s.y - 1) && frei(s.x, s.y + 1);\r\n                    } else if (s.waag) {\r\n                        abgeschlossen = frei(s.x - 1, s.y) && frei(s.x2 + 1, s.y);\r\n                    } else {\r\n                        abgeschlossen = frei(s.x, s.y - 1) && frei(s.x, s.y2 + 1);\r\n                    }\r\n                    if (abgeschlossen) ist[s.laenge]++; else offene++;\r\n                }\r\n                for (const k of [4, 3, 2, 1]) if (ist[k] > FLOTTE_SOLL[k]) return false;\r\n                if (fertig) {\r\n                    if (offene) return false;\r\n                    for (const k of [4, 3, 2, 1]) if (ist[k] !== FLOTTE_SOLL[k]) return false;\r\n                }\r\n                return true;\r\n            }\r\n\r\n            (function suche(g0) {\r\n                if (sols.length >= limit) return;\r\n                const g = kopie(g0);\r\n                if (!ausbreiten(g)) return;\r\n                if (!flotteOk(g, false)) return;\r\n                \/\/ Verzweigung auf die unbekannte Zelle in der knappsten Zeile\/Spalte\r\n                let bx = -1, by = -1, best = Infinity;\r\n                for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) {\r\n                    if (g[y][x] !== LEER) continue;\r\n                    let u = 0;\r\n                    for (let k = 0; k < GRID; k++) { if (g[y][k] === LEER) u++; if (g[k][x] === LEER) u++; }\r\n                    if (u < best) { best = u; bx = x; by = y; }\r\n                }\r\n                if (bx === -1) {\r\n                    if (flotteOk(g, true)) sols.push(kopie(g));\r\n                    return;\r\n                }\r\n                for (const wert of [SCHIFF, WASSER]) {\r\n                    const g2 = kopie(g);\r\n                    g2[by][bx] = wert;\r\n                    suche(g2);\r\n                    if (sols.length >= limit) return;\r\n                }\r\n            })(start);\r\n\r\n            return sols;\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Generator mit Eindeutigkeitsgarantie \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Unterscheidender Hinweis: Findet der L\u00f6ser zwei L\u00f6sungen, wird eine\r\n        \/\/ Zelle, in der sie voneinander abweichen, aus der wahren L\u00f6sung\r\n        \/\/ aufgedeckt \u2014 so lange, bis nur eine L\u00f6sung \u00fcbrig bleibt.\r\n        function erzeugeRaetsel() {\r\n            let letztes = null;\r\n            \/\/ Die ersten Versuche halten das Zeitbudget ein (ung\u00fcnstige Flotte \u2192\r\n            \/\/ neue Flotte). Der letzte l\u00e4uft ohne Budget: der Hinweis-Loop\r\n            \/\/ konvergiert immer, also gibt es auf jedem Ger\u00e4t ein R\u00e4tsel \u2014 nur\r\n            \/\/ auf sehr langsamen ausnahmsweise etwas sp\u00e4ter.\r\n            for (let versuch = 0; versuch < 12; versuch++) {\r\n                const budget = versuch < 11 ? ZEITBUDGET_MS : Infinity;\r\n                const t0  = performance.now();\r\n                const sol = erzeugeFlotte();\r\n                if (!sol) continue;\r\n                const rows = sol.map(r => r.reduce((a, b) => a + b, 0));\r\n                const cols = Array.from({ length: GRID }, (_, x) => sol.reduce((n, r) => n + r[x], 0));\r\n                const fix  = leeresGitter(LEER);\r\n\r\n                const schiffZellen = [], wasserZellen = [];\r\n                for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) (sol[y][x] ? schiffZellen : wasserZellen).push([x, y]);\r\n                mischen(schiffZellen); mischen(wasserZellen);\r\n                for (let i = 0; i < HINWEIS_START_SCHIFF; i++) { const [x, y] = schiffZellen[i]; fix[y][x] = SCHIFF; }\r\n\r\n                let ok = true;\r\n                for (;;) {\r\n                    if (performance.now() - t0 > budget) { ok = false; break; }\r\n                    const sols = loeseBimaru(rows, cols, fix, 2);\r\n                    if (sols.length === 1) break;\r\n                    if (sols.length === 0) { ok = false; break; }\r\n                    const diff = [];\r\n                    for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) {\r\n                        if (sols[0][y][x] !== sols[1][y][x] && fix[y][x] === LEER) diff.push([x, y]);\r\n                    }\r\n                    const [x, y] = diff[Math.floor(Math.random() * diff.length)];\r\n                    fix[y][x] = sol[y][x] ? SCHIFF : WASSER;\r\n                }\r\n                if (!ok) continue;\r\n\r\n                \/\/ Zusatzhinweise je Stufe, bevorzugt Schiffsteile\r\n                let extra = ZUSATZ_HINWEISE[stufe] || 0;\r\n                for (const [x, y] of schiffZellen) { if (!extra) break; if (fix[y][x] === LEER) { fix[y][x] = SCHIFF; extra--; } }\r\n                for (const [x, y] of wasserZellen) { if (!extra) break; if (fix[y][x] === LEER) { fix[y][x] = WASSER; extra--; } }\r\n\r\n                \/\/ Zusicherung: genau eine L\u00f6sung\r\n                letztes = { sol, rows, cols, fix };\r\n                if (loeseBimaru(rows, cols, fix, 2).length === 1) return letztes;\r\n            }\r\n            return letztes;   \/\/ praktisch unerreichbar; die Endkontrolle greift bei jedem Versuch\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Form eines Schiffsteils \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Aus einem Gitter (L\u00f6sung oder Spielereingabe) ableiten. Ein einzelnes\r\n        \/\/ Teil mit noch offenen Nachbarn ist \u00abunbestimmt\u00bb, kein U-Boot \u2014 erst\r\n        \/\/ wenn ringsum Wasser oder Rand liegt, wird daraus das U-Boot.\r\n        function schiffForm(x, y, istSchiff, istWasser) {\r\n            const l = imGitter(x - 1, y) && istSchiff(x - 1, y);\r\n            const r = imGitter(x + 1, y) && istSchiff(x + 1, y);\r\n            const o = imGitter(x, y - 1) && istSchiff(x, y - 1);\r\n            const u = imGitter(x, y + 1) && istSchiff(x, y + 1);\r\n            if (l && r) return 'mitte';\r\n            if (o && u) return 'mitte';\r\n            \/\/ Ein Ende ist erst ein Ende, wenn hinter ihm bekanntes Wasser liegt \u2014\r\n            \/\/ sonst k\u00f6nnte der Lauf noch weitergehen (halber Kreuzer statt Zerst\u00f6rer).\r\n            if (r)      return istWasser(x - 1, y) ? 'start' : 'unbestimmt';\r\n            if (l)      return istWasser(x + 1, y) ? 'ende'  : 'unbestimmt';\r\n            if (u)      return istWasser(x, y - 1) ? 'oben'  : 'unbestimmt';\r\n            if (o)      return istWasser(x, y + 1) ? 'unten' : 'unbestimmt';\r\n            const ringsum = [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]]\r\n                .every(([nx, ny]) => istWasser(nx, ny));\r\n            return ringsum ? 'einzel' : 'unbestimmt';\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Bekanntes Wasser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Die eine Regel, der Abhaken UND Darstellung folgen. Ein leeres Feld ist\r\n        \/\/ bekanntes Wasser, wenn dort kein Schiff mehr liegen kann: Zeile oder\r\n        \/\/ Spalte bereits erf\u00fcllt, oder die Form einer angrenzenden Vorgabe sagt\r\n        \/\/ es (rundum ein U-Boot, hinter einem Ende, quer zu einem Mittelst\u00fcck).\r\n        \/\/ Fr\u00fcher galt jedes leere Feld als Wasser \u2014 dadurch wurde ein isoliertes\r\n        \/\/ Mittelst\u00fcck als U-Boot abgehakt und ein offener Dreierlauf als Kreuzer.\r\n        \/\/ Exakt erf\u00fcllt \u2014 aus einer \u00fcberzogenen (roten) Zeile l\u00e4sst sich nichts ableiten.\r\n        function zeileErfuellt(y)  { return spielGrid[y].filter(v => v === SCHIFF).length === rowCounts[y]; }\r\n        function spalteErfuellt(x) { return spielGrid.reduce((n, r) => n + (r[x] === SCHIFF ? 1 : 0), 0) === colCounts[x]; }\r\n\r\n        function istBekanntesWasser(x, y) {\r\n            if (!imGitter(x, y)) return true;\r\n            const v = spielGrid[y][x];\r\n            if (v === WASSER) return true;\r\n            if (v === SCHIFF) return false;\r\n            if (zeileErfuellt(y) || spalteErfuellt(x)) return true;\r\n            \/\/ Orthogonale Nachbarn einer Vorgabe sind in der L\u00f6sung entweder Schiff\r\n            \/\/ (L\u00e4ngsachse) oder Wasser \u2014 genau das verr\u00e4t ihre Form.\r\n            for (const [nx, ny] of [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]]) {\r\n                if (imGitter(nx, ny) && hinweise[ny][nx] === SCHIFF && loesung[y][x] === 0) return true;\r\n            }\r\n            return false;\r\n        }\r\n\r\n        \/\/ Abgeschlossene Schiffe je Gr\u00f6sse: beide Enden (bei L\u00e4nge 1 alle vier\r\n        \/\/ Seiten) durch bekanntes Wasser oder den Rand begrenzt.\r\n        function zaehleAbgeschlossene() {\r\n            const ist = { 4: 0, 3: 0, 2: 0, 1: 0 };\r\n            for (const s of lieseSchiffe((x, y) => spielGrid[y][x] === SCHIFF)) {\r\n                if (s.laenge > 4) continue;\r\n                let zu;\r\n                if (s.laenge === 1) {\r\n                    zu = istBekanntesWasser(s.x - 1, s.y) && istBekanntesWasser(s.x + 1, s.y) &&\r\n                         istBekanntesWasser(s.x, s.y - 1) && istBekanntesWasser(s.x, s.y + 1);\r\n                } else if (s.waag) {\r\n                    zu = istBekanntesWasser(s.x - 1, s.y) && istBekanntesWasser(s.x2 + 1, s.y);\r\n                } else {\r\n                    zu = istBekanntesWasser(s.x, s.y - 1) && istBekanntesWasser(s.x, s.y2 + 1);\r\n                }\r\n                if (zu) ist[s.laenge]++;\r\n            }\r\n            return ist;\r\n        }\r\n        const FORM_KLASSE = { start: 'ship-start', ende: 'ship-end', oben: 'ship-top', unten: 'ship-bottom',\r\n                              mitte: 'ship-middle', einzel: 'ship-single', unbestimmt: 'ship-generic' };\r\n        const FORM_TEXT   = { start: 'Schiffsende (links)', ende: 'Schiffsende (rechts)', oben: 'Schiffsende (oben)',\r\n                              unten: 'Schiffsende (unten)', mitte: 'Mittelst\u00fcck', einzel: 'U-Boot', unbestimmt: 'Schiffsteil' };\r\n\r\n        \/\/ \u2500\u2500 Darstellung \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        function meldung(text) { if (spielmeldung) spielmeldung.textContent = text; }\r\n\r\n        function baueGitter() {\r\n            gridContainer.innerHTML = '';\r\n            zellen = [];\r\n            const ecke = document.createElement('div');\r\n            ecke.className = 'empty-cell';\r\n            gridContainer.appendChild(ecke);\r\n            for (let x = 0; x < GRID; x++) {\r\n                const h = document.createElement('div');\r\n                h.className = 'hint-cell';\r\n                h.dataset.spalte = x;\r\n                h.textContent = colCounts[x];\r\n                h.setAttribute('aria-label', `Spalte ${x + 1}: ${colCounts[x]} Schiffsteile`);\r\n                gridContainer.appendChild(h);\r\n            }\r\n            for (let y = 0; y < GRID; y++) {\r\n                const h = document.createElement('div');\r\n                h.className = 'hint-cell';\r\n                h.dataset.zeile = y;\r\n                h.textContent = rowCounts[y];\r\n                h.setAttribute('aria-label', `Zeile ${y + 1}: ${rowCounts[y]} Schiffsteile`);\r\n                gridContainer.appendChild(h);\r\n                zellen[y] = [];\r\n                for (let x = 0; x < GRID; x++) {\r\n                    \/\/ fahrtauglich: <button> statt <div>, damit per Tastatur bedienbar\r\n                    const z = document.createElement('button');\r\n                    z.type = 'button';\r\n                    z.className = 'batalla-cell';\r\n                    z.dataset.x = x; z.dataset.y = y;\r\n                    z.tabIndex = (x === 0 && y === 0) ? 0 : -1;\r\n                    z.setAttribute('role', 'gridcell');\r\n                    if (hinweise[y][x] !== LEER) {\r\n                        z.classList.add('highlighted');\r\n                        z.setAttribute('aria-disabled', 'true');\r\n                    } else {\r\n                        z.addEventListener('click', handleCellClick);\r\n                    }\r\n                    gridContainer.appendChild(z);\r\n                    zellen[y][x] = z;\r\n                }\r\n            }\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) zeichneZelle(x, y);\r\n            aktualisiereHinweise();\r\n            aktualisiereFlotte();\r\n        }\r\n\r\n        function zeichneZelle(x, y) {\r\n            const z = zellen[y][x];\r\n            const wert = spielGrid[y][x];\r\n            const vorgabe = hinweise[y][x] !== LEER;\r\n            z.textContent = '';\r\n            z.classList.remove('water', 'ship');\r\n            const alt = z.querySelector('.ship-part');\r\n            if (alt) alt.remove();\r\n            const pos = `Zeile ${y + 1}, Spalte ${x + 1}`;\r\n\r\n            if (wert === WASSER) {\r\n                z.classList.add('water');\r\n                z.textContent = '\ud83c\udf0a';\r\n                z.setAttribute('aria-label', `${pos}: Wasser${vorgabe ? ' (vorgegeben)' : ''}`);\r\n            } else if (wert === SCHIFF) {\r\n                z.classList.add('ship');\r\n                \/\/ Vorgaben zeigen ihre wahre Form; Spielereingaben die aus den Nachbarn ableitbare\r\n                const form = vorgabe\r\n                    ? schiffForm(x, y, (a, b) => loesung[b][a] === 1, (a, b) => !imGitter(a, b) || loesung[b][a] === 0)\r\n                    : schiffForm(x, y, (a, b) => spielGrid[b][a] === SCHIFF, istBekanntesWasser);\r\n                const teil = document.createElement('div');\r\n                teil.className = `ship-part visible ${FORM_KLASSE[form]}`;\r\n                z.appendChild(teil);\r\n                z.setAttribute('aria-label', `${pos}: ${FORM_TEXT[form]}${vorgabe ? ' (vorgegeben)' : ''}`);\r\n            } else {\r\n                z.setAttribute('aria-label', `${pos}: leer`);\r\n            }\r\n        }\r\n\r\n        \/\/ Zeilen-\/Spaltenzahlen: erf\u00fcllt = gr\u00fcn, \u00fcberschritten = rot\r\n        function aktualisiereHinweise() {\r\n            for (let y = 0; y < GRID; y++) {\r\n                const n = spielGrid[y].filter(v => v === SCHIFF).length;\r\n                const h = gridContainer.querySelector(`.hint-cell[data-zeile=\"${y}\"]`);\r\n                h.classList.toggle('erfuellt', n === rowCounts[y]);\r\n                h.classList.toggle('zuviel',   n >  rowCounts[y]);\r\n                h.setAttribute('aria-label', `Zeile ${y + 1}: ${rowCounts[y]} Schiffsteile, ${n} gesetzt${n === rowCounts[y] ? ', erf\u00fcllt' : n > rowCounts[y] ? ', zu viele' : ''}`);\r\n            }\r\n            for (let x = 0; x < GRID; x++) {\r\n                const n = spielGrid.reduce((s, r) => s + (r[x] === SCHIFF ? 1 : 0), 0);\r\n                const h = gridContainer.querySelector(`.hint-cell[data-spalte=\"${x}\"]`);\r\n                h.classList.toggle('erfuellt', n === colCounts[x]);\r\n                h.classList.toggle('zuviel',   n >  colCounts[x]);\r\n                h.setAttribute('aria-label', `Spalte ${x + 1}: ${colCounts[x]} Schiffsteile, ${n} gesetzt${n === colCounts[x] ? ', erf\u00fcllt' : n > colCounts[x] ? ', zu viele' : ''}`);\r\n            }\r\n        }\r\n\r\n        \/\/ Flottenanzeige: fertig gesetzte Schiffe je Gr\u00f6sse abhaken\r\n        function renderShipContainer() {\r\n            const container = document.getElementById('ftbm-flotte');\r\n            container.innerHTML = '';\r\n            for (const size of FLOTTE) {\r\n                const ship = document.createElement('div');\r\n                ship.className = 'ship';\r\n                ship.dataset.size = size;\r\n                ship.setAttribute('aria-label', FLOTTE_NAME[size]);\r\n                for (let j = 0; j < size; j++) {\r\n                    const part = document.createElement('div');\r\n                    part.className = 'part';\r\n                    if (size === 1)           part.classList.add('ship-single');\r\n                    else if (j === 0)         part.classList.add('ship-start');\r\n                    else if (j === size - 1)  part.classList.add('ship-end');\r\n                    ship.appendChild(part);\r\n                }\r\n                container.appendChild(ship);\r\n            }\r\n        }\r\n\r\n        function aktualisiereFlotte() {\r\n            const verbleibend = zaehleAbgeschlossene();\r\n            document.querySelectorAll('#ftbm-flotte .ship').forEach(el => {\r\n                const size = parseInt(el.dataset.size, 10);\r\n                const fertig = verbleibend[size] > 0;\r\n                if (fertig) verbleibend[size]--;\r\n                el.classList.toggle('gefunden', fertig);\r\n            });\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Regelbasierte Gewinnpr\u00fcfung \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Nicht markierte Zellen gelten als Wasser. Gepr\u00fcft werden die Regeln,\r\n        \/\/ nicht die Identit\u00e4t mit der erzeugten L\u00f6sung \u2014 das R\u00e4tsel ist eindeutig,\r\n        \/\/ die Regelpr\u00fcfung ist das Sicherheitsnetz.\r\n        function istGeloest() {\r\n            const istS = (x, y) => spielGrid[y][x] === SCHIFF;\r\n            for (let y = 0; y < GRID; y++) if (spielGrid[y].filter(v => v === SCHIFF).length !== rowCounts[y]) return false;\r\n            for (let x = 0; x < GRID; x++) if (spielGrid.reduce((s, r) => s + (r[x] === SCHIFF ? 1 : 0), 0) !== colCounts[x]) return false;\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) {\r\n                if (hinweise[y][x] === SCHIFF && !istS(x, y)) return false;\r\n                if (hinweise[y][x] === WASSER && istS(x, y)) return false;\r\n            }\r\n            if (beruehrungVorhanden(istS)) return false;\r\n            const ist = { 4: 0, 3: 0, 2: 0, 1: 0 };\r\n            for (const s of lieseSchiffe(istS)) { if (s.laenge > 4) return false; ist[s.laenge]++; }\r\n            for (const k of [4, 3, 2, 1]) if (ist[k] !== FLOTTE_SOLL[k]) return false;\r\n            return true;\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Eingabe \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        \/\/ Drei Zust\u00e4nde: leer \u2192 Wasser \u2192 Schiff \u2192 leer. Die Form ergibt sich aus\r\n        \/\/ den Nachbarn, deshalb werden diese mitgezeichnet.\r\n        function handleCellClick(e) {\r\n            if (geloest) return;\r\n            const x = parseInt(e.currentTarget.dataset.x, 10);\r\n            const y = parseInt(e.currentTarget.dataset.y, 10);\r\n            if (hinweise[y][x] !== LEER) return;\r\n            spielGrid[y][x] = (spielGrid[y][x] + 1) % 3;\r\n            aktualisiereHinweise();\r\n            \/\/ Alle Zellen: eine erf\u00fcllte Zeile macht anderswo Enden zu Enden\r\n            for (let yy = 0; yy < GRID; yy++) for (let xx = 0; xx < GRID; xx++) zeichneZelle(xx, yy);\r\n            aktualisiereFlotte();\r\n            if (istGeloest()) {\r\n                geloest = true;\r\n                meldung('Gl\u00fcckwunsch! R\u00e4tsel gel\u00f6st!');\r\n                geloestAnzeigen();\r\n            }\r\n        }\r\n        \/\/ \u2550\u2550\u2550 Ende der uebernommenen Spiellogik \u2550\u2550\u2550\r\n\r\n        \/\/ \u2500\u2500 Spielfluss (fahrtauglich) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        const meldungEl = document.getElementById('ftbm-meldung');\r\n        const modal     = document.getElementById('ftbm-modal');\r\n        let startZeit   = 0;\r\n\r\n        function sichtbar(text, art) {\r\n            meldungEl.textContent = text;\r\n            meldungEl.className = 'ftbm-meldung' + (art ? ' ' + art : '');\r\n        }\r\n\r\n        function geloestAnzeigen() {\r\n            const s = Math.floor((performance.now() - startZeit) \/ 1000);\r\n            const zeit = `${Math.floor(s \/ 60)}:${String(s % 60).padStart(2, '0')}`;\r\n            document.getElementById('ftbm-modal-zeit').textContent = zeit;\r\n            sichtbar(`Geschafft in ${zeit}!`, 'erfolg');\r\n            ftEvent({ event: 'bimaru_geloest', bimaru_stufe: stufe, bimaru_sekunden: s });\r\n            setTimeout(() => {\r\n                modal.classList.add('active');\r\n                document.body.style.overflow = 'hidden';\r\n                document.getElementById('ftbm-modal-neu').focus();\r\n            }, 250);\r\n        }\r\n\r\n        function modalSchliessen() {\r\n            modal.classList.remove('active');\r\n            document.body.style.overflow = '';\r\n        }\r\n\r\n        function neuesSpiel() {\r\n            sichtbar('R\u00e4tsel wird erstellt \u2026');\r\n            \/\/ Kurz Luft fuer die Anzeige, bevor der Generator rechnet (meist < 0.1 s)\r\n            setTimeout(() => {\r\n                const r = erzeugeRaetsel();\r\n                loesung   = r.sol;\r\n                rowCounts = r.rows;\r\n                colCounts = r.cols;\r\n                hinweise  = r.fix;\r\n                geloest   = false;\r\n                spielGrid = kopie(hinweise);\r\n                renderShipContainer();\r\n                baueGitter();\r\n                startZeit = performance.now();\r\n                document.getElementById('ftbm-loesung').disabled = false;\r\n                const n = hinweise.flat().filter(v => v !== LEER).length;\r\n                sichtbar('');\r\n                meldung(`Neues Bimaru, Stufe ${stufe}, mit ${n} vorgegebenen Feldern. Genau eine L\u00f6sung.`);\r\n            }, 30);\r\n        }\r\n\r\n        function neustart() {\r\n            geloest   = false;\r\n            spielGrid = kopie(hinweise);\r\n            renderShipContainer();\r\n            baueGitter();\r\n            document.getElementById('ftbm-loesung').disabled = false;\r\n            sichtbar('R\u00e4tsel auf den Anfang zur\u00fcckgesetzt.');\r\n            meldung('R\u00e4tsel auf den Anfangszustand zur\u00fcckgesetzt.');\r\n        }\r\n\r\n        function zeigeLoesung() {\r\n            if (geloest) return;\r\n            geloest = true;\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) spielGrid[y][x] = loesung[y][x] ? SCHIFF : WASSER;\r\n            for (let y = 0; y < GRID; y++) for (let x = 0; x < GRID; x++) zeichneZelle(x, y);\r\n            aktualisiereHinweise();\r\n            aktualisiereFlotte();\r\n            document.getElementById('ftbm-loesung').disabled = true;\r\n            sichtbar('L\u00f6sung angezeigt. Mit \u00abNeues Bimaru\u00bb geht es weiter.');\r\n            meldung('L\u00f6sung wird angezeigt.');\r\n            ftEvent({ event: 'bimaru_loesung', bimaru_stufe: stufe });\r\n        }\r\n\r\n        function setzeStufe(neu) {\r\n            stufe = neu;\r\n            root.querySelectorAll('.ftbm-stufe').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.stufe === neu)));\r\n            try { localStorage.setItem('ft_bimaru_stufe', neu); } catch (e) {}\r\n            neuesSpiel();\r\n        }\r\n\r\n        \/** Spielereignis an GTM (dataLayer). Nur Spieldaten, keine Personendaten. *\/\r\n        function ftEvent(daten) {\r\n            try {\r\n                window.dataLayer = window.dataLayer || [];\r\n                window.dataLayer.push(Object.assign({ spiel_seite: 'fahrtauglich' }, daten));\r\n            } catch (e) {}\r\n        }\r\n\r\n        \/\/ \u2500\u2500 Tastatur im Raster: Pfeiltasten bewegen den Fokus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        gridContainer.addEventListener('keydown', e => {\r\n            const z = e.target.closest('.batalla-cell');\r\n            if (!z) return;\r\n            const d = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] }[e.key];\r\n            if (!d) return;\r\n            e.preventDefault();\r\n            const x = Math.max(0, Math.min(GRID - 1, +z.dataset.x + d[0]));\r\n            const y = Math.max(0, Math.min(GRID - 1, +z.dataset.y + d[1]));\r\n            z.tabIndex = -1;\r\n            zellen[y][x].tabIndex = 0;\r\n            zellen[y][x].focus();\r\n        });\r\n\r\n        \/\/ Nach einem Mausklick den Fokus abgeben; Tastaturbedienung unveraendert\r\n        function klick(btn, fn) {\r\n            btn.addEventListener('click', e => {\r\n                e.preventDefault();\r\n                if (e.detail > 0) btn.blur();\r\n                fn();\r\n            });\r\n        }\r\n        root.querySelectorAll('.ftbm-stufe').forEach(b => klick(b, () => setzeStufe(b.dataset.stufe)));\r\n        klick(document.getElementById('ftbm-neu'), neuesSpiel);\r\n        klick(document.getElementById('ftbm-neustart'), neustart);\r\n        klick(document.getElementById('ftbm-loesung'), zeigeLoesung);\r\n        klick(document.getElementById('ftbm-modal-neu'), () => { modalSchliessen(); neuesSpiel(); });\r\n        modal.querySelector('.ftbm-modal-schliessen').addEventListener('click', modalSchliessen);\r\n        modal.querySelector('.ftbm-modal-hintergrund').addEventListener('click', modalSchliessen);\r\n        document.addEventListener('keydown', e => {\r\n            if (e.key === 'Escape' && modal.classList.contains('active')) { e.preventDefault(); modalSchliessen(); }\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Start \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        let gespeichert = null;\r\n        try { gespeichert = localStorage.getItem('ft_bimaru_stufe'); } catch (e) {}\r\n        if (gespeichert && ZUSATZ_HINWEISE[gespeichert] !== undefined) {\r\n            stufe = gespeichert;\r\n            root.querySelectorAll('.ftbm-stufe').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.stufe === stufe)));\r\n        }\r\n        neuesSpiel();\r\n        try {\r\n            if (!localStorage.getItem('ft_bimaru_seen')) {\r\n                document.getElementById('ftbm-anleitung').open = true;\r\n                localStorage.setItem('ft_bimaru_seen', '1');\r\n            }\r\n        } catch (e) {}\r\n    }\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Spielen Sie Sudoku online mit individuell einstellbarem Fehlerlimit. Unser adaptives Sudoku wird nach jedem Erfolg schwieriger.<\/p>","protected":false},"author":1,"featured_media":4437,"parent":1467,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"content-type":"","iawp_total_views":6384,"footnotes":""},"class_list":["post-4378","page","type-page","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Bimaru online: Bimaru online spielen<\/title>\n<meta name=\"description\" content=\"Spielen Sie Bimaru online! Ideal zur Steigerung der geistigen Fitness und als Ged\u00e4chtnistraining. Geniessen Sie jetzt diese Denksportaufgabe!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fahrtauglich.ch\/fr\/praxisportal\/bimaru\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bimaru online: Bimaru online spielen\" \/>\n<meta property=\"og:description\" content=\"Spielen Sie Bimaru online! Ideal zur Steigerung der geistigen Fitness und als Ged\u00e4chtnistraining. Geniessen Sie jetzt diese Denksportaufgabe!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fahrtauglich.ch\/fr\/praxisportal\/bimaru\/\" \/>\n<meta property=\"og:site_name\" content=\"Fahrtauglich\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-12T10:43:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1420\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/\",\"url\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/\",\"name\":\"Bimaru online: Bimaru online spielen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fahrtauglich.ch\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/Bimaru.jpg\",\"datePublished\":\"2024-11-15T11:02:38+00:00\",\"dateModified\":\"2026-10-12T10:43:32+00:00\",\"description\":\"Spielen Sie Bimaru online! Ideal zur Steigerung der geistigen Fitness und als Ged\u00e4chtnistraining. Geniessen Sie jetzt diese Denksportaufgabe!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/#primaryimage\",\"url\":\"https:\\\/\\\/fahrtauglich.ch\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/Bimaru.jpg\",\"contentUrl\":\"https:\\\/\\\/fahrtauglich.ch\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/Bimaru.jpg\",\"width\":1420,\"height\":1080,\"caption\":\"Bimaru l\u00f6sen - R\u00e4tsel zur Steigerung der geistigen Fitness\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/bimaru\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/fahrtauglich.ch\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Praxisportal\",\"item\":\"https:\\\/\\\/fahrtauglich.ch\\\/praxisportal\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Bimaru online\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/#website\",\"url\":\"https:\\\/\\\/fahrtauglich.ch\\\/\",\"name\":\"Fahrtauglich\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/fahrtauglich.ch\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/#organization\",\"name\":\"Fahrtauglich\",\"url\":\"https:\\\/\\\/fahrtauglich.ch\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/fahrtauglich.ch\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/cropped-Logo-2.jpg\",\"contentUrl\":\"https:\\\/\\\/fahrtauglich.ch\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/cropped-Logo-2.jpg\",\"width\":307,\"height\":188,\"caption\":\"Fahrtauglich\"},\"image\":{\"@id\":\"https:\\\/\\\/fahrtauglich.ch\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Bimaru online: Bimaru online spielen","description":"Spielen Sie Bimaru online! Ideal zur Steigerung der geistigen Fitness und als Ged\u00e4chtnistraining. Geniessen Sie jetzt diese Denksportaufgabe!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fahrtauglich.ch\/fr\/praxisportal\/bimaru\/","og_locale":"fr_FR","og_type":"article","og_title":"Bimaru online: Bimaru online spielen","og_description":"Spielen Sie Bimaru online! Ideal zur Steigerung der geistigen Fitness und als Ged\u00e4chtnistraining. Geniessen Sie jetzt diese Denksportaufgabe!","og_url":"https:\/\/fahrtauglich.ch\/fr\/praxisportal\/bimaru\/","og_site_name":"Fahrtauglich","article_modified_time":"2026-10-12T10:43:32+00:00","og_image":[{"width":1420,"height":1080,"url":"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/","url":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/","name":"Bimaru online: Bimaru online spielen","isPartOf":{"@id":"https:\/\/fahrtauglich.ch\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/#primaryimage"},"image":{"@id":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/#primaryimage"},"thumbnailUrl":"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg","datePublished":"2024-11-15T11:02:38+00:00","dateModified":"2026-10-12T10:43:32+00:00","description":"Spielen Sie Bimaru online! Ideal zur Steigerung der geistigen Fitness und als Ged\u00e4chtnistraining. Geniessen Sie jetzt diese Denksportaufgabe!","breadcrumb":{"@id":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/#primaryimage","url":"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg","contentUrl":"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg","width":1420,"height":1080,"caption":"Bimaru l\u00f6sen - R\u00e4tsel zur Steigerung der geistigen Fitness"},{"@type":"BreadcrumbList","@id":"https:\/\/fahrtauglich.ch\/praxisportal\/bimaru\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/fahrtauglich.ch\/"},{"@type":"ListItem","position":2,"name":"Praxisportal","item":"https:\/\/fahrtauglich.ch\/praxisportal\/"},{"@type":"ListItem","position":3,"name":"Bimaru online"}]},{"@type":"WebSite","@id":"https:\/\/fahrtauglich.ch\/#website","url":"https:\/\/fahrtauglich.ch\/","name":"Fahrtauglich","description":"","publisher":{"@id":"https:\/\/fahrtauglich.ch\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fahrtauglich.ch\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/fahrtauglich.ch\/#organization","name":"Fahrtauglich","url":"https:\/\/fahrtauglich.ch\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/fahrtauglich.ch\/#\/schema\/logo\/image\/","url":"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/08\/cropped-Logo-2.jpg","contentUrl":"https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/08\/cropped-Logo-2.jpg","width":307,"height":188,"caption":"Fahrtauglich"},"image":{"@id":"https:\/\/fahrtauglich.ch\/#\/schema\/logo\/image\/"}}]}},"rttpg_featured_image_url":{"full":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg",1420,1080,false],"landscape":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg",1420,1080,false],"portraits":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg",1420,1080,false],"thumbnail":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru-150x150.jpg",150,150,true],"medium":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru-300x228.jpg",300,228,true],"large":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru-1024x779.jpg",800,609,true],"1536x1536":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg",1420,1080,false],"2048x2048":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg",1420,1080,false],"trp-custom-language-flag":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru.jpg",16,12,false],"woocommerce_thumbnail":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru-300x228.jpg",300,228,true],"woocommerce_single":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru-600x456.jpg",600,456,true],"woocommerce_gallery_thumbnail":["https:\/\/fahrtauglich.ch\/wp-content\/uploads\/2024\/11\/Bimaru-100x100.jpg",100,100,true]},"rttpg_author":{"display_name":"fahrtauglich.ch","author_link":"https:\/\/fahrtauglich.ch\/fr\/blog\/author\/mintcream-quetzal-259960-hostingersite-com\/"},"rttpg_comment":0,"rttpg_category":null,"rttpg_excerpt":"Spielen Sie Sudoku online mit individuell einstellbarem Fehlerlimit. Unser adaptives Sudoku wird nach jedem Erfolg schwieriger.","_links":{"self":[{"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/pages\/4378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/comments?post=4378"}],"version-history":[{"count":71,"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/pages\/4378\/revisions"}],"predecessor-version":[{"id":8578,"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/pages\/4378\/revisions\/8578"}],"up":[{"embeddable":true,"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/pages\/1467"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/media\/4437"}],"wp:attachment":[{"href":"https:\/\/fahrtauglich.ch\/fr\/wp-json\/wp\/v2\/media?parent=4378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}