diff --git a/card-game/build.gradle b/card-game/build.gradle
deleted file mode 100644
index a85e5c54..00000000
--- a/card-game/build.gradle
+++ /dev/null
@@ -1,123 +0,0 @@
-plugins {
- id "java"
- id "org.openjfx.javafxplugin" version "0.0.13"
- id "com.github.johnrengelman.shadow" version "7.0.0"
-}
-
-configurations {
- internal
- implementation.extendsFrom(internal)
-}
-
-// JavaFX dependencies
-javafx {
- version = "20"
- modules = ["javafx.controls", "javafx.graphics", "javafx.fxml", "javafx.media"]
-}
-
-// Project dependencies
-dependencies {
-
- // https://mvnrepository.com/artifact/org.jetbrains/annotations
- implementation "org.jetbrains:annotations:24.0.1"
-
- // JFxFramework
- implementation project(":framework")
-
- // https://mvnrepository.com/artifact/com.google.dagger/dagger
- implementation group: "com.google.dagger", name: "dagger", version: "2.42"
-
- // https://mvnrepository.com/artifact/com.google.dagger/dagger-compiler
- annotationProcessor group: "com.google.dagger", name: "dagger-compiler", version: "2.42"
-
- // https://mvnrepository.com/artifacts/fr.brouillard.oss/cssfx
- implementation group: "fr.brouillard.oss", name: "cssfx", version: "11.5.1"
-
- // https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit
- implementation group: "com.squareup.retrofit2", name: "retrofit", version: "2.9.0"
-
- // https://mvnrepository.com/artifact/com.squareup.retrofit2/adapter-rxjava3
- implementation group: "com.squareup.retrofit2", name: "adapter-rxjava3", version: "2.9.0"
-
- // https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-jackson
- implementation group: "com.squareup.retrofit2", name: "converter-jackson", version: "2.9.0"
-
- // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
- implementation group: "com.fasterxml.jackson.core", name: "jackson-core", version: "2.13.3"
-
- // https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxjava
- implementation group: "io.reactivex.rxjava3", name: "rxjava", version: "3.1.4"
-
- // https://mvnrepository.com/artifact/org.glassfish.tyrus.bundles/tyrus-standalone-client/1.9
- implementation group: "org.glassfish.tyrus.bundles", name: "tyrus-standalone-client", version: "1.9"
-
- // https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api/1.1
- compileOnly group: "javax.websocket", name: "javax.websocket-api", version: "1.1"
-
- // https://mvnrepository.com/artifact/org.glassfish.tyrus/tyrus-client/1.15
- implementation group: "org.glassfish.tyrus", name: "tyrus-client", version: "1.15"
-
- // https://mvnrepository.com/artifact/org.glassfish.tyrus/tyrus-container-grizzly-client/1.15
- implementation group: "org.glassfish.tyrus", name: "tyrus-container-grizzly-client", version: "1.15"
-
- annotationProcessor project(':annotation-processor')
-}
-
-java {
- sourceCompatibility = getVersionForMajor(javaSourceVersion)
- targetCompatibility = getVersionForMajor(javaTargetVersion)
-
- if (generateSourcesJar) {
- withSourcesJar()
- }
- if (generateJavadocJar) {
- withJavadocJar()
- }
-}
-
-sourcesJar {
- duplicatesStrategy = DuplicatesStrategy.INCLUDE
-}
-
-jar {
- from {
- configurations.internal.collect { it.isDirectory() ? it : zipTree(it) }
- }
-
- manifest {
- attributes(
- "Manifest-Version": 1.0,
- "Class-Path": ".",
- "Main-Class": "io.github.sekassel.person.Main"
- )
- }
-
- duplicatesStrategy = DuplicatesStrategy.EXCLUDE
-}
-
-compileJava {
- options.encoding = "UTF-8"
- options.sourcepath = sourceSets.main.resources.getSourceDirectories()
-}
-javadoc { options.encoding = "UTF-8" }
-
-repositories {
- mavenCentral()
- maven {
- name = "jitpack"
- url = "https://jitpack.io"
- }
-}
-
-group projectGroup
-version projectVersion
-
-// Include local jar dependencies
-dependencies {
- implementation fileTree(dir: "libs/implementation", include: "*.jar")
- internal fileTree(dir: "libs/internal", include: "*.jar")
-}
-
-static JavaVersion getVersionForMajor(String version) {
- return JavaVersion.values().find { (it.majorVersion == version) }
-}
diff --git a/card-game/libs/implementation/.gitkeep b/card-game/libs/implementation/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/card-game/libs/internal/.gitkeep b/card-game/libs/internal/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/card-game/src/main/java/io/github/sekassel/uno/App.java b/card-game/src/main/java/io/github/sekassel/uno/App.java
deleted file mode 100644
index 74036b70..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/App.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package io.github.sekassel.uno;
-
-import io.github.sekassel.uno.dagger.DaggerMainComponent;
-import io.github.sekassel.uno.dagger.MainComponent;
-import javafx.stage.Stage;
-import org.fulib.fx.FulibFxApp;
-
-import java.nio.file.Path;
-import java.util.Map;
-import java.util.logging.Level;
-
-import static javafx.scene.input.KeyEvent.KEY_PRESSED;
-
-/**
- * The main class of your application.
- */
-public class App extends FulibFxApp {
-
-
- /**
- * The dagger component of the application.
- */
- private final MainComponent component;
-
- /**
- * The constructor of the application.
- */
- public App() {
- super();
-
- // Create a new dagger component as a starting point for the dependency injection
- this.component = DaggerMainComponent.builder().mainApp(this).build();
- }
-
- /**
- * The start method of the application.
- * This method is called by the {@link Main} class when the application is started.
- *
- * @param primaryStage The primary stage of the application
- */
- @Override
- public void start(Stage primaryStage) {
- try {
-
- // Starting the framework, initializes all the necessary components
- super.start(primaryStage);
-
- // Registering the routes of the application. See UnoRouting.java for more information.
- registerRoutes(component.routes());
-
- // Setting the default resource bundle of the application to the resource bundle provided by the component
- setDefaultResourceBundle(component.bundle());
-
- stage().addEventHandler(KEY_PRESSED, event -> {
- if (event.getCode().toString().equals("F5")) {
- this.refresh();
- }
- });
-
- this.setTitlePattern("Uno - %s");
-
- // Setting the resource path to the resources folder of the project (required for reloading in dev)
- // If the resource path is not set, the framework will use the default resource path (src/main/resources)
- setResourcesPath(Path.of("card-game/src/main/resources/"));
-
- // Setting the path which the auto refresher should watch (required for auto-reloading in dev)
- autoRefresher().setup(Path.of("card-game/src/main/resources/io/github/sekassel/uno"));
- show("", Map.of());
-
- } catch (Exception e) {
- // If an error occurs while starting the application, we want to log it and exit the application
- LOGGER.log(Level.SEVERE, "An error occurred while starting the application: " + e.getMessage(), e);
- }
- }
-
- /**
- * The stop method of the application. This method will be called when the application stops, for example if the
- * window is closed.
- */
- @Override
- public void stop() {
- super.stop();
- }
-
- /**
- * Returns the dagger component of the application.
- *
- * @return The dagger component
- */
- public MainComponent component() {
- return component;
- }
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/Constants.java b/card-game/src/main/java/io/github/sekassel/uno/Constants.java
deleted file mode 100644
index ff6a35e0..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/Constants.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.github.sekassel.uno;
-
-import javafx.scene.media.Media;
-
-
-public class Constants {
-
- public static final int START_CARD_AMOUNT = 4;
-
- public static final int MAX_NAME_LENGTH = 16;
- public static final String BOT_NAME = "Bot %s";
-
- public static final int BOT_PLAY_DELAY = 2000;
-
- public static final String CARD_FONT_FAMILY = "System";
- public static final String BOT_ICON_FONT_FAMILY = "Cooper Black";
- public static final int CARD_FONT_SIZE = 64;
-
- public static final String CARD_STYLE = "-fx-border-radius: 10px; -fx-border-color: BLACK; -fx-border-width: 10px; -fx-background-color: %s; -fx-background-radius: 16px; -fx-background-insets: 3px;";
-
- public static final Media SOUND_CLICK = new Media(Main.class.getResource("sound/click.mp3").toString());
- public static final Media SOUND_FAIL = new Media(Main.class.getResource("sound/fail.mp3").toString());
-
- public static final String COUNTER_CLOCKWISE_ICON = "\u21BA";
- public static final String CLOCKWISE_ICON = "\u21BB";
- public static final String WILD_ICON = "\u2605";
- public static final String SKIP_ICON = "\u2A02";
- public static final String DRAW_TWO_ICON = "+2";
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/Main.java b/card-game/src/main/java/io/github/sekassel/uno/Main.java
deleted file mode 100644
index eb61be91..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/Main.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.github.sekassel.uno;
-
-import javafx.application.Application;
-
-public class Main {
-
- public static void main(String[] args) {
- Application.launch(App.class, args);
- }
-}
\ No newline at end of file
diff --git a/card-game/src/main/java/io/github/sekassel/uno/UnoRouting.java b/card-game/src/main/java/io/github/sekassel/uno/UnoRouting.java
deleted file mode 100644
index dae0271a..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/UnoRouting.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.github.sekassel.uno;
-
-import org.fulib.fx.annotation.Route;
-import io.github.sekassel.uno.controller.*;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
-/**
- * This class is used to set up the routing for the application.
- * Every route is mapped to a controller, which is then used to display the corresponding view.
- *
- * The {@link Route} annotation is used to mark a controller as a route.
- * The value of the annotation is the path of the route.
- *
- * The controllers will be created using Providers, which in this case are injected by dagger. Therefore, the controllers
- * need an empty constructor annotated with {@link Inject}.
- */
-@Singleton
-public class UnoRouting {
-
- @Inject
- @Route("")
- // The empty route is the default route. It is often used as the starting point of the application.
- public Provider setupController;
-
- @Inject
- @Route("ingame")
- public Provider ingameController;
-
- @Inject
- @Route("gameover")
- public Provider gameOverController;
-
- @Inject
- public UnoRouting() {
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/controller/BotController.java b/card-game/src/main/java/io/github/sekassel/uno/controller/BotController.java
deleted file mode 100644
index 1367e080..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/controller/BotController.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package io.github.sekassel.uno.controller;
-
-import org.fulib.fx.annotation.controller.Component;
-import org.fulib.fx.annotation.event.onDestroy;
-import org.fulib.fx.annotation.event.onInit;
-import org.fulib.fx.annotation.event.onRender;
-import org.fulib.fx.annotation.param.Param;
-import org.fulib.fx.controller.Subscriber;
-import io.github.sekassel.uno.Constants;
-import io.github.sekassel.uno.model.Player;
-import io.github.sekassel.uno.service.GameService;
-import javafx.fxml.FXML;
-import javafx.scene.control.Label;
-import javafx.scene.layout.VBox;
-import javafx.scene.text.Font;
-
-import javax.inject.Inject;
-
-@Component(view = "sub/Bot.fxml")
-public class BotController extends VBox {
-
- @FXML
- public VBox botBox;
- @FXML
- public Label nameLabel;
- @FXML
- public Label currentCardsValueLabel;
- @FXML
- public Label iconLabel;
-
- @Inject
- GameService gameService;
- @Inject
- Subscriber subscriber;
-
- @Param("bot")
- private Player bot;
-
- @Param("parent")
- private IngameController parent;
-
- @onInit
- public void initSout() {
- System.out.println(this + " initialized.");
- }
-
- @onRender()
- public void renderSout() {
- System.out.println(this + " rendered.");
- }
-
- @onDestroy
- public void destroySout() {
- System.out.println(this + " destroyed.");
- }
-
- @onRender()
- public void render() {
-
- botBox.setId(bot.getName().replace(" ", ""));
-
- updateCards();
- updateName();
- setupPropertyChangeListeners();
- }
-
- /**
- * Sets up all the required listeners for displaying the card.
- */
- private void setupPropertyChangeListeners() {
- // Update the card amount if the cards of the bot change (or display a winning screen if the bot won the game)
- this.subscriber.listen(bot.listeners(), Player.PROPERTY_CARDS, event -> {
- updateCards();
- if (bot.getGame() != null && this.bot.getCards().isEmpty()) {
- parent.displayWinner(this.bot);
- }
- });
- }
-
- /**
- * Updates the card amount to the correct number.
- */
- public void updateCards() {
- currentCardsValueLabel.setText(String.valueOf(bot.getCards().size()));
- }
-
- /**
- * Updates the name to the correct value.
- */
- public void updateName() {
- this.nameLabel.setText(bot.getName());
- }
-
- /**
- * Highlights a bot or removes the highlight from a bot.
- *
- * @param highlight Whether the bot should be highlighted
- */
- public void highlight(boolean highlight) {
- nameLabel.setUnderline(highlight);
- iconLabel.setFont(Font.font(Constants.BOT_ICON_FONT_FAMILY, highlight ? 72 : 64));
- }
-
- @onDestroy
- public void destroy() {
- // Remove the bot from the game
- this.gameService.getBotService().removeBot(bot);
- this.subscriber.dispose();
- }
-
- @Inject
- public BotController() {
- super();
- System.out.println(this + " created.");
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/controller/ButtonController.java b/card-game/src/main/java/io/github/sekassel/uno/controller/ButtonController.java
deleted file mode 100644
index 34160453..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/controller/ButtonController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package io.github.sekassel.uno.controller;
-
-import org.fulib.fx.annotation.controller.Component;
-import org.fulib.fx.annotation.event.onDestroy;
-import org.fulib.fx.annotation.event.onInit;
-import org.fulib.fx.annotation.event.onRender;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.layout.HBox;
-
-import javax.inject.Inject;
-
-@Component(view = "sub/Buttons.fxml")
-public class ButtonController extends HBox {
-
- public void setParentController(IngameController parentController) {
- this.parentController = parentController;
- }
-
- private IngameController parentController;
-
- @Inject
- public ButtonController() {
- System.out.println(this + " created.");
- }
-
-
- @onInit
- public void initSout() {
- System.out.println(this + " initialized.");
- }
-
- @onRender()
- public void renderSout() {
- System.out.println(this + " rendered.");
- }
-
- @onDestroy
- public void destroySout() {
- System.out.println(this + " destroyed.");
- }
-
- /**
- * The method triggered by the wild card buttons.
- * Different behaviour is defined by the id of the clicked button.
- * Chooses the card color and plays the wild card as a colored card.
- */
- @FXML
- public void onWildPressed(ActionEvent event) {
- this.parentController.onWildPressed(event);
- }
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/controller/CardController.java b/card-game/src/main/java/io/github/sekassel/uno/controller/CardController.java
deleted file mode 100644
index 291a46d6..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/controller/CardController.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package io.github.sekassel.uno.controller;
-
-import org.fulib.fx.annotation.controller.Component;
-import org.fulib.fx.annotation.event.onDestroy;
-import org.fulib.fx.annotation.event.onInit;
-import org.fulib.fx.annotation.event.onRender;
-import org.fulib.fx.controller.Subscriber;
-import io.github.sekassel.uno.Constants;
-import io.github.sekassel.uno.model.Card;
-import io.github.sekassel.uno.model.Player;
-import io.github.sekassel.uno.service.GameService;
-import io.github.sekassel.uno.util.Utils;
-import javafx.fxml.FXML;
-import javafx.scene.control.Label;
-import javafx.scene.layout.VBox;
-import javafx.scene.text.Font;
-import javafx.scene.text.FontWeight;
-
-import javax.inject.Inject;
-
-@Component(view = "sub/Card.fxml")
-public class CardController extends VBox {
-
- @FXML
- public VBox cardScreen;
- @FXML
- public Label cardTypeLabel;
-
- @Inject
- GameService gameService;
-
- @Inject
- Subscriber subscriber;
-
- private Card card;
-
- @Inject
- public CardController() {
- System.out.println(this + " created.");
- }
-
- @onRender
- public void render() {
-
- cardScreen.setId((this.card.getColor() + "_" + this.card.getType()).toLowerCase());
-
- setupPropertyChangeListeners();
- setupSelection();
- setColor();
- }
-
- /**
- * Sets up all the required listeners for displaying the card.
- */
- private void setupPropertyChangeListeners() {
- // Change the card color if the card color changes (wild cards)
- subscriber.listen(card.listeners(), Card.PROPERTY_COLOR, event -> setColor());
- }
-
- /**
- * Set up a click listener so that the card will be selected when it's clicked.
- */
- private void setupSelection() {
-
- Player owner = card.getOwner();
-
- if (owner == null) {
- return;
- }
-
- cardScreen.setOnMouseClicked(event -> gameService.selectCard(this.card));
- }
-
- /**
- * Update the color of the controller.
- */
- private void setColor() {
- cardScreen.setStyle(Utils.getCardStyle(this.card.getColor()));
- cardTypeLabel.setText(card.getType().getIcon());
- }
-
- /**
- * Highlights a card or removes the highlight from a card.
- *
- * @param highlight Whether the card should be highlighted
- */
- public void highlight(boolean highlight) {
- cardTypeLabel.setFont(Font.font(Constants.CARD_FONT_FAMILY, highlight ? FontWeight.BOLD : FontWeight.NORMAL, Constants.CARD_FONT_SIZE));
- cardTypeLabel.setUnderline(highlight);
- }
-
- /**
- * Sets the card that should be displayed.
- *
- * @param card The card that should be displayed
- */
- public CardController setCard(Card card) {
- this.card = card;
- return this;
- }
-
- @onDestroy
- public void destroy() {
- // Remove the card from the game
- this.subscriber.dispose();
- }
-
-
- @onInit
- public void initSout() {
- System.out.println(this + " initialized.");
- }
-
- @onRender()
- public void renderSout() {
- System.out.println(this + " rendered.");
- }
-
- @onDestroy
- public void destroySout() {
- System.out.println(this + " destroyed.");
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/controller/GameOverController.java b/card-game/src/main/java/io/github/sekassel/uno/controller/GameOverController.java
deleted file mode 100644
index 06ab881b..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/controller/GameOverController.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.github.sekassel.uno.controller;
-
-import org.fulib.fx.annotation.controller.Controller;
-import org.fulib.fx.annotation.controller.Title;
-import org.fulib.fx.annotation.event.onDestroy;
-import org.fulib.fx.annotation.event.onInit;
-import org.fulib.fx.annotation.event.onRender;
-import org.fulib.fx.annotation.param.Param;
-import io.github.sekassel.uno.App;
-import io.github.sekassel.uno.model.Player;
-import javafx.fxml.FXML;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.layout.VBox;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-@Controller
-@Title("Game Over")
-public class GameOverController {
-
- @Inject
- App app;
-
- @FXML
- public VBox gameOverScreen;
- @FXML
- public Button backToMenuButton;
- @FXML
- public Label wonLabel;
-
- @Inject
- public GameOverController() {
- System.out.println(this + " created.");
- }
-
- // This method will be called when the controller is rendered. Since we don't have to save the winner in a field,
- // we can just pass it as a parameter to the method.
- @onRender
- public void render(@Param(value = "winner") Player player) {
- wonLabel.setText(wonLabel.getText().formatted(player.getName()));
- }
-
- /**
- * The method triggered by the quit button.
- * Displays the setup screen again.
- */
- @FXML
- private void backToMenu() {
- this.app.show("/");
- }
-
-
- @onInit
- public void initSout() {
- System.out.println(this + " initialized.");
- }
-
- @onRender()
- public void renderSout() {
- System.out.println(this + " rendered.");
- }
-
- @onDestroy
- public void destroySout() {
- System.out.println(this + " destroyed.");
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/controller/IngameController.java b/card-game/src/main/java/io/github/sekassel/uno/controller/IngameController.java
deleted file mode 100644
index 51b78498..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/controller/IngameController.java
+++ /dev/null
@@ -1,432 +0,0 @@
-package io.github.sekassel.uno.controller;
-
-import io.github.sekassel.uno.App;
-import io.github.sekassel.uno.Constants;
-import io.github.sekassel.uno.model.Card;
-import io.github.sekassel.uno.model.Game;
-import io.github.sekassel.uno.model.Player;
-import io.github.sekassel.uno.service.GameService;
-import io.github.sekassel.uno.util.CardColor;
-import io.github.sekassel.uno.util.Utils;
-import javafx.beans.property.BooleanProperty;
-import javafx.beans.property.SimpleBooleanProperty;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Parent;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.input.KeyCode;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import org.fulib.fx.annotation.controller.Controller;
-import org.fulib.fx.annotation.controller.Resource;
-import org.fulib.fx.annotation.controller.SubComponent;
-import org.fulib.fx.annotation.controller.Title;
-import org.fulib.fx.annotation.event.onDestroy;
-import org.fulib.fx.annotation.event.onInit;
-import org.fulib.fx.annotation.event.onKey;
-import org.fulib.fx.annotation.event.onRender;
-import org.fulib.fx.annotation.param.Param;
-import org.fulib.fx.constructs.forloop.FxFor;
-import org.fulib.fx.controller.Subscriber;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-/**
- * The controller for the ingame screen.
- * Displays the game and handles the user input.
- *
- * The controller annotation is required for the framework to recognize this class as a controller.
- * As there is no view specified, the framework will use the default file name which is located in the 'resources' folder
- * and has a name based on the class name (IngameController.class --> Ingame.fxml).
- */
-@Controller
-@Title
-public class IngameController {
-
- private final BooleanProperty wildCardSelectedProperty = new SimpleBooleanProperty();
- private final BooleanProperty playersTurn = new SimpleBooleanProperty();
- private final BooleanProperty cardSelected = new SimpleBooleanProperty();
-
- HashMap cards = new HashMap<>();
- HashMap bots = new HashMap<>();
-
- // We're using dagger for injecting our dependencies
- @Inject
- App app;
- @Inject
- Subscriber subscriber;
- @Inject
- FxFor fxFor;
- @Inject
- GameService gameService;
- @Inject
- Provider botControllerProvider;
- @Inject
- Provider cardControllerProvider;
-
- @Inject
- @Resource
- ResourceBundle resourceBundle;
-
- @Inject
- @SubComponent
- @FXML
- // Fields annotated with @SubComponent will be initialized and rendered with the controller.
- // They can be placed manually in code or using the FXML file.
- ButtonController buttonController;
-
- @FXML
- private VBox colorSelectorBox;
- @FXML
- private HBox mainBox1;
- @FXML
- private HBox mainBox2;
- @FXML
- private HBox cardListHBox;
- @FXML
- private Button drawButton;
- @FXML
- private Button playButton;
- @FXML
- private Label playersTurnText;
- @FXML
- private Label directionIconLabel;
-
-
- private CardController currentCardController;
-
- @Param("game") // Fields annotated with @Param will be injected when the controller is initialized
- private Game game;
-
- @Inject
- public IngameController() {
- System.out.println(this + " created.");
- // The annotation @Inject is required for dagger to recognize this constructor as an injectable constructor
- }
-
- @onInit
- public void init() {
- buttonController.setParentController(this);
-
- // Initialize the game
- this.gameService.initialize(this.game);
-
- }
-
- // Since this method is annotated wth @onRender, it will be called when the controller is rendered
- @onRender
- public void render() {
- // Setup gui elements
- setupPropertyChangeListeners();
- renderBots();
- displayLastPlayed(this.game.getCurrentCard());
-
-
- // Render the cards of the player
- subscriber.subscribe(
- fxFor.of(this.cardListHBox, this.game.getFirstPlayer().getCards(), cardControllerProvider, (controller, card) -> {
- controller.setCard(card);
- this.cards.put(card, controller);
- controller.subscriber.subscribe(() -> this.cards.remove(card));
- }).disposable()
- );
- }
-
- /**
- * Sets up all the required listeners for displaying the game.
- */
- private void setupPropertyChangeListeners() {
-
- // Listener for displaying the direction of the game
- subscriber.listen(game.listeners(), Game.PROPERTY_CLOCKWISE, event ->
- this.directionIconLabel.setText(this.game.isClockwise() ? Constants.CLOCKWISE_ICON : Constants.COUNTER_CLOCKWISE_ICON)
- );
-
- // Listener for displaying the last played card in the center
- subscriber.listen(game.listeners(), Game.PROPERTY_CURRENT_CARD, event -> {
- Card newCard = (Card) event.getNewValue();
- if (newCard != null) {
- displayLastPlayed(newCard);
- }
- });
-
- // Listener for toggling the play/color picker buttons when a wild card is selected
- subscriber.listen(game.getFirstPlayer().listeners(), Player.PROPERTY_CURRENT_CARD, event ->
- this.wildCardSelectedProperty.set(event.getNewValue() != null && ((Card) event.getNewValue()).getColor() == CardColor.WILD)
- );
-
- // Listener for highlighting the selected card
- subscriber.listen(game.getFirstPlayer().listeners(), Player.PROPERTY_CURRENT_CARD, event -> {
- if (event.getOldValue() != null) {
- Card oldCard = ((Card) event.getOldValue());
- getControllerByCard(oldCard).highlight(false);
- }
-
- if (event.getNewValue() != null) {
- Card newCard = ((Card) event.getNewValue());
- getControllerByCard(newCard).highlight(true);
- cardSelected.set(newCard.canBeOnTopOf(game.getCurrentCard()));
- } else {
- cardSelected.set(false);
- }
- });
-
-
- // Listener for toggling the play/draw button when the player is at turn and selecting the playing bot
- subscriber.listen(game.listeners(), Game.PROPERTY_CURRENT_PLAYER, event -> {
- Player newPlayer = (Player) event.getNewValue();
- Player oldPlayer = (Player) event.getOldValue();
-
- BotController oldController = getControllerByBot(oldPlayer);
- BotController newController = getControllerByBot(newPlayer);
-
- // Highlight the next player (and remove the highlighting from the old one)
- // As human players don't have a controller, the if-statement won't pass
- if (oldController != null) {
- oldController.highlight(false);
- }
- if (newController != null) {
- newController.highlight(true);
- }
-
- // If the new player is a human, it's the player's turn now
- boolean isHuman = this.game.getFirstPlayer().equals(newPlayer);
- playersTurn.set(isHuman);
-
- // If the new player is a bot, let the bot play
- if (!isHuman) {
- this.gameService.getBotService().startTurn(newPlayer);
- }
-
- });
-
- // Listener for displaying the winner if the player wins
- this.game.getFirstPlayer().listeners().addPropertyChangeListener(Player.PROPERTY_CARDS,
- event -> {
- // Check if the player wins
- if (game.getFirstPlayer().getCards().isEmpty()) {
- displayWinner(game.getFirstPlayer());
- }
- }
- );
-
- playersTurn.set(true);
- // Display the color selection when a wildcard has been selected and it's the player's turn
- subscriber.bind(colorSelectorBox.visibleProperty(), wildCardSelectedProperty.and(playersTurn));
- // Disable the play button if the player selected a wildcard, has no card selected or if it's not the player's turn
- subscriber.bind(playButton.disableProperty(), wildCardSelectedProperty.or(playersTurn.not()).or(cardSelected.not()));
- // Disable the draw button if it isn't the player's turn
- subscriber.bind(drawButton.disableProperty(), playersTurn.not());
- // Display the text if it's the player's turn
- subscriber.bind(playersTurnText.visibleProperty(), playersTurn);
- }
-
- /**
- * The method triggered by the quit button.
- * Display the setup screen again (with the currently used values as initial values).
- */
- @FXML
- public void onQuitPressed() {
- System.out.println("Quit");
- this.app.show("/", Map.of("initialBotAmount", this.game.getPlayers().size() - 1, "initialText", this.game.getFirstPlayer().getName()));
- }
-
- /**
- * The method triggered by the draw button.
- * Checks if it's the player's turn and then draws a new card.
- * If the card can be played, play it (if it's a wild card randomize the color).
- */
- @FXML
- public void onDrawPressed() {
- if (playersTurn.get()) {
- Card drawn = this.gameService.handoutCards(game.getPlayers().get(0), 1).get(0);
- if (drawn.canBeOnTopOf(game.getCurrentCard())) {
- playCard(drawn, drawn.getColor() == CardColor.WILD ? Utils.getRandomColor(this.gameService.getRandom()) : null);
- } else {
- this.gameService.selectNextPlayer(game, 1);
- Utils.playSound(Constants.SOUND_FAIL);
- }
- }
- }
-
- @onKey(code = KeyCode.ESCAPE)
- public void onKeyPressed() {
- onQuitPressed();
- }
-
- /**
- * The method triggered by the play button.
- * Checks if it's the player's turn and then plays the currently selected card.
- */
- @FXML
- public void onPlayPressed() {
- Card selected = this.game.getFirstPlayer().getCurrentCard();
- if (playersTurn.get() && selected != null) {
- playCard(selected, null);
- }
- }
-
- /**
- * The method triggered by the wild card buttons.
- * Different behaviour is defined by the id of the clicked button.
- * Chooses the card color and plays the wild card as a colored card.
- */
- public void onWildPressed(ActionEvent event) {
- Card selected = this.game.getFirstPlayer().getCurrentCard();
- Button pressed = (Button) event.getSource();
- CardColor color = switch (pressed.getId()) {
- case "redButton" -> CardColor.RED;
- case "blueButton" -> CardColor.BLUE;
- case "yellowButton" -> CardColor.YELLOW;
- case "greenButton" -> CardColor.GREEN;
- default -> null;
- };
- playCard(selected, color);
- }
-
- /**
- * Plays a card and changes its color if set.
- *
- * @param card The card to play
- * @param color The color the card should become (not set if null)
- */
- private void playCard(Card card, CardColor color) {
- this.gameService.playRound(card, color);
- }
-
- /**
- * Creates bot controllers and renders them at the correct place.
- */
- private void renderBots() {
- List players = this.game.getPlayers();
- players.forEach(player -> {
- if (this.game.getFirstPlayer() == player)
- return;
-
- // Create a new controller for the bot. Since the controller isn't rendered by the framework, we have to initialize it manually using initAndRender.
- // Since the controller will persist for the whole lifetime of the game, we can let the framework handle the destruction of the controller.
- BotController botController = app.initAndRender(botControllerProvider.get(), Map.of("bot", player, "parent", this), subscriber);
-
- bots.put(player, botController);
-
- switch (players.indexOf(player)) {
- case 1 -> renderBot(botController, mainBox2, 0);
- case 2 -> renderBot(botController, mainBox1, 0);
- case 3 -> renderBot(botController, mainBox2, 1);
- }
-
- });
-
- }
-
- /**
- * Renders a bot controller at a given pane and index.
- *
- * @param botNode The controller to be rendered
- * @param pane Where the controller should be displayed
- * @param index The index of the bot controller
- */
- private void renderBot(Parent botNode, Pane pane, int index) {
- System.out.println("Rendering bot " + botNode + " at " + pane + " with index " + index);
- pane.getChildren().remove(index);
- pane.getChildren().add(index, botNode);
- }
-
- /**
- * Displays a card as the last played card.
- *
- * @param card The card that has been played
- */
- public void displayLastPlayed(Card card) {
-
- // Destroy the controller of the last played card
- if (currentCardController != null) {
- // We have to destroy the controller manually, since it was rendered manually (see below)
- app.destroy(currentCardController);
- }
-
- // Remove the last played card if it exists
- if (mainBox2.getChildren().size() >= 3) {
- mainBox2.getChildren().remove(1);
- }
-
- // Create a new controller and initialize it, if there isn't already one
- if (!cards.containsKey(card)) {
- // Create a new controller for the card. Since the controller isn't rendered by the framework, we have to initialize it manually using initAndRender.
- // Since the controller won't persist for the whole lifetime of the game, we have to handle the destruction of the controller manually (see above).
- CardController controller = app.initAndRender(cardControllerProvider.get().setCard(card));
- cards.put(card, controller);
- }
-
- // Move the controller in the middle
- CardController newController = getControllerByCard(card);
-
- mainBox2.getChildren().add(1, newController);
-
- this.currentCardController = newController;
-
- }
-
-
- /**
- * Returns the controller for a given card.
- *
- * @param card The card of which the controller is searched
- * @return The controller of the card or null
- */
- public CardController getControllerByCard(Card card) {
- return cards.get(card);
- }
-
- /**
- * Returns the controller for a given bot.
- *
- * @param bot The bot of which the controller is searched
- * @return The controller of the bot or null
- */
- public BotController getControllerByBot(Player bot) {
- return bots.get(bot);
- }
-
- /**
- * Displays a winning screen with a given player as the winner of the game.
- *
- * @param player The player who won the game
- */
- public void displayWinner(Player player) {
- // In order to show the winner screen, we have to start with a '/', since otherwise path traversal would lead us
- // to the controller at the route '/ingame/gameover', which isn't specified.
- this.app.show("/gameover", Map.of("winner", player));
- }
-
- @onDestroy
- public void destroy() {
- // Remove the card from the game
- this.subscriber.dispose();
- }
-
-
- @onInit
- public void initSout() {
- System.out.println(this + " initialized.");
- }
-
- @onRender()
- public void renderSout() {
- System.out.println(this + " rendered.");
- }
-
- @onDestroy
- public void destroySout() {
- System.out.println(this + " destroyed.");
- }
-
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/controller/SetupController.java b/card-game/src/main/java/io/github/sekassel/uno/controller/SetupController.java
deleted file mode 100644
index eeedf0f7..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/controller/SetupController.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package io.github.sekassel.uno.controller;
-
-import org.fulib.fx.annotation.controller.Controller;
-import org.fulib.fx.annotation.controller.Title;
-import org.fulib.fx.annotation.event.onDestroy;
-import org.fulib.fx.annotation.event.onInit;
-import org.fulib.fx.annotation.event.onRender;
-import org.fulib.fx.annotation.param.Param;
-import org.fulib.fx.controller.Subscriber;
-import io.github.sekassel.uno.App;
-import io.github.sekassel.uno.Constants;
-import io.github.sekassel.uno.model.Game;
-import io.github.sekassel.uno.service.GameService;
-import io.github.sekassel.uno.util.Utils;
-import javafx.fxml.FXML;
-import javafx.scene.control.Button;
-import javafx.scene.control.Slider;
-import javafx.scene.control.TextField;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.Map;
-
-@Controller
-@Singleton
-@Title("Setup")
-public class SetupController {
-
- @FXML
- public Slider botAmountSlider;
- @FXML
- public TextField nicknameField;
- @FXML
- public Button playButton;
-
- @Inject
- GameService gameService;
- @Inject
- App app;
- @Inject
- Subscriber subscriber;
-
- @Param("initialText")
- private String initialText; // The initial text that will be display in the name input
- @Param("initialBotAmount")
- private Integer initialBotAmount; // The initial bot amount that will be selected
-
- @Inject
- public SetupController() {
- }
-
-
- @onRender
- public void render() {
-
- // Display initial values if set
- if (initialText != null)
- nicknameField.setText(initialText);
-
- if (initialBotAmount != null) {
- botAmountSlider.setValue(initialBotAmount);
- }
-
- setupPlayButton();
- }
-
- /**
- * Changes the play button to only be active if a name is present
- */
- private void setupPlayButton() {
- playButton.disableProperty().bind(nicknameField.textProperty().isEmpty());
- subscriber.subscribe(() -> playButton.disableProperty().unbind());
- }
-
- /**
- * The method triggered by the start button.
- * Creates a new game, modifies the username and displays the screen
- */
- @FXML
- private void start() {
- String name = Utils.trim(nicknameField.getText(), Constants.MAX_NAME_LENGTH);
- name = Utils.replaceIllegals(name);
- Game game = this.gameService.createGame(name, (int) botAmountSlider.getValue());
- this.app.show("/ingame", Map.of("game", game));
- }
-
- @onDestroy
- public void destroy() {
- // Remove the card from the game
- this.subscriber.dispose();
- }
-
-
- @onInit
- public void initSout() {
- System.out.println(this + " initialized.");
- }
-
- @onRender()
- public void renderSout() {
- System.out.println(this + " rendered.");
- }
-
- @onDestroy
- public void destroySout() {
- System.out.println(this + " destroyed.");
- }
-
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/dagger/MainComponent.java b/card-game/src/main/java/io/github/sekassel/uno/dagger/MainComponent.java
deleted file mode 100644
index 99a46745..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/dagger/MainComponent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package io.github.sekassel.uno.dagger;
-
-import dagger.BindsInstance;
-import dagger.Component;
-import io.github.sekassel.uno.App;
-import io.github.sekassel.uno.UnoRouting;
-
-import javax.inject.Singleton;
-import java.util.ResourceBundle;
-
-@Component(modules = {MainModule.class})
-@Singleton
-public interface MainComponent {
-
- UnoRouting routes();
-
- ResourceBundle bundle();
-
- @Component.Builder
- interface Builder {
- @BindsInstance
- Builder mainApp(App app);
-
- MainComponent build();
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/dagger/MainModule.java b/card-game/src/main/java/io/github/sekassel/uno/dagger/MainModule.java
deleted file mode 100644
index b2498ecb..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/dagger/MainModule.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.github.sekassel.uno.dagger;
-
-import dagger.Module;
-import dagger.Provides;
-import io.github.sekassel.uno.App;
-import org.fulib.fx.FulibFxApp;
-
-import java.util.Locale;
-import java.util.ResourceBundle;
-
-@Module
-public class MainModule {
- @Provides
- FulibFxApp app(App app) {
- return app;
- }
-
- @Provides
- ResourceBundle bundle() {
- return ResourceBundle.getBundle("io/github/sekassel/uno/lang", Locale.GERMAN);
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/model/Card.java b/card-game/src/main/java/io/github/sekassel/uno/model/Card.java
deleted file mode 100644
index 33c4c291..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/model/Card.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package io.github.sekassel.uno.model;
-
-import io.github.sekassel.uno.util.CardColor;
-import io.github.sekassel.uno.util.CardType;
-
-import java.util.Objects;
-import java.beans.PropertyChangeSupport;
-
-public class Card
-{
- public static final String PROPERTY_COLOR = "color";
- public static final String PROPERTY_OWNER = "owner";
- public static final String PROPERTY_GAME = "game";
- public static final String PROPERTY_TYPE = "type";
- protected PropertyChangeSupport listeners;
- private io.github.sekassel.uno.util.CardColor color = CardColor.WILD;
- private Player owner;
- private Game game;
- private io.github.sekassel.uno.util.CardType type = CardType.ZERO;
-
- public io.github.sekassel.uno.util.CardColor getColor()
- {
- return this.color;
- }
-
- public Card setColor(io.github.sekassel.uno.util.CardColor value)
- {
- if (Objects.equals(value, this.color))
- {
- return this;
- }
-
- final io.github.sekassel.uno.util.CardColor oldValue = this.color;
- this.color = value;
- this.firePropertyChange(PROPERTY_COLOR, oldValue, value);
- return this;
- }
-
- public Player getOwner()
- {
- return this.owner;
- }
-
- public Card setOwner(Player value)
- {
-
- if (this.owner == value)
- {
- return this;
- }
-
- final Player oldValue = this.owner;
- if (this.owner != null)
- {
- this.owner = null;
- oldValue.withoutCards(this);
- }
- this.owner = value;
- if (value != null)
- {
- value.withCards(this);
- }
- this.firePropertyChange(PROPERTY_OWNER, oldValue, value);
- return this;
- }
-
- public Game getGame()
- {
- return this.game;
- }
-
- public Card setGame(Game value)
- {
- if (this.game == value)
- {
- return this;
- }
-
- final Game oldValue = this.game;
- if (this.game != null)
- {
- this.game = null;
- oldValue.withoutCards(this);
- }
- this.game = value;
- if (value != null)
- {
- value.withCards(this);
- }
- this.firePropertyChange(PROPERTY_GAME, oldValue, value);
- return this;
- }
-
- public io.github.sekassel.uno.util.CardType getType()
- {
- return this.type;
- }
-
- public Card setType(io.github.sekassel.uno.util.CardType value)
- {
- if (Objects.equals(value, this.type))
- {
- return this;
- }
-
- final io.github.sekassel.uno.util.CardType oldValue = this.type;
- this.type = value;
- this.firePropertyChange(PROPERTY_TYPE, oldValue, value);
- return this;
- }
-
- public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue)
- {
- if (this.listeners != null)
- {
- this.listeners.firePropertyChange(propertyName, oldValue, newValue);
- return true;
- }
- return false;
- }
-
- public PropertyChangeSupport listeners()
- {
- if (this.listeners == null)
- {
- this.listeners = new PropertyChangeSupport(this);
- }
- return this.listeners;
- }
-
- public void removeYou()
- {
- this.setGame(null);
- this.setOwner(null);
- }
-
- /**
- * Determines whether this card is compatible with another card (can be played on top of the other card).
- * (Placed here for an easy way of checking card compatibility)
- *
- * @param below The card that would be below this card.
- * @return Whether the card could be played.
- */
- public boolean canBeOnTopOf(Card below) {
- return below.getColor() == this.getColor() || this.getColor() == CardColor.WILD || below.getType() == this.getType();
- }
-
- public String toString() { // no fulib
- return "[%s %s by %s in %s]".formatted(this.getName(), this.getColor(), this.getOwner(), this.getGame());
- }
-
- /**
- * @return The name of the card
- */
- public String getName() {
- return this.getType().toString();
- }
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/model/Game.java b/card-game/src/main/java/io/github/sekassel/uno/model/Game.java
deleted file mode 100644
index 7d69b608..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/model/Game.java
+++ /dev/null
@@ -1,251 +0,0 @@
-package io.github.sekassel.uno.model;
-
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public class Game
-{
- public static final String PROPERTY_PLAYERS = "players";
- public static final String PROPERTY_CLOCKWISE = "clockwise";
- public static final String PROPERTY_CARDS = "cards";
- public static final String PROPERTY_CURRENT_PLAYER = "currentPlayer";
- public static final String PROPERTY_CURRENT_CARD = "currentCard";
- private List players;
- protected PropertyChangeSupport listeners;
- private boolean clockwise = true;
- private List cards;
- private Player currentPlayer;
- private Card currentCard;
-
- public List getPlayers()
- {
- return this.players != null ? Collections.unmodifiableList(this.players) : Collections.emptyList();
- }
-
- public Game withPlayers(Player value)
- {
- if (this.players == null)
- {
- this.players = new ArrayList<>();
- }
- if (!this.players.contains(value))
- {
- this.players.add(value);
- value.setGame(this);
- this.firePropertyChange(PROPERTY_PLAYERS, null, value);
- }
- return this;
- }
-
- public Game withPlayers(Player... value)
- {
- for (final Player item : value)
- {
- this.withPlayers(item);
- }
- return this;
- }
-
- public Game withPlayers(Collection extends Player> value)
- {
- for (final Player item : value)
- {
- this.withPlayers(item);
- }
- return this;
- }
-
- public Game withoutPlayers(Player value)
- {
- if (this.players != null && this.players.remove(value))
- {
- value.setGame(null);
- this.firePropertyChange(PROPERTY_PLAYERS, value, null);
- }
- return this;
- }
-
- public Game withoutPlayers(Player... value)
- {
- for (final Player item : value)
- {
- this.withoutPlayers(item);
- }
- return this;
- }
-
- public Game withoutPlayers(Collection extends Player> value)
- {
- for (final Player item : value)
- {
- this.withoutPlayers(item);
- }
- return this;
- }
-
- public boolean isClockwise()
- {
- return this.clockwise;
- }
-
- public Game setClockwise(boolean value)
- {
- if (value == this.clockwise)
- {
- return this;
- }
-
- final boolean oldValue = this.clockwise;
- this.clockwise = value;
- this.firePropertyChange(PROPERTY_CLOCKWISE, oldValue, value);
- return this;
- }
-
- public List getCards()
- {
- return this.cards != null ? Collections.unmodifiableList(this.cards) : Collections.emptyList();
- }
-
- public Game withCards(Card value)
- {
- if (this.cards == null)
- {
- this.cards = new ArrayList<>();
- }
- if (!this.cards.contains(value))
- {
- this.cards.add(value);
- value.setGame(this);
- this.firePropertyChange(PROPERTY_CARDS, null, value);
- }
- return this;
- }
-
- public Game withCards(Card... value)
- {
- for (final Card item : value)
- {
- this.withCards(item);
- }
- return this;
- }
-
- public Game withCards(Collection extends Card> value)
- {
- for (final Card item : value)
- {
- this.withCards(item);
- }
- return this;
- }
-
- public Game withoutCards(Card value)
- {
- if (this.cards != null && this.cards.remove(value))
- {
- value.setGame(null);
- this.firePropertyChange(PROPERTY_CARDS, value, null);
- }
- return this;
- }
-
- public Game withoutCards(Card... value)
- {
- for (final Card item : value)
- {
- this.withoutCards(item);
- }
- return this;
- }
-
- public Game withoutCards(Collection extends Card> value)
- {
- for (final Card item : value)
- {
- this.withoutCards(item);
- }
- return this;
- }
-
- public Player getCurrentPlayer()
- {
- return this.currentPlayer;
- }
-
- public Game setCurrentPlayer(Player value)
- {
- if (this.currentPlayer == value)
- {
- return this;
- }
-
- final Player oldValue = this.currentPlayer;
- this.currentPlayer = value;
- this.firePropertyChange(PROPERTY_CURRENT_PLAYER, oldValue, value);
- return this;
- }
-
- public Card getCurrentCard()
- {
- return this.currentCard;
- }
-
- public Game setCurrentCard(Card value)
- {
- if (this.currentCard == value)
- {
- return this;
- }
-
- final Card oldValue = this.currentCard;
- this.currentCard = value;
- this.firePropertyChange(PROPERTY_CURRENT_CARD, oldValue, value);
- return this;
- }
-
- public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue)
- {
- if (this.listeners != null)
- {
- this.listeners.firePropertyChange(propertyName, oldValue, newValue);
- return true;
- }
- return false;
- }
-
- public PropertyChangeSupport listeners()
- {
- if (this.listeners == null)
- {
- this.listeners = new PropertyChangeSupport(this);
- }
- return this.listeners;
- }
-
- public void removeYou()
- {
- this.setCurrentPlayer(null);
- this.setCurrentCard(null);
- this.withoutCards(new ArrayList<>(this.getCards()));
- this.withoutPlayers(new ArrayList<>(this.getPlayers()));
- }
-
- /**
- * Returns the first player of the game (which is always the human player when using game logic).
- * (Placed here for an easy way of accessing the human player (or first player) of a game)
- *
- * @return The first player of the game
- */
- public Player getFirstPlayer() {
- return this.players.get(0);
- }
-
- public String toString() { // no fulib
- StringBuilder builder = new StringBuilder("[");
- getPlayers().forEach(player -> builder.append(player).append(" "));
- return builder.substring(0, builder.length() - 1).toString() + "]";
- }
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/model/Player.java b/card-game/src/main/java/io/github/sekassel/uno/model/Player.java
deleted file mode 100644
index 7c388968..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/model/Player.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package io.github.sekassel.uno.model;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Objects;
-
-public class Player
-{
- public static final String PROPERTY_NAME = "name";
- public static final String PROPERTY_GAME = "game";
- public static final String PROPERTY_CARDS = "cards";
- public static final String PROPERTY_CURRENT_CARD = "currentCard";
- private String name;
- private Game game;
- protected PropertyChangeSupport listeners;
- private ObservableList cards;
- private Card currentCard;
-
- public String getName()
- {
- return this.name;
- }
-
- public Player setName(String value)
- {
- if (Objects.equals(value, this.name))
- {
- return this;
- }
-
- final String oldValue = this.name;
- this.name = value;
- this.firePropertyChange(PROPERTY_NAME, oldValue, value);
- return this;
- }
-
- public Game getGame()
- {
- return this.game;
- }
-
- public Player setGame(Game value)
- {
- if (this.game == value)
- {
- return this;
- }
-
- final Game oldValue = this.game;
- if (this.game != null)
- {
- this.game = null;
- oldValue.withoutPlayers(this);
- }
- this.game = value;
- if (value != null)
- {
- value.withPlayers(this);
- }
- this.firePropertyChange(PROPERTY_GAME, oldValue, value);
- return this;
- }
-
- public ObservableList getCards()
- {
- return this.cards != null ? cards : FXCollections.emptyObservableList();
- }
-
- public Player withCards(Card value)
- {
- if (this.cards == null)
- {
- this.cards = FXCollections.observableArrayList();
- }
- if (!this.cards.contains(value))
- {
- this.cards.add(value);
- value.setOwner(this);
- this.firePropertyChange(PROPERTY_CARDS, null, value);
- }
- return this;
- }
-
- public Player withCards(Card... value)
- {
- for (final Card item : value)
- {
- this.withCards(item);
- }
- return this;
- }
-
- public Player withCards(Collection extends Card> value)
- {
- for (final Card item : value)
- {
- this.withCards(item);
- }
- return this;
- }
-
- public Player withoutCards(Card value)
- {
- if (this.cards != null && this.cards.remove(value))
- {
- value.setOwner(null);
- this.firePropertyChange(PROPERTY_CARDS, value, null);
- }
- return this;
- }
-
- public Player withoutCards(Card... value)
- {
- for (final Card item : value)
- {
- this.withoutCards(item);
- }
- return this;
- }
-
- public Player withoutCards(Collection extends Card> value)
- {
- for (final Card item : value)
- {
- this.withoutCards(item);
- }
- return this;
- }
-
- public Card getCurrentCard()
- {
- return this.currentCard;
- }
-
- public Player setCurrentCard(Card value)
- {
- if (this.currentCard == value)
- {
- return this;
- }
-
- final Card oldValue = this.currentCard;
- this.currentCard = value;
- this.firePropertyChange(PROPERTY_CURRENT_CARD, oldValue, value);
- return this;
- }
-
- public boolean firePropertyChange(String propertyName, Object oldValue, Object newValue)
- {
- if (this.listeners != null)
- {
- this.listeners.firePropertyChange(propertyName, oldValue, newValue);
- return true;
- }
- return false;
- }
-
- public PropertyChangeSupport listeners()
- {
- if (this.listeners == null)
- {
- this.listeners = new PropertyChangeSupport(this);
- }
- return this.listeners;
- }
-
- @Override
- public String toString()
- {
- final StringBuilder result = new StringBuilder();
- result.append(' ').append(this.getName());
- return result.substring(1);
- }
-
- public void removeYou()
- {
- this.setGame(null);
- this.withoutCards(new ArrayList<>(this.getCards()));
- this.setCurrentCard(null);
- }
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/service/BotService.java b/card-game/src/main/java/io/github/sekassel/uno/service/BotService.java
deleted file mode 100644
index 92888c17..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/service/BotService.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package io.github.sekassel.uno.service;
-
-import dagger.Lazy;
-import io.github.sekassel.uno.Constants;
-import io.github.sekassel.uno.model.Card;
-import io.github.sekassel.uno.model.Player;
-import io.github.sekassel.uno.util.CardColor;
-import io.github.sekassel.uno.util.Utils;
-import javafx.application.Platform;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.swing.*;
-import java.util.List;
-import java.util.Random;
-
-@Singleton
-public class BotService {
-
- private final Random random;
-
- @Inject
- Lazy gameService;
-
- @Inject
- public BotService() {
- this.random = new Random();
- }
-
- /**
- * Makes a bot play a round after a certain delay.
- *
- * @param bot The bot which should play
- */
- public void startTurn(Player bot) {
- Timer timer = new Timer(Constants.BOT_PLAY_DELAY, task -> Platform.runLater(() -> this.playRound(bot)));
- timer.setInitialDelay(Constants.BOT_PLAY_DELAY);
- timer.setRepeats(false);
- timer.restart(); //TODO: Fix timer not being stopped when game is closed by "Quit" button
- }
-
- /**
- * Selects a random cart out of the bot's cards which can be played
- *
- * @param bot The bot from which a card should be picked
- * @return A card which can be played or null
- */
- public Card selectCardToPlay(Player bot) {
- Card current = bot.getGame().getCurrentCard();
- List possibleCards = bot.getCards().stream().filter(card -> card.canBeOnTopOf(current)).toList();
- return possibleCards.isEmpty() ? null : possibleCards.get(random.nextInt(possibleCards.size()));
- }
-
- /**
- * Selects a card and plays it. If no card can be found, a card will be drawn.
- * If there is still no playable card, the next player will be selected.
- *
- * @param bot The bot which should play a card
- */
- private void playRound(Player bot) {
- Card selected = selectCardToPlay(bot);
-
- // If no card can be selected, draw a card
- if (selected == null) {
- Card drawn = this.gameService.get().handoutCards(bot, 1).get(0);
- if (!drawn.canBeOnTopOf(bot.getGame().getCurrentCard())) {
- this.gameService.get().selectNextPlayer(bot.getGame(), 1);
- Utils.playSound(Constants.SOUND_FAIL);
- return;
- }
- selected = drawn;
- }
-
- CardColor color = selected.getColor();
-
- // If the card is a wildcard, select a random color
- color = color == CardColor.WILD ? Utils.getRandomColor(this.random) : null;
-
- // Play the card
- gameService.get().playRound(selected, color);
- }
-
- /**
- * Removes a bot from the game.
- * @param player The bot to remove
- */
- public void removeBot(Player player) {
- player.removeYou();
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/service/CardService.java b/card-game/src/main/java/io/github/sekassel/uno/service/CardService.java
deleted file mode 100644
index a4a5bfc5..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/service/CardService.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package io.github.sekassel.uno.service;
-
-import io.github.sekassel.uno.model.Card;
-import io.github.sekassel.uno.model.Game;
-import io.github.sekassel.uno.model.Player;
-import io.github.sekassel.uno.util.CardColor;
-import io.github.sekassel.uno.util.CardType;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.Random;
-
-@Singleton
-public class CardService {
-
- private final Random random;
-
- @Inject
- public CardService() {
- this.random = new Random();
- }
-
- /**
- * Generates a card and gives it to the player
- *
- * @param player The player which should receive a card
- * @return The card given to the player
- */
- public Card giveCardTo(Player player) {
- return generateCard(player.getGame()).setOwner(player);
- }
-
- /**
- * Creates a random card
- *
- * @return The random card
- */
- public Card generateCard(Game game) {
- // Generate a random number (common or special)
- int num = this.random.nextInt(CardType.values().length);
-
- // If the card isn't a wild card, pick a random color
- CardColor color;
- if (CardType.values()[num] == CardType.WILD) {
- color = CardColor.WILD;
- } else {
- int colorNum = this.random.nextInt(CardColor.values().length - 1);
- color = CardColor.values()[colorNum];
- }
-
- // Generate the card and return it
- return new Card().setColor(color).setType(CardType.values()[num]).setGame(game);
-
- }
-
- /**
- * @return The currently used random instance.
- */
- public Random getRandom() {
- return this.random;
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/service/GameService.java b/card-game/src/main/java/io/github/sekassel/uno/service/GameService.java
deleted file mode 100644
index e9f6cfd7..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/service/GameService.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package io.github.sekassel.uno.service;
-
-import io.github.sekassel.uno.Constants;
-import io.github.sekassel.uno.model.Card;
-import io.github.sekassel.uno.model.Game;
-import io.github.sekassel.uno.model.Player;
-import io.github.sekassel.uno.util.CardColor;
-import io.github.sekassel.uno.util.CardType;
-import io.github.sekassel.uno.util.Utils;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-@Singleton
-public class GameService {
-
- @Inject
- CardService cardService;
- @Inject
- BotService botService;
-
- private final Random random;
-
- @Inject
- public GameService() {
- this.random = new Random();
- }
-
- /**
- * Creates a game with a player and a certain number of bots.
- *
- * @param playerName The name of the player
- * @param bots The amount of bots
- * @return The created game
- */
- public Game createGame(String playerName, int bots) {
- Player player = new Player().setName(playerName);
-
- // Initialize the game with the human as the current player
- Game game = new Game().setClockwise(true).withPlayers(player).setCurrentPlayer(player);
-
- // Create bots
- for (int i = 1; i <= bots; i++) {
- game.withPlayers(new Player().setName(Constants.BOT_NAME.formatted(i)));
- }
-
- return game;
- }
-
- /**
- * Hands out cards to every player and selects a random start card.
- *
- * @param game The game to initialize
- */
- public void initialize(Game game) {
-
- // Handout cards to every player
- game.getPlayers().forEach(player -> handoutCards(player, Constants.START_CARD_AMOUNT));
-
- // Generate a card and give it a random color if it's a wild card
- Card firstCard = cardService.generateCard(game);
- if (firstCard.getType() == CardType.WILD) {
- firstCard.setColor(Utils.getRandomColor(this.random));
- }
-
- // Place the card
- game.setCurrentCard(firstCard);
-
- }
-
- /**
- * Hands out cards to a player.
- *
- * @param player The player which should receive cards
- * @param amount The amount of cards
- * @return The cards given to the player
- */
- public List handoutCards(Player player, int amount) {
- List cards = new ArrayList<>();
- for (int i = 0; i < amount; i++) {
- cards.add(cardService.giveCardTo(player));
- }
- return cards;
- }
-
- public void selectCard(Card card) {
- card.getOwner().setCurrentCard(card);
- }
-
- /**
- * Plays a given card as a given color and run its special effects.
- *
- * @param card The card to play
- * @param color The color to play the card as (if null, the color will not be changed)
- */
- public void playRound(Card card, CardColor color) {
-
- Game game = card.getGame();
- Card current = game.getCurrentCard();
-
- if (!card.canBeOnTopOf(current)) {
- return;
- }
-
- if (color != null) {
- card.setColor(color);
- }
-
- Utils.playSound(Constants.SOUND_CLICK);
-
- // Remove the card from the player
- card.getOwner().setCurrentCard(null);
- card.setOwner(null);
-
- // Delete the old card, as it will never appear again
- game.withoutCards(current);
- current.removeYou();
-
- // Place the card
- game.setCurrentCard(card);
-
- // Check for special cards
- if (card.getType().hasAction()) {
- card.getType().getAction().run(card, this);
- } else {
- selectNextPlayer(game, 1);
- }
- }
-
-
- /**
- * Updates the current player of a given game.
- *
- * @param game The game to update.
- * @param amount The amount of players to go over (amount of players to skip plus one)
- */
- public void selectNextPlayer(Game game, int amount) {
- Player next = getNextPlayer(game, amount);
-
- Player current = game.getCurrentPlayer();
- game.setCurrentPlayer(next);
-
- // If the player stays the same, no event gets fired, so we have to call the method manually
- if (current == next && next != game.getFirstPlayer()) {
- getBotService().startTurn(next);
- }
-
- }
-
- /**
- * Returns the player which should play next.
- *
- * @param game The current game
- * @param amount The amount of players to go over (amount of players to skip plus one)
- * @return The next player
- */
- public Player getNextPlayer(Game game, int amount) {
- int nextIndex = getNextPlayerIndex(game, amount);
- return game.getPlayers().get(nextIndex);
- }
-
- /**
- * Returns the index of the player which should play next.
- *
- * @param game The current game
- * @param amount The amount of players to go over (amount of players to skip plus one)
- * @return The index of the next player
- */
- private int getNextPlayerIndex(Game game, int amount) {
- int current = game.getPlayers().indexOf(game.getCurrentPlayer());
- int players = game.getPlayers().size();
-
- if (game.isClockwise()) {
- return (current + amount) % players;
- } else {
- return (current + players - amount) % players;
- }
- }
-
- /**
- * @return The currently used bot service instance.
- */
- public BotService getBotService() {
- return botService;
- }
-
- /**
- * @return The currently used card service instance.
- */
- public CardService getCardService() {
- return cardService;
- }
-
- /**
- * @return The currently used random instance.
- */
- public Random getRandom() {
- return this.random;
- }
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/util/ActionRunnable.java b/card-game/src/main/java/io/github/sekassel/uno/util/ActionRunnable.java
deleted file mode 100644
index 1462ae8f..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/util/ActionRunnable.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.github.sekassel.uno.util;
-
-import io.github.sekassel.uno.model.Card;
-import io.github.sekassel.uno.service.GameService;
-
-/**
- * Defines the behaviour of a card.
- * Every aspect of the game can be accessed through the card instance.
- * Every method can be accessed through the game service instance.
- */
-@FunctionalInterface
-public interface ActionRunnable {
-
- void run(Card card, GameService service);
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/util/CardColor.java b/card-game/src/main/java/io/github/sekassel/uno/util/CardColor.java
deleted file mode 100644
index b7ee6d7e..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/util/CardColor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.github.sekassel.uno.util;
-
-/**
- * Defines the color a card can have.
- * If no color string is defined, it will use the enum's name as the color.
- */
-public enum CardColor {
-
- RED,
- BLUE,
- GREEN,
- YELLOW,
- WILD("GRAY");
-
- private final String color;
-
- CardColor(String color) {
- this.color = color;
- }
-
- CardColor() {
- this.color = this.name();
- }
-
- public String getColorString() {
- return this.color;
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/util/CardType.java b/card-game/src/main/java/io/github/sekassel/uno/util/CardType.java
deleted file mode 100644
index 8c3b7a2f..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/util/CardType.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package io.github.sekassel.uno.util;
-
-import io.github.sekassel.uno.Constants;
-
-/**
- * Defines the (special) mechanic of a card.
- * Number cards don't need any special mechanic and can therefore be defined as a plain enum instance.
- * Cards with a special mechanic have an ActionRunnable which will be called.
- */
-public enum CardType {
-
- ZERO,
- ONE,
- TWO,
- THREE,
- FOUR,
- FIVE,
- SIX,
- SEVEN,
- EIGHT,
- NINE,
-
- REVERSE(Constants.COUNTER_CLOCKWISE_ICON, (card, service) -> {
- var game = card.getGame();
- game.setClockwise(!game.isClockwise());
- if (game.getPlayers().size() > 2) {
- service.selectNextPlayer(game, 1);
- } else if (game.getCurrentPlayer() != card.getGame().getFirstPlayer()) {
- service.selectNextPlayer(card.getGame(), 2);
- }
- }),
-
- SKIP(Constants.SKIP_ICON, ((card, service) -> service.selectNextPlayer(card.getGame(), 2))),
-
- DRAW_TWO(Constants.DRAW_TWO_ICON, ((card, service) -> {
- var receiver = service.getNextPlayer(card.getGame(), 1);
- service.handoutCards(receiver, 2);
- service.selectNextPlayer(card.getGame(), 2);
- })),
-
- WILD(Constants.WILD_ICON);
-
- private final String icon;
- private ActionRunnable action;
-
- CardType() {
- this.icon = String.valueOf(this.ordinal());
- }
-
- CardType(String icon) {
- this.icon = icon;
- }
-
- CardType(String icon, ActionRunnable action) {
- this.icon = icon;
- this.action = action;
- }
-
- @Deprecated
- public int getNumber() {
- return this.ordinal();
- }
-
- public String getIcon() {
- return this.icon;
- }
-
- public boolean hasAction() {
- return this.action != null;
- }
-
- public ActionRunnable getAction() {
- return this.action;
- }
-
-}
diff --git a/card-game/src/main/java/io/github/sekassel/uno/util/Utils.java b/card-game/src/main/java/io/github/sekassel/uno/util/Utils.java
deleted file mode 100644
index 991b7912..00000000
--- a/card-game/src/main/java/io/github/sekassel/uno/util/Utils.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package io.github.sekassel.uno.util;
-
-import io.github.sekassel.uno.Constants;
-import javafx.scene.media.Media;
-import javafx.scene.media.MediaPlayer;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Random;
-
-public class Utils {
-
- /**
- * Replaces all illegal characters in a String
- *
- * @param name The string which should be cleared of illegal items
- * @return The string with all illegal characters replaced
- */
- public static String replaceIllegals(String name) {
- return name.replaceAll("[/\\\\:*?\"<>|]", "x"); // Needs 4 backslashes since it's a regex and java escape char
- }
-
- /**
- * Trims a string to a certain length.
- * @param toTrim The string to trim.
- * @param size The size to trim the string to.
- * @return The trimmed string.
- */
- public static String trim(String toTrim, int size) {
- return toTrim.length() < size ? toTrim : toTrim.substring(0, size);
- }
-
- /**
- * Generates a random color by a given random instance.
- * Every color except the last one (wild) can be selected.
- *
- * @param random The instance to use for the random selection
- * @return A random color
- */
- public static CardColor getRandomColor(Random random) {
- return CardColor.values()[random.nextInt(CardColor.values().length - 1)];
- }
-
- public static String getCardStyle(CardColor color) {
- return Constants.CARD_STYLE.formatted(color.getColorString());
- }
-
- /**
- * Generates a random instance by loading a seed from a file.
- * If no file is found or the seed in the file is invalid, generate an instance without a seed.
- *
- * @return The generated random instance
- */
- public static Random getRandomBySeedFile() {
- try {
- File file = new File("seed.txt");
- if (file.exists())
- return new Random(Integer.parseInt(Files.readString(file.toPath())));
- } catch (IOException | NumberFormatException exception) {
- System.out.println("Couldn't read seed from 'seed.txt'.");
- }
- return new Random();
- }
-
- /**
- * Plays a media/sound.
- *
- * @param sound The sound to be played
- */
- public static void playSound(Media sound) {
- try {
- new MediaPlayer(sound).play();
- } catch (IllegalStateException e) {
- System.err.println("Tried to play sound whilst game was in test mode.");
- }
- }
-
-
-}
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/controller/GameOver.fxml b/card-game/src/main/resources/io/github/sekassel/uno/controller/GameOver.fxml
deleted file mode 100644
index ef9f012c..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/controller/GameOver.fxml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/controller/Ingame.fxml b/card-game/src/main/resources/io/github/sekassel/uno/controller/Ingame.fxml
deleted file mode 100644
index 11561a6f..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/controller/Ingame.fxml
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/controller/Setup.fxml b/card-game/src/main/resources/io/github/sekassel/uno/controller/Setup.fxml
deleted file mode 100644
index 0c01f1df..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/controller/Setup.fxml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Bot.fxml b/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Bot.fxml
deleted file mode 100644
index e02dad5e..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Bot.fxml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Buttons.fxml b/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Buttons.fxml
deleted file mode 100644
index 07af5702..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Buttons.fxml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Card.fxml b/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Card.fxml
deleted file mode 100644
index 73263c66..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/controller/sub/Card.fxml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/image/logo.png b/card-game/src/main/resources/io/github/sekassel/uno/image/logo.png
deleted file mode 100644
index 7ec0115b..00000000
Binary files a/card-game/src/main/resources/io/github/sekassel/uno/image/logo.png and /dev/null differ
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/lang_de.properties b/card-game/src/main/resources/io/github/sekassel/uno/lang_de.properties
deleted file mode 100644
index dfe2e3df..00000000
--- a/card-game/src/main/resources/io/github/sekassel/uno/lang_de.properties
+++ /dev/null
@@ -1 +0,0 @@
-title=Uno
\ No newline at end of file
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/sound/click.mp3 b/card-game/src/main/resources/io/github/sekassel/uno/sound/click.mp3
deleted file mode 100644
index c66b7954..00000000
Binary files a/card-game/src/main/resources/io/github/sekassel/uno/sound/click.mp3 and /dev/null differ
diff --git a/card-game/src/main/resources/io/github/sekassel/uno/sound/fail.mp3 b/card-game/src/main/resources/io/github/sekassel/uno/sound/fail.mp3
deleted file mode 100644
index c4dbaf37..00000000
Binary files a/card-game/src/main/resources/io/github/sekassel/uno/sound/fail.mp3 and /dev/null differ
diff --git a/card-game/src/main/scenarios/.gitkeep b/card-game/src/main/scenarios/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/card-game/src/test/java/io/github/sekassel/fx/.gitkeep b/card-game/src/test/java/io/github/sekassel/fx/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/card-game/src/test/resources/io/github/sekassel/fx/.gitkeep b/card-game/src/test/resources/io/github/sekassel/fx/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/settings.gradle b/settings.gradle
index a82ac71d..9a7cdd26 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,5 +3,4 @@ rootProject.name = projectName
include "framework"
include "annotation-processor"
-include "card-game"
include "ludo"
\ No newline at end of file