Annpassung challenge-Logik, beide Spieler erhalten den selben Text

This commit is contained in:
DST81 2026-05-31 14:53:16 +02:00
parent 5199b32471
commit 96175ae699
3 changed files with 150 additions and 11 deletions

View File

@ -136,9 +136,9 @@
<script src="js/login.js"></script>
<script src="js/leaderboard.js"></script>
<script src="js/scores.js"></script>
<script src="js/messages.js?v=challenge-flow-20260528f"></script>
<script src="js/messages.js?v=challenge-flow-20260531b"></script>
<!--Navigation Script -->
<script src="js/play.js?v=challenge-flow-20260528d"></script>
<script src="js/play.js?v=challenge-flow-20260531b"></script>
<script src="js/navigation.js?v=challenge-flow-20260528"></script>
</body>
</html>

View File

@ -4,11 +4,97 @@
const MESSAGE_POLL_INTERVAL_MS = 30000;
const ACTIVE_CHALLENGE_STORAGE_KEY = "loremIpsumActiveChallenge";
const CHALLENGE_DATA_PREFIX = "[[loremIpsumChallenge:";
const CHALLENGE_TEXT_PARTS = {
subjects: [
"Der flinke Entwickler",
"Die neugierige Studentin",
"Ein mueder Professor",
"Das kleine Frontend",
"Der mutige Browser",
"Eine schlaue Funktion",
"Der vergessliche Server",
"Die kreative Gruppe",
],
actions: [
"sortiert leise",
"debuggt geduldig",
"vergleicht heimlich",
"speichert vorsichtig",
"rendert ploetzlich",
"zaehlt konzentriert",
"testet neugierig",
"kompiliert langsam",
],
objects: [
"sieben blaue Buttons",
"drei lange Variablen",
"neun goldene Woerter",
"vier kaputte Formulare",
"acht schnelle Requests",
"zwei leuchtende Karten",
"fuenf stille Fehlermeldungen",
"sechs winzige Icons",
],
places: [
"im hellen Dashboard",
"unter dem dunklen Navbar",
"neben dem alten Footer",
"zwischen Login und Leaderboard",
"vor dem ersten Kaffee",
"waehrend der Lernphase",
"hinter dem lokalen Server",
"mitten im Semesterprojekt",
],
endings: [
"Danach lacht der Code, weil alles endlich funktioniert.",
"Am Ende merkt sich niemand die Semikolons, aber alle die Punkte.",
"Kurz darauf blinkt die Konsole und behauptet, sie sei unschuldig.",
"Spaeter landet der Score im Ranking und wartet auf Applaus.",
"Dabei bleibt die Seite ruhig, obwohl der Timer dramatisch tickt.",
"Zum Schluss gewinnt, wer die Woerter sauber in Reihenfolge bringt.",
],
};
let currentMessages = [];
let currentUsers = [];
let messagePollingInterval = null;
function getRandomChallengeTextPart(items) {
return items[Math.floor(Math.random() * items.length)];
}
function generateChallengeText() {
const firstSentence =
[
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.subjects),
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.actions),
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.objects),
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.places),
].join(" ") + ".";
const secondSentence =
[
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.subjects),
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.actions),
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.objects),
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.places),
].join(" ") + ".";
return firstSentence +
" " +
secondSentence +
" " +
getRandomChallengeTextPart(CHALLENGE_TEXT_PARTS.endings);
}
function buildEmbeddedChallengeText(challengeData, displayText) {
return CHALLENGE_DATA_PREFIX +
JSON.stringify(challengeData) +
"]]" +
"\n" +
displayText;
}
function getAuth() {
if (!window.AppAuth || typeof window.AppAuth.getAuth !== "function") {
return null;
@ -53,12 +139,24 @@
function normalizeMessage(message) {
// Das Backend und unser Nachrichten-Fallback liefern Challenge-Daten leicht unterschiedlich.
// Hier werden beide Formen in ein einheitliches Message-Objekt gebracht.
const embeddedChallenge = extractEmbeddedChallenge(message.text ?? "");
const textCandidates = [
message.text,
message.content,
message.message,
message.challenge?.text,
message.result?.text,
];
const rawText = textCandidates.find((value) => String(value ?? "").includes(CHALLENGE_DATA_PREFIX))
?? textCandidates.find((value) => value !== null && value !== undefined)
?? "";
const embeddedChallenge = extractEmbeddedChallenge(rawText);
const type = message.type ?? MESSAGE_TYPE_CHALLENGE;
const challenge = message.challenge
const backendChallenge = message.challenge
?? message.result
?? embeddedChallenge.challenge
?? (type === MESSAGE_TYPE_CHALLENGE || type === MESSAGE_TYPE_CHALLENGE_RESULT ? message : null);
const challenge = embeddedChallenge.challenge
? { ...(backendChallenge ?? {}), ...embeddedChallenge.challenge }
: backendChallenge;
return {
id: message.id,
@ -76,14 +174,15 @@
// Fallback fuer Challenge-Daten, die im Nachrichtentext mitgesendet werden.
// So koennen wir bestehende Message-Endpunkte nutzen, ohne neue Backend-Felder zu verlangen.
const rawText = String(text ?? "");
if (!rawText.startsWith(CHALLENGE_DATA_PREFIX)) {
const startIndex = rawText.indexOf(CHALLENGE_DATA_PREFIX);
if (startIndex === -1) {
return {
text: rawText,
challenge: null,
};
}
const endIndex = rawText.indexOf("]]");
const endIndex = rawText.indexOf("]]", startIndex);
if (endIndex === -1) {
return {
text: rawText,
@ -91,8 +190,11 @@
};
}
const json = rawText.slice(CHALLENGE_DATA_PREFIX.length, endIndex);
const displayText = rawText.slice(endIndex + 2).trim();
const json = rawText.slice(startIndex + CHALLENGE_DATA_PREFIX.length, endIndex);
const displayText = (
rawText.slice(0, startIndex) +
rawText.slice(endIndex + 2)
).trim();
try {
return {
@ -137,6 +239,13 @@
?? null;
}
function getChallengeText(challenge) {
return challenge?.challengeText
?? challenge?.roundText
?? challenge?.textToRemember
?? null;
}
function hasScore(value) {
return value !== null && value !== undefined && value !== "";
}
@ -254,6 +363,7 @@
challenger: challenger,
opponent: otherUser,
opponentScore: role === "challenger" ? getOpponentScore(challenge) : null,
challengeText: getChallengeText(challenge),
ownUsername: auth?.username ?? "",
}),
);
@ -767,11 +877,17 @@
return;
}
const challengeText = generateChallengeText();
const challengeMessage = buildEmbeddedChallengeText(
{ challengeText: challengeText },
text,
);
const result = await challengeService.postChallenge(
auth.username,
auth.password,
recipient,
text,
challengeMessage,
);
if (!result.ok) {

View File

@ -135,7 +135,7 @@
gameStatus.style.color = "#1b1b2f";
}
currentGameText = generateGameText();
currentGameText = getRoundText();
if (targetTextDisplay) targetTextDisplay.textContent = currentGameText;
// Nach Ablauf des Timers wird automatisch zur Eingabe gewechselt.
@ -318,6 +318,27 @@
return hasActiveChallenge() && activeChallenge.role === "opponent";
}
function writeActiveChallenge(challenge) {
sessionStorage.setItem(ACTIVE_CHALLENGE_STORAGE_KEY, JSON.stringify(challenge));
}
function getRoundText() {
// Bei Challenges spielen beide User mit demselben Text aus dem Challenge-Kontext.
// Falls alte Challenges diesen Text noch nicht haben, gibt es weiterhin einen lokalen Fallback.
if (!activeChallenge) {
return generateGameText();
}
if (typeof activeChallenge.challengeText === "string" && activeChallenge.challengeText.trim()) {
return activeChallenge.challengeText;
}
const generatedText = generateGameText();
activeChallenge.challengeText = generatedText;
writeActiveChallenge(activeChallenge);
return generatedText;
}
function showScoreSaveFeedback(message, type) {
if (!scoreSaveFeedback) return;
@ -534,6 +555,7 @@
challenger: activeChallenge.challenger,
opponent: auth.username,
opponentScore: scoreData.score,
challengeText: scoreData.text,
};
const messageText =
@ -617,6 +639,7 @@
opponent: activeChallenge.opponent,
challengerScore: scoreData.score,
opponentScore: opponentScore,
challengeText: scoreData.text,
winner: winner,
};