Update 2025-04-13_16:49:18
This commit is contained in:
75
static/app.js
Normal file
75
static/app.js
Normal file
@ -0,0 +1,75 @@
|
||||
let currentWord = [];
|
||||
let attemptsLeft = 0;
|
||||
|
||||
const wordDisplay = document.getElementById("word");
|
||||
const input = document.getElementById("input");
|
||||
const feedback = document.getElementById("feedback");
|
||||
const attemptsDisplay = document.getElementById("attempts");
|
||||
const startBtn = document.getElementById("start");
|
||||
const topicLabel = document.createElement("div");
|
||||
topicLabel.id = "topic-label";
|
||||
topicLabel.style.marginTop = "1rem";
|
||||
topicLabel.style.fontWeight = "bold";
|
||||
wordDisplay.parentElement.insertBefore(topicLabel, wordDisplay);
|
||||
|
||||
function renderWord() {
|
||||
wordDisplay.textContent = currentWord.join(" ");
|
||||
attemptsDisplay.textContent = `Versuche übrig: ${attemptsLeft}`;
|
||||
}
|
||||
|
||||
async function startGame() {
|
||||
const res = await fetch("/api/start", {
|
||||
method: "POST"
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
if (!data.word) {
|
||||
feedback.textContent = "❌ Fehler: Keine gültige Antwort vom Server.";
|
||||
return;
|
||||
}
|
||||
|
||||
currentWord = data.word;
|
||||
attemptsLeft = data.attempts;
|
||||
topicLabel.textContent = `🧠 Thema: ${data.topic || '(unbekannt)'}`;
|
||||
feedback.textContent = `Spiel gestartet (${data.source})`;
|
||||
renderWord();
|
||||
input.focus();
|
||||
}
|
||||
|
||||
async function guessLetter() {
|
||||
if (!currentWord.length) {
|
||||
feedback.textContent = "❌ Bitte zuerst ein Spiel starten!";
|
||||
return;
|
||||
}
|
||||
|
||||
const letter = input.value.trim().toLowerCase();
|
||||
if (!letter || letter.length !== 1) return;
|
||||
|
||||
const res = await fetch(`/api/guess/${letter}`, { method: "POST" });
|
||||
const data = await res.json();
|
||||
|
||||
if (!data.word) {
|
||||
feedback.textContent = "❌ Kein aktives Spiel – bitte erst starten!";
|
||||
return;
|
||||
}
|
||||
|
||||
currentWord = data.word;
|
||||
attemptsLeft = data.attempts;
|
||||
|
||||
let msg = data.correct_this_turn > 0 ? "✅" : "❌";
|
||||
if (data.status === "won") {
|
||||
msg += " 🎉 Gewonnen!";
|
||||
} else if (data.status === "lost") {
|
||||
msg += ` 💥 Verloren! ⇨ ${data.target} ⇦`;
|
||||
}
|
||||
feedback.textContent = msg;
|
||||
renderWord();
|
||||
input.value = "";
|
||||
input.focus();
|
||||
}
|
||||
|
||||
startBtn.addEventListener("click", startGame);
|
||||
input.addEventListener("keypress", (e) => {
|
||||
if (e.key === "Enter") guessLetter();
|
||||
});
|
||||
|
27
static/index.html
Normal file
27
static/index.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>WordCraze</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>🧠 WordCraze</h1>
|
||||
|
||||
<section class="controls">
|
||||
<button id="start">Spiel starten</button>
|
||||
</section>
|
||||
|
||||
<section class="game">
|
||||
<div id="word" class="word">_ _ _</div>
|
||||
<input id="input" type="text" maxlength="1">
|
||||
<div id="feedback" class="feedback"></div>
|
||||
<div id="attempts" class="attempts">Versuche übrig: 8</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script type="module" src="/static/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
48
static/ollama.js
Normal file
48
static/ollama.js
Normal file
@ -0,0 +1,48 @@
|
||||
// ollama.js – WordCraze: KI-Unterstützung über Ollama
|
||||
|
||||
export async function getWordsFromOllama(length, category) {
|
||||
try {
|
||||
const response = await fetch("https://at1.dynproxy.net/api/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer sk-d0e3a491b19c435a975b234969298cd0"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: "gemma3:1b",
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: `Gib ein zufälliges Thema an (z. B. Tiere, Essen, Möbel) und dann ein Array mit 5 Wörtern dieses Themas mit 3 bis 6 Buchstaben im JSON-Format. Nur das Array, keine Einleitung.`
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: "Einfaches Thema und 5 passende Wörter mit 3–6 Buchstaben im JSON-Array."
|
||||
}
|
||||
],
|
||||
stream: false
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("Ollama API Error:", response.status);
|
||||
return [];
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const raw = data.choices?.[0]?.message?.content || "[]";
|
||||
const clean = raw.trim().replace(/^```json\s*/i, "").replace(/```$/, "");
|
||||
try {
|
||||
const parsed = JSON.parse(clean);
|
||||
return parsed;
|
||||
} catch (e) {
|
||||
console.warn("Ollama hat kein parsebares JSON geliefert:", raw);
|
||||
return [];
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen von Wörtern via Ollama:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
71
static/style.css
Normal file
71
static/style.css
Normal file
@ -0,0 +1,71 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
background: #f9f9f9;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.controls label,
|
||||
.controls button {
|
||||
font-size: 1rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.game {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.word {
|
||||
font-size: 2rem;
|
||||
letter-spacing: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
font-size: 1.5rem;
|
||||
text-align: center;
|
||||
padding: 0.3rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.feedback {
|
||||
margin-top: 1rem;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.attempts {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
|
Reference in New Issue
Block a user