diff --git a/BinTree/src/main/java/Main.java b/BinTree/src/main/java/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..a939dc749395d5955a5964c6e3ca3f99f30fdde1 --- /dev/null +++ b/BinTree/src/main/java/Main.java @@ -0,0 +1,12 @@ + +public class Main { + public static void main(String[] args) { + + BinTreeNode btn = BinTreeNode.bin( new BinTreeNode(), "1", new BinTreeNode() ); + + BinTreeNode btn2 = BinTreeNode.bin( btn, "2", btn ); + + System.out.println( btn2.left().getNodeValue() ); + } + +} diff --git a/sth-backend/src/main/java/hdm/mi/sthbackend/controller/TournamentController.java b/sth-backend/src/main/java/hdm/mi/sthbackend/controller/TournamentController.java index 0185e761e1c0b6f459841365ca2225546357f8ac..4428bb10876d07702c033f402b94320737e897cb 100644 --- a/sth-backend/src/main/java/hdm/mi/sthbackend/controller/TournamentController.java +++ b/sth-backend/src/main/java/hdm/mi/sthbackend/controller/TournamentController.java @@ -2,11 +2,8 @@ package hdm.mi.sthbackend.controller; import hdm.mi.sthbackend.dto.PlayerDTO; -import hdm.mi.sthbackend.exeptions.MatchIdNotFoundException; +import hdm.mi.sthbackend.exeptions.*; import hdm.mi.sthbackend.dto.TeamDTO; -import hdm.mi.sthbackend.exeptions.PlayerIdNotFoundException; -import hdm.mi.sthbackend.exeptions.TeamIdNotFoundException; -import hdm.mi.sthbackend.exeptions.TournamentIdNotFoundException; import hdm.mi.sthbackend.model.Player; import hdm.mi.sthbackend.model.Team; import hdm.mi.sthbackend.model.Tournament; @@ -70,7 +67,7 @@ public class TournamentController { } @PatchMapping public UUID determineWinner(@PathVariable UUID tournamentId, - @PathVariable UUID matchId) throws TournamentIdNotFoundException, MatchIdNotFoundException { + @PathVariable UUID matchId) throws TournamentIdNotFoundException, MatchIdNotFoundException, WinnerNotDeterminedException { return service.determineWinner(tournamentId, matchId); } diff --git a/sth-backend/src/main/java/hdm/mi/sthbackend/exeptions/WinnerNotDeterminedException.java b/sth-backend/src/main/java/hdm/mi/sthbackend/exeptions/WinnerNotDeterminedException.java new file mode 100644 index 0000000000000000000000000000000000000000..3c15f2e3641dfdf3af0b9b77483addd4ac1f4390 --- /dev/null +++ b/sth-backend/src/main/java/hdm/mi/sthbackend/exeptions/WinnerNotDeterminedException.java @@ -0,0 +1,9 @@ +package hdm.mi.sthbackend.exeptions; + +import java.util.UUID; + +public class WinnerNotDeterminedException extends Exception{ + public WinnerNotDeterminedException(UUID match, UUID tournamentId) { + super(String.format("Winner not determined for Match %s in Tournament %s ", match.toString(), tournamentId.toString())); + } +} \ No newline at end of file diff --git a/sth-backend/src/main/java/hdm/mi/sthbackend/model/Match.java b/sth-backend/src/main/java/hdm/mi/sthbackend/model/Match.java index dbb97aac847b78a4c56542307c23039d2246df77..8041fd19e362850a7ff37b73a8d0be30189d02ef 100644 --- a/sth-backend/src/main/java/hdm/mi/sthbackend/model/Match.java +++ b/sth-backend/src/main/java/hdm/mi/sthbackend/model/Match.java @@ -20,7 +20,7 @@ public class Match { @Id private UUID matchId; - private Map<UUID, Number> teamScores; + private Map<UUID, Integer> teamScores; @Setter private UUID winnerTeamId; diff --git a/sth-backend/src/main/java/hdm/mi/sthbackend/service/TournamentService.java b/sth-backend/src/main/java/hdm/mi/sthbackend/service/TournamentService.java index 89a57655697e43e1cd28db1d0dceed978b3e7525..53178368abef5e426ad5c7806ae77b65e946660e 100644 --- a/sth-backend/src/main/java/hdm/mi/sthbackend/service/TournamentService.java +++ b/sth-backend/src/main/java/hdm/mi/sthbackend/service/TournamentService.java @@ -2,10 +2,7 @@ package hdm.mi.sthbackend.service; import hdm.mi.sthbackend.dto.PlayerDTO; import hdm.mi.sthbackend.dto.TeamDTO; -import hdm.mi.sthbackend.exeptions.MatchIdNotFoundException; -import hdm.mi.sthbackend.exeptions.PlayerIdNotFoundException; -import hdm.mi.sthbackend.exeptions.TeamIdNotFoundException; -import hdm.mi.sthbackend.exeptions.TournamentIdNotFoundException; +import hdm.mi.sthbackend.exeptions.*; import hdm.mi.sthbackend.model.Match; import hdm.mi.sthbackend.model.Player; import hdm.mi.sthbackend.model.Team; @@ -147,7 +144,7 @@ public class TournamentService { return tournament; } - public UUID determineWinner (UUID tournamentId, UUID matchId) throws TournamentIdNotFoundException, MatchIdNotFoundException{ + public UUID determineWinner (UUID tournamentId, UUID matchId) throws TournamentIdNotFoundException, MatchIdNotFoundException, WinnerNotDeterminedException { Tournament tournament = tournamentRepository.findById(tournamentId) .orElseThrow(() -> new TournamentIdNotFoundException(tournamentId)); @@ -158,9 +155,9 @@ public class TournamentService { .orElseThrow(() -> new MatchIdNotFoundException(matchId)); UUID winnerTeamId = match.getTeamScores().entrySet().stream() - .max(Comparator.<Map.Entry<UUID, Number>, Double>comparing(entry -> entry.getValue().doubleValue())) + .max(Comparator.comparing(Map.Entry::getKey)) .map(Map.Entry::getKey) - .orElse(null); + .orElseThrow(() -> new WinnerNotDeterminedException(matchId,tournamentId)); match.setWinnerTeamId(winnerTeamId); tournamentRepository.save(tournament); @@ -183,6 +180,24 @@ public class TournamentService { log.debug("Team " + teamId + " assign to Match " + matchId + " in Tournament " + tournamentId); } + + public void updateTeamScore(UUID tournamentId, UUID matchId, UUID teamId, int newScore)throws TournamentIdNotFoundException, MatchIdNotFoundException, TeamIdNotFoundException{ + Tournament tournament = tournamentRepository.findById(tournamentId) + .orElseThrow(() -> new TournamentIdNotFoundException(tournamentId)); + + Match match = tournament.getMatches().stream() + .filter(m -> m.getMatchId().equals(matchId)) + .findFirst() + .orElseThrow(() -> new MatchIdNotFoundException(matchId)); + + if (!match.getTeamScores().containsKey(teamId)) { + throw new TeamIdNotFoundException(teamId); + } + match.getTeamScores().put(teamId, newScore); + tournamentRepository.save(tournament); + log.debug("Score von Team " + teamId + " auf " + newScore + " geupdatet"); + } + public Tournament getTournament(UUID tournamentId) throws TournamentIdNotFoundException { Tournament tournament = tournamentRepository.findById(tournamentId) .orElseThrow(() -> new TournamentIdNotFoundException(tournamentId)); @@ -201,9 +216,11 @@ public class TournamentService { /* Weitere Methoden: - Gewinner bestimmen, defineWinner() - Teams Matches zuordnen, - + UpdateTeamScore Marius + Tunier beenden + GetTournament Leon + DeleteTournament Leon + User Mattis */ diff --git a/sth-frontend/src/App.jsx b/sth-frontend/src/App.jsx index a3a7e253f6d522fd8b76b4ded6dc6b205f7e7d8f..44798e3def41b80c43e008ad69853579271fb8af 100644 --- a/sth-frontend/src/App.jsx +++ b/sth-frontend/src/App.jsx @@ -1,7 +1,6 @@ import Navbar from "./layouts/Navbar"; import {Outlet} from "react-router-dom"; import "./index.css" -import Test from "./components/Test"; function App() { return ( diff --git a/sth-frontend/src/components/Test.jsx b/sth-frontend/src/components/Test.jsx deleted file mode 100644 index daad32d996b81c00e3ff494e81920257c8e450e2..0000000000000000000000000000000000000000 --- a/sth-frontend/src/components/Test.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Test({style}) { - return ( - <div className={`font-bold ${style}`}> - <h1>Test</h1> - </div> - ) -} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/components/BracketingRound.jsx b/sth-frontend/src/features/tournament/components/BracketingRound.jsx new file mode 100644 index 0000000000000000000000000000000000000000..b20d07cadd565f0074a5a9d2bd94be21d671cabc --- /dev/null +++ b/sth-frontend/src/features/tournament/components/BracketingRound.jsx @@ -0,0 +1,16 @@ +import Match from "./Match"; + +export default function BracketingRound({matchesNum}) { + const matches = []; + + for (let i = 0; i < matchesNum; i++) { + matches.push(<Match style={i + 1} key={i} />) + + } + + return( + <div className={'flex-col justify-around m-3 hover:shadow flex'}> + {matches} + </div> + ) +} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/components/BracketingTree.jsx b/sth-frontend/src/features/tournament/components/BracketingTree.jsx new file mode 100644 index 0000000000000000000000000000000000000000..1e5c15495556a5bf4460870e1a6a4fb98919c694 --- /dev/null +++ b/sth-frontend/src/features/tournament/components/BracketingTree.jsx @@ -0,0 +1,16 @@ +import BracketingRound from "./BracketingRound"; + +export default function BracketingTree({roundsNum}) { + const matches = roundsNum; + const rounds = []; + roundsNum = Math.log2(roundsNum) + 1 + for (let i = 0; i < roundsNum; i++) { + rounds.push(<BracketingRound key={i} matchesNum={matches / Math.pow(2, i)} />) + } + + return ( + <div className={'flex flex-row justify-center'}> + {rounds} + </div> + ) +} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/components/Match.jsx b/sth-frontend/src/features/tournament/components/Match.jsx new file mode 100644 index 0000000000000000000000000000000000000000..c988981387fd9ba17f719a18729b5d229f1e04bb --- /dev/null +++ b/sth-frontend/src/features/tournament/components/Match.jsx @@ -0,0 +1,18 @@ +import Team from "./Team"; +import {useState} from "react"; + +export default function Match() { + + const [teamOneScore, setTeamOneScore] = useState(0); + const [teamTwoScore, setTeamTwoScore] = useState(0); + + const teamOneWinning = teamOneScore > teamTwoScore; + const teamTwoWinning = teamTwoScore > teamOneScore; + + return( + <div className={`m-2 hover:shadow-lg border-4 rounded-xl`}> + <Team name={'Lucca'} score={teamOneScore} setScore={setTeamOneScore} winning={teamOneWinning}/> + <Team name={'Jonas'} score={teamTwoScore} setScore={setTeamTwoScore} winning={teamTwoWinning}/> + </div> + ) +} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/components/Score.jsx b/sth-frontend/src/features/tournament/components/Score.jsx new file mode 100644 index 0000000000000000000000000000000000000000..954cdc2f3e071c4da23bd4713d78514350abe82b --- /dev/null +++ b/sth-frontend/src/features/tournament/components/Score.jsx @@ -0,0 +1,13 @@ +import {useState} from "react"; + +export default function Score({score, setScore}) { + + + return( + <div> + <button className={'w-6 rounded hover:bg-gray-100 bg-gray-300 mr-1'} onClick={() => setScore(score - 1)}>-</button> + <input className={'w-6'} type={"text"} value={score}/> + <button className={'w-6 rounded hover:bg-gray-100 bg-gray-300 ml-1'} onClick={() => setScore(score + 1)}>+</button> + </div> + ) +} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/components/Team.jsx b/sth-frontend/src/features/tournament/components/Team.jsx new file mode 100644 index 0000000000000000000000000000000000000000..bb762e829932c9011db904d134a8d618f378ad93 --- /dev/null +++ b/sth-frontend/src/features/tournament/components/Team.jsx @@ -0,0 +1,12 @@ +import {useState} from "react"; +import Score from "./Score"; + +export default function Team({name, score, setScore, winning}) { + + return( + <div className={'flex w-40 m-3'}> + <div className={`mr-4 rounded flex justify-center ` + (winning ? 'bg-green-300' : 'bg-gray-100')}>{name}</div> + <Score setScore={setScore} score={score}/> + </div> + ) +} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/components/Tournament.jsx b/sth-frontend/src/features/tournament/components/Tournament.jsx new file mode 100644 index 0000000000000000000000000000000000000000..6f0858c8a3551163620b96274b93b2239716a74f --- /dev/null +++ b/sth-frontend/src/features/tournament/components/Tournament.jsx @@ -0,0 +1,12 @@ +import BracketingTree from "./BracketingTree"; + + +export default function Tournament() { + + + return( + <div> + <BracketingTree roundsNum={4}/> + </div> + ) +} \ No newline at end of file diff --git a/sth-frontend/src/features/tournament/index.jsx b/sth-frontend/src/features/tournament/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..139597f9cb07c5d48bed18984ec4747f4b4f3438 --- /dev/null +++ b/sth-frontend/src/features/tournament/index.jsx @@ -0,0 +1,2 @@ + + diff --git a/sth-frontend/src/index.jsx b/sth-frontend/src/index.jsx index 50e232e6e8dd7107266ed4e5f3b74f0dd1e2d397..e81e3b13307d00008f109996563b63d13a69104b 100644 --- a/sth-frontend/src/index.jsx +++ b/sth-frontend/src/index.jsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import {RouterProvider} from "react-router-dom"; -import router from "./router"; +import router from "./utils/router"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( diff --git a/sth-frontend/src/router.jsx b/sth-frontend/src/utils/router.jsx similarity index 72% rename from sth-frontend/src/router.jsx rename to sth-frontend/src/utils/router.jsx index 4e67c2de702aad83af0e2a4a0214fb2e07e945c9..e5eb6de3abc64ddc4656d0190ec3a01de4cc4331 100644 --- a/sth-frontend/src/router.jsx +++ b/sth-frontend/src/utils/router.jsx @@ -1,6 +1,6 @@ import {createBrowserRouter} from "react-router-dom"; -import Tournament from "./pages/Tournament"; -import App from "./App"; +import Tournament from "../features/tournament/components/Tournament"; +import App from "../App"; const router = createBrowserRouter([ { @@ -10,8 +10,6 @@ const router = createBrowserRouter([ {path: "", element: <Tournament/>}, ] }, - - ])