88 lines
3.5 KiB
Java
88 lines
3.5 KiB
Java
package com.example.mindflux.controller;
|
|
|
|
import com.example.mindflux.dto.*;
|
|
import com.example.mindflux.service.TechtacularService;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.security.Principal;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
import jakarta.servlet.http.HttpSession;
|
|
|
|
/** Spieler-API für TechTacular: Board laden, Antwort prüfen, Runde abschließen. */
|
|
@RestController
|
|
@RequestMapping("/api/techtacular")
|
|
public class TechtacularApiController {
|
|
|
|
private static final String JOKER_USED = "techtacular.fiftyFiftyUsed";
|
|
private static final String HINTED_QUESTION_IDS = "techtacular.hintedQuestionIds";
|
|
|
|
private final TechtacularService techtacularService;
|
|
|
|
public TechtacularApiController(TechtacularService techtacularService) {
|
|
this.techtacularService = techtacularService;
|
|
}
|
|
|
|
/** exclude = komma-separierte Frage-IDs der Vorrunde, die möglichst nicht erneut kommen sollen. */
|
|
@GetMapping("/board")
|
|
public TechtacularBoardView board(@RequestParam(required = false) String exclude, HttpSession session) {
|
|
// Ein neues Board beginnt immer eine neue Runde mit genau einem Joker.
|
|
session.removeAttribute(JOKER_USED);
|
|
session.removeAttribute(HINTED_QUESTION_IDS);
|
|
return techtacularService.buildBoard(parseIds(exclude));
|
|
}
|
|
|
|
private Set<Long> parseIds(String csv) {
|
|
Set<Long> ids = new HashSet<>();
|
|
if (csv != null && !csv.isBlank()) {
|
|
for (String part : csv.split(",")) {
|
|
try {
|
|
ids.add(Long.parseLong(part.trim()));
|
|
} catch (NumberFormatException ignored) {
|
|
// ungültige IDs einfach überspringen
|
|
}
|
|
}
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
@PostMapping("/answer")
|
|
public AnswerResult answer(@RequestBody AnswerRequest request, HttpSession session) {
|
|
// Das Client-Flag dient der UI und dem Finish-Payload. Ob die Punkte halbiert
|
|
// werden, entscheidet jedoch allein der serverseitige Rundenzustand.
|
|
boolean validHint = hintedQuestionIds(session).contains(request.getQuestionId());
|
|
return techtacularService.checkAnswer(request.getQuestionId(), request.getAnswerId(), validHint);
|
|
}
|
|
|
|
/** Liefert zwei eliminierbare, garantiert falsche Antworten ohne die Loesung offenzulegen. */
|
|
@GetMapping("/hint")
|
|
public FiftyFiftyHint hint(@RequestParam Long questionId, HttpSession session) {
|
|
if (Boolean.TRUE.equals(session.getAttribute(JOKER_USED))) {
|
|
return new FiftyFiftyHint(java.util.List.of());
|
|
}
|
|
|
|
FiftyFiftyHint hint = techtacularService.fiftyFifty(questionId);
|
|
if (!hint.removeAnswerIds().isEmpty()) {
|
|
session.setAttribute(JOKER_USED, true);
|
|
Set<Long> hinted = new HashSet<>();
|
|
hinted.add(questionId);
|
|
session.setAttribute(HINTED_QUESTION_IDS, hinted);
|
|
}
|
|
return hint;
|
|
}
|
|
|
|
@PostMapping("/finish")
|
|
public TechtacularResult finish(@RequestBody FinishRequest request, Principal principal, HttpSession session) {
|
|
TechtacularResult result = techtacularService.finish(principal.getName(), request, hintedQuestionIds(session));
|
|
session.removeAttribute(JOKER_USED);
|
|
session.removeAttribute(HINTED_QUESTION_IDS);
|
|
return result;
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private Set<Long> hintedQuestionIds(HttpSession session) {
|
|
Object value = session.getAttribute(HINTED_QUESTION_IDS);
|
|
return value instanceof Set<?> ? (Set<Long>) value : Set.of();
|
|
}
|
|
}
|