{"id":9601,"date":"2026-04-03T18:02:14","date_gmt":"2026-04-03T16:02:14","guid":{"rendered":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/?page_id=9601"},"modified":"2026-04-03T18:05:56","modified_gmt":"2026-04-03T16:05:56","slug":"play-it","status":"publish","type":"page","link":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/play-it\/","title":{"rendered":"Play it!"},"content":{"rendered":"\t\n\n\t\n<style>\n.arb-game{max-width:420px;margin:20px auto;font-family:sans-serif;text-align:center;position:relative;touch-action: none}\n.arb-grid{display:grid;gap:10px;margin-top:15px;position:relative;z-index:1;box-sizing:border-box}\n.arb-cell{background:#f3f3f3;padding:28px 0;border-radius:10px;font-size:1.4rem;font-weight:bold;user-select:none;position:relative;z-index:2;box-sizing:border-box;line-height:1.2}\n.arb-cell.active{background:#a4be49;color:#fff}\n.arb-cell.locked{background:#a4be49;color:#fff;opacity:0.7}\n.arb-target{font-size:1.1rem;color:#555}\n.arb-result{margin-top:10px;font-weight:bold}\n.arb-canvas{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:0}\n<\/style>\n\n<div class=\"arb-game\" id=\"arbGame\">\n  <canvas class=\"arb-canvas\" id=\"lineCanvas\"><\/canvas>\n\t\n <div class=\"arb-target\">\n  \ud83c\udf41 <span id=\"targetName\">Vogel-Kir\u00adsche, S\u00fc\u00df-Kir\u00adsche<\/span>\n  <br>\n  \ud83e\uddea <span id=\"scientificName\">Pru\u00adnus avi\u00adum (L.)<\/span>\n<\/div>\n  <div class=\"arb-grid\" id=\"grid\"><\/div>\n  <div class=\"arb-result\" id=\"result\"><\/div>\n<\/div>\n\n<script>\n(function(){\n  \n  const word = \"prunusavium(l.)\";\n  const displayName = \"Vogel-Kirsche, S\u00fc\u00df-Kirsche\";\n\t\n\tconsole.log(\"Scientific slug:\", word);\nconsole.log(\"German display name:\", displayName);\t\n\t\n\t\n\tdocument.getElementById(\"targetName\").textContent = displayName;\n  const targetWords = [word];\n\tif(!word || word.length < 2){\n  console.error(\"Word kaputt:\", word);\n  return;\n}\n\n  const gridEl = document.getElementById(\"grid\");\n  const result = document.getElementById(\"result\");\n  const canvas = document.getElementById(\"lineCanvas\");\n  const ctx = canvas.getContext(\"2d\");\n  let path = [], currentWord = \"\";\n\n  \/\/ ------------------------\n  \/\/ Grid generieren\n  \/\/ ------------------------\n  function generateWordGrid(word) {\n    const letters = word.toUpperCase().split(\"\");\n    const n = Math.ceil(Math.sqrt(letters.length));\n    const grid = Array.from({length: n}, ()=>Array(n).fill(null));\n    const dirs = [[0,1],[1,0],[0,-1],[-1,0],[1,1],[1,-1],[-1,1],[-1,-1]];\n\n    function canPlace(x,y){ return x>=0 && y>=0 && x<n && y<n && grid[y][x]===null; }\n\n    function placeLetter(index,x,y){\n      if(index===letters.length) return true;\n      const shuffledDirs = dirs.sort(()=>Math.random()-0.5);\n      for(const [dx,dy] of shuffledDirs){\n        const nx = x+dx, ny = y+dy;\n        if(canPlace(nx,ny)){\n          grid[ny][nx] = letters[index];\n          if(placeLetter(index+1,nx,ny)) return true;\n          grid[ny][nx] = null;\n        }\n      }\n      return false;\n    }\n\n    const startX = Math.floor(Math.random()*n);\n    const startY = Math.floor(Math.random()*n);\n    grid[startY][startX] = letters[0];\n    if(!placeLetter(1,startX,startY)) console.log(\"Konnte Layout nicht finden\");\n    return grid;\n  }\n\n  const gridArray = generateWordGrid(word);\n  const rows = gridArray.length;\n  const cols = gridArray[0].length;\n  gridEl.style.gridTemplateColumns = `repeat(${cols},1fr)`;\n\n  \/\/ ------------------------\n  \/\/ Grid rendern\n  \/\/ ------------------------\n  for(let r=0;r<rows;r++){\n    for(let c=0;c<cols;c++){\n      const l = gridArray[r][c];\n      const div = document.createElement(\"div\");\n      div.className = \"arb-cell\";\n      div.textContent = l?l:\"\";\n      if(l) div.dataset.letter = l;\n      gridEl.appendChild(div);\n    }\n  }\n\n  \/\/ ------------------------\n  \/\/ Canvas Setup\n  \/\/ ------------------------\n  function resizeCanvas(){\n    const rect = gridEl.getBoundingClientRect();\n    const dpr = window.devicePixelRatio||1;\n    canvas.width = rect.width*dpr;\n    canvas.height = rect.height*dpr;\n    canvas.style.width = rect.width+\"px\";\n    canvas.style.height = rect.height+\"px\";\n    ctx.setTransform(1,0,0,1,0,0);\n    ctx.scale(dpr,dpr);\n  }\n  requestAnimationFrame(resizeCanvas);\n  window.addEventListener('resize',resizeCanvas);\n\n  function getCellIndex(cell){ return Array.from(gridEl.children).indexOf(cell); }\n  function areAdjacent(i1,i2){ \n    const r1=Math.floor(i1\/cols), c1=i1%cols;\n    const r2=Math.floor(i2\/cols), c2=i2%cols;\n    const dr=r2-r1, dc=c2-c1;\n    return Math.abs(dr)<=1 && Math.abs(dc)<=1;\n  }\n  function getCellCenter(cell){\n    const cellRect = cell.getBoundingClientRect();\n    const canvasRect = canvas.getBoundingClientRect();\n    return {x:cellRect.left-canvasRect.left+cellRect.width\/2,\n            y:cellRect.top -canvasRect.top +cellRect.height\/2};\n  }\n  function drawPath(){\n    ctx.clearRect(0,0,canvas.width,canvas.height);\n    if(path.length<1) return;\n    ctx.strokeStyle=\"#FF0000\";\n    ctx.lineWidth=4;\n    ctx.lineCap=\"round\";\n    ctx.lineJoin=\"round\";\n    ctx.beginPath();\n    path.forEach((p,i)=>{\n      const pos=getCellCenter(p.el);\n      if(i===0) ctx.moveTo(pos.x,pos.y);\n      else ctx.lineTo(pos.x,pos.y);\n    });\n    ctx.stroke();\n  }\n\n  \/\/ ------------------------\n  \/\/ Touch \/ Mouse\n  \/\/ ------------------------\n  let isTouching=false;\n  gridEl.addEventListener(\"touchstart\",e=>{isTouching=true; path=[]; currentWord=\"\"; drawPath();});\n\t\ngridEl.addEventListener(\"touchmove\", e => {\n    e.preventDefault();\n    if (!isTouching) return;\n\n    const touch = e.touches[0];\n    const el = document.elementFromPoint(touch.clientX, touch.clientY);\n\n    if (!el || !el.classList.contains(\"arb-cell\") || !el.dataset.letter || el.classList.contains(\"locked\"))\n        return;\n\n    const index = getCellIndex(el);\n\n    if (path.length === 0) {\n        \/\/ Startpunkt\n        path.push({ el, index });\n        el.classList.add(\"active\");\n        currentWord += el.dataset.letter.toLowerCase();\n    } else {\n        const head = path[path.length - 1];\n\n        if (index === head.index) return; \/\/ gleiche Zelle nochmal ignorieren\n\n        if (path.length >= 2 && index === path[path.length - 2].index) {\n            \/\/ R\u00fcckw\u00e4rts ziehen\n            const removed = path.pop();\n            removed.el.classList.remove(\"active\");\n            currentWord = currentWord.slice(0, -1);\n        } else if (areAdjacent(head.index, index) && !path.some(p => p.index === index)) {\n            \/\/ Vorw\u00e4rts ziehen auf freie Zelle\n            path.push({ el, index });\n            el.classList.add(\"active\");\n            currentWord += el.dataset.letter.toLowerCase();\n        }\n        \/\/ Ansonsten: nicht angrenzend oder schon im Pfad -> ignorieren\n    }\n\n    drawPath();\n\n    \/\/ Sofort-Check f\u00fcr korrektes Wort\n    if (targetWords.includes(currentWord)) {\n        result.textContent = \"\u2705 \" + currentWord;\n    } else {\n        result.textContent = \"\";\n    }\n}, { passive: false });\n\t\n\t\n  gridEl.addEventListener(\"touchend\",()=>{\n    isTouching=false;\n    if(targetWords.includes(currentWord)) path.forEach(p=>p.el.classList.add(\"locked\"));\n    path.forEach(p=>p.el.classList.remove(\"active\"));\n    path=[]; currentWord=\"\"; drawPath();\n  });\n})();\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"wp_typography_post_enhancements_disabled":false,"ocean_post_layout":"full-screen","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"off","ocean_display_header":"on","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"on","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"off","ocean_display_footer_bottom":"off","ocean_custom_footer_template":"","footnotes":""},"class_list":["post-9601","page","type-page","status-publish","hentry","entry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/pages\/9601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/comments?post=9601"}],"version-history":[{"count":3,"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/pages\/9601\/revisions"}],"predecessor-version":[{"id":9605,"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/pages\/9601\/revisions\/9605"}],"wp:attachment":[{"href":"https:\/\/www2.hu-berlin.de\/insidespaetharboretum\/wp-json\/wp\/v2\/media?parent=9601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}