Broadcast channel (#1)

* added sessions

* added sessions

* added sessions

* Edited Schafkopf classes

* removed LOG usages and removed unused method

* changed dotenv version

* added dotenv for ip address and deleted unused class

* removed unused logger

* removed unused logger

* renamed server classes

* renamed server classes

* changed schafkopf klassen

* added SpielController for a few Games

* added initialization of cards and ability to show cards in frontend

* SpielController.drawio eingefügt

* SpielController.drawio aktualisiert

* SpielController.drawio aktualisiert

* updated SpielController.drawio

* edited drawio

* edited drawio and renamed wert to punkte

---------

Co-authored-by: Tobias <tibistruppi.te@gmail.com>
This commit is contained in:
Valentin Heiserer
2023-11-13 21:29:33 +01:00
committed by GitHub
parent ad830bdc58
commit e63f18f4b7
16 changed files with 574 additions and 252 deletions

1
SpielController.drawio Normal file

File diff suppressed because one or more lines are too long

23
pom.xml
View File

@@ -26,29 +26,26 @@
<artifactId>websocket-jetty-server</artifactId> <artifactId>websocket-jetty-server</artifactId>
<version>11.0.15</version> <version>11.0.15</version>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>11.0.15</version>
</dependency>
<!-- To run websockets client --> <!-- To run websockets client -->
<dependency> <dependency>
<groupId>org.eclipse.jetty.websocket</groupId> <groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-jetty-client</artifactId> <artifactId>websocket-jetty-client</artifactId>
<version>11.0.15</version> <version>11.0.15</version>
</dependency> </dependency>
<!-- for logging reasons -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<version>11.0.15</version>
</dependency>
<!-- to test code with -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.10.1</version> <version>2.10.1</version>
</dependency> </dependency>
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-java</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -0,0 +1,136 @@
package org.example;
import java.net.InetSocketAddress;
import java.net.URI;
import java.time.Duration;
import java.util.EnumSet;
import jakarta.servlet.DispatcherType;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import io.github.cdimascio.dotenv.Dotenv;
public class BackendServer
{
private List<FrontendEndpoint> frontendEndpoints = new ArrayList<>();
public static void main(String[] args) throws Exception
{
BackendServer server = new BackendServer();
server.setPort(8080);
server.start();
server.join();
}
private final Server server;
private final ServerConnector connector;
private final Schafkopf schafkopfGame;
public BackendServer()
{
Dotenv dotenv = Dotenv.configure().load();
server = new Server();
InetSocketAddress address = new InetSocketAddress(dotenv.get("VITE_APP_WEBSOCKET_IP"), 8080);
connector = new ServerConnector(server);
connector.setHost(address.getHostName());
connector.setPort(address.getPort());
server.addConnector(connector);
schafkopfGame = new Schafkopf(this);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Configure CORS settings
configureCORS(context);
// Configure specific websocket behavior
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) ->
{
// Configure default max size
wsContainer.setMaxTextMessageSize(65535);
wsContainer.setIdleTimeout(Duration.ofDays(300000));
// Add websockets
wsContainer.addMapping("/schafkopf-events/*", new FrontendEndpointCreator(this));
});
}
private void configureCORS(ServletContextHandler context) {
// Enable CORS for all paths
FilterHolder cors = context.addFilter(CrossOriginFilter.class, "/*", null);
// Configure allowed origins, headers, and methods
cors.setInitParameter("allowedOrigins", "http://192.168.178.126:5173");
cors.setInitParameter("allowedHeaders", "X-Requested-With,Content-Type,Accept,Origin");
cors.setInitParameter("allowedMethods", "GET,POST,PUT,DELETE,OPTIONS");
// Add filter mappings
EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.REQUEST);
context.addFilter(cors, "*", types);
}
public void setPort(int port)
{
connector.setPort(port);
}
public void start() throws Exception
{
server.start();
}
public URI getURI()
{
return server.getURI();
}
public void stop() throws Exception
{
server.stop();
}
public void join() throws InterruptedException
{
server.join();
}
public void addFrontendEndpoint(FrontendEndpoint endpoint) {
frontendEndpoints.add(endpoint);
}
public void removeFrontendEndpoint(FrontendEndpoint endpoint) {
frontendEndpoints.remove(endpoint);
}
public void sendMessageToAllFrontendEndpoints(String message) {
for (FrontendEndpoint endpoint : frontendEndpoints) {
endpoint.sendMessage(message);
}
}
public void startSchafkopfGame() {
schafkopfGame.startGame();
}
public void stopSchafkopfGame() {
schafkopfGame.stopGame();
}
public void showTrumpf() {
schafkopfGame.showTrumpf();
}
public void showFarbe() {
schafkopfGame.showFarbe();
}
}

View File

@@ -1,56 +0,0 @@
package org.example;
import java.net.URI;
import java.util.concurrent.Future;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.WebSocketClient;
public class EventClient
{
public static void main(String[] args)
{
EventClient client = new EventClient();
URI uri = URI.create("ws://localhost:8080/events/");
try
{
client.run(uri);
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
public void run(URI uri) throws Exception
{
WebSocketClient client = new WebSocketClient();
try
{
client.start();
// The socket that receives events
EventEndpoint socket = new EventEndpoint();
// Attempt Connect
Future<Session> fut = client.connect(socket, uri);
// Wait for Connect
Session session = fut.get();
// Send a message
session.getRemote().sendString("Hello");
// Send another message
session.getRemote().sendString("Goodbye");
// Wait for other side to close
socket.awaitClosure();
// Close session
session.close();
}
finally
{
client.stop();
}
}
}

View File

@@ -1,92 +0,0 @@
package org.example;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import com.google.gson.Gson;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EventEndpoint extends WebSocketAdapter
{
private static final Logger LOG = LoggerFactory.getLogger(EventEndpoint.class);
private final CountDownLatch closureLatch = new CountDownLatch(1);
private Schafkopf schafkopf;
@Override
public void onWebSocketConnect(Session sess)
{
super.onWebSocketConnect(sess);
LOG.debug("Endpoint connected: {}", sess);
System.out.println("Endpoint connected:" + sess);
schafkopf = new Schafkopf(getSession());
try {
schafkopf.initializeCardDeck();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void onWebSocketText(String message)
{
super.onWebSocketText(message);
LOG.debug("Received TEXT message: {}", message);
System.out.println("Received TEXT message:" + message);
if (message.toLowerCase(Locale.US).contains("bye"))
{
getSession().close(StatusCode.NORMAL, "Thanks");
}
if (message.toLowerCase(Locale.US).contains("startsimulation"))
{
try {
Gson gson = new Gson();
String jsonData = gson.toJson("Start");
getRemote().sendString(jsonData);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (message.toLowerCase(Locale.US).contains("stopsimulation"))
{
try {
Gson gson = new Gson();
String jsonData = gson.toJson("Stop");
getRemote().sendString(jsonData);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void onWebSocketClose(int statusCode, String reason)
{
super.onWebSocketClose(statusCode, reason);
LOG.debug("Socket Closed: [{}] {}", statusCode, reason);
closureLatch.countDown();
}
@Override
public void onWebSocketError(Throwable cause)
{
super.onWebSocketError(cause);
cause.printStackTrace(System.err);
}
public void awaitClosure() throws InterruptedException
{
LOG.debug("Awaiting closure from remote");
closureLatch.await();
}
}

View File

@@ -1,77 +0,0 @@
package org.example;
import java.net.URI;
import java.time.Duration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EventServer
{
private static final Logger LOG = LoggerFactory.getLogger(EventServer.class);
public static void main(String[] args) throws Exception
{
EventServer server = new EventServer();
server.setPort(8080);
server.start();
server.join();
}
private final Server server;
private final ServerConnector connector;
public EventServer()
{
server = new Server();
connector = new ServerConnector(server);
server.addConnector(connector);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Configure specific websocket behavior
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) ->
{
// Configure default max size
wsContainer.setMaxTextMessageSize(65535);
wsContainer.setIdleTimeout(Duration.ofDays(300000));
// Add websockets
wsContainer.addMapping("/events/*", new EventEndpointCreator());
});
}
public void setPort(int port)
{
connector.setPort(port);
}
public void start() throws Exception
{
server.start();
}
public URI getURI()
{
return server.getURI();
}
public void stop() throws Exception
{
server.stop();
}
public void join() throws InterruptedException
{
LOG.info("Use Ctrl+C to stop server");
server.join();
}
}

View File

@@ -0,0 +1,73 @@
package org.example;
import com.google.gson.Gson;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
public class FrontendEndpoint extends WebSocketAdapter {
private final CountDownLatch closureLatch = new CountDownLatch(1);
private BackendServer backendServer;
public FrontendEndpoint(BackendServer backendServer) {
this.backendServer = backendServer;
System.out.println("new FrontendEndpoint");
}
@Override
public void onWebSocketConnect(Session session) {
super.onWebSocketConnect(session);
String clientIp = session.getRemoteAddress().toString();
System.out.println("Endpoint connected from ip: " + clientIp);
backendServer.addFrontendEndpoint(this);
}
@Override
public void onWebSocketText(String message) {
super.onWebSocketText(message);
System.out.println("Received TEXT message:" + message);
if (message.contains("startsimulation")) {
backendServer.startSchafkopfGame();
}
if (message.contains("stopsimulation")) {
backendServer.stopSchafkopfGame();
}
if(message.contains("showtrumpf")) {
backendServer.showTrumpf();
}
if(message.contains("showfarben")) {
backendServer.showFarbe();
}
}
@Override
public void onWebSocketClose(int statusCode, String reason) {
super.onWebSocketClose(statusCode, reason);
backendServer.removeFrontendEndpoint(this);
System.out.println("Socket Closed: [" + statusCode + "] " + reason);
closureLatch.countDown();
}
@Override
public void onWebSocketError(Throwable cause) {
super.onWebSocketError(cause);
cause.printStackTrace(System.err);
}
public void sendMessage(String message) {
try {
getRemote().sendString(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -3,11 +3,16 @@ import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest;
import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse;
import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
public class EventEndpointCreator implements JettyWebSocketCreator public class FrontendEndpointCreator implements JettyWebSocketCreator
{ {
private BackendServer backendServer;
public FrontendEndpointCreator(BackendServer backendServer) {
this.backendServer = backendServer;
}
@Override @Override
public Object createWebSocket(JettyServerUpgradeRequest jettyServerUpgradeRequest, JettyServerUpgradeResponse jettyServerUpgradeResponse) public Object createWebSocket(JettyServerUpgradeRequest jettyServerUpgradeRequest, JettyServerUpgradeResponse jettyServerUpgradeResponse)
{ {
return new EventEndpoint(); return new FrontendEndpoint(this.backendServer);
} }
} }

View File

@@ -1,12 +1,32 @@
package org.example; package org.example;
public class Karte { public class Karte {
private int id; private String id;
Karte(int id){ private String name;
private String farbe;
private String symbol;
private int punkte;
Karte(String id, String name, String farbe, String symbol, int punkte){
this.id = id; this.id = id;
this.name = name;
this.farbe = farbe;
this.symbol = symbol;
this.punkte = punkte;
} }
public int getId(){ public String getId(){
return this.id; return this.id;
} }
public String getName(){
return this.name;
}
public String getFarbe(){
return this.farbe;
}
public String getSymbol() {
return this.symbol;
}
} }

View File

@@ -0,0 +1,82 @@
package org.example;
import java.util.ArrayList;
import java.util.List;
public class KartenUtil {
public static List<Karte> getKartenByFarbe(List<Karte> karten, String farbe) {
List<Karte> result = new ArrayList<>();
for (Karte karte : karten) {
if (karte.getFarbe().equalsIgnoreCase(farbe)) {
result.add(karte);
}
}
return result;
}
public static List<Karte> getKartenBySymbol(List<Karte> karten, String symbol) {
List<Karte> result = new ArrayList<>();
for (Karte karte : karten) {
if (karte.getSymbol().equalsIgnoreCase(symbol)) {
result.add(karte);
}
}
return result;
}
public static List<Karte> initializeSchafKopfCardDeck() {
String[] farben = {"schell", "herz", "blatt", "eichel"};
String[] symbole = {"6", "7", "8", "9", "u", "o", "k", "x", "a"};
int totalCards = farben.length * symbole.length;
List<Karte> deck = new ArrayList<>();
for (String farbe : farben) {
for (String symbol : symbole) {
String cardId = farbe + "_" + symbol;
String cardName = getCardName(farbe, symbol);
int wert = switch (symbol) {
case "6", "9", "8", "7" -> 0;
case "k" -> 4;
case "x" -> 10;
case "a" -> 11;
case "u" -> 2;
case "o" -> 3;
default -> -1;
};
deck.add(new Karte(cardId, cardName, farbe, symbol, wert));
}
}
deck.removeAll(KartenUtil.getKartenBySymbol(deck, "6"));
return deck;
}
private static String getCardName(String farbe, String symbol) {
String cardName = switch (farbe) {
case "schell" -> "Schell";
case "herz" -> "Herz";
case "blatt" -> "Blatt";
case "eichel" -> "Eichel";
default -> "";
};
String prefix = switch (symbol) {
case "6" -> "6";
case "7" -> "7";
case "8" -> "8";
case "9" -> "9";
case "k" -> "König";
case "x" -> "10";
case "a" -> "Ass";
case "u" -> "Unter";
case "o" -> "Ober";
default -> "";
};
cardName += " " + prefix;
return cardName;
}
public static void removeCards(List<Karte> allCards, List<Karte> cardsToRemove) {
allCards.removeAll(cardsToRemove);
}
}

View File

@@ -1,17 +1,114 @@
package org.example; package org.example;
import org.eclipse.jetty.websocket.api.Session;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.io.IOException; import org.example.spielController.GeierSpielController;
import org.example.spielController.SoloSpielController;
import org.example.spielController.SpielController;
import org.example.spielController.WenzSpielController;
public class Schafkopf { public class Schafkopf {
private Karte[] deck; private final Karte[] kartenDeck;
private Session session; private final SpielController spielController = new GeierSpielController( "schell");
Schafkopf(Session session){ private final BackendServer server;
this.session = session; private boolean gameState = false;
Schafkopf(BackendServer server) {
this.server = server;
System.out.println("SchaffKopfGame erstellt");
this.kartenDeck = initializeCardDeck();
} }
public void initializeCardDeck() throws IOException {
private static String getCardName(String farbe, String symbol) {
String cardName = switch (farbe) {
case "schell" -> "Schell";
case "herz" -> "Herz";
case "blatt" -> "Blatt";
case "eichel" -> "Eichel";
default -> "";
};
String prefix = switch (symbol) {
case "6" -> "6";
case "7" -> "7";
case "8" -> "8";
case "9" -> "9";
case "k" -> "König";
case "x" -> "10";
case "a" -> "Ass";
case "u" -> "Unter";
case "o" -> "Ober";
default -> "";
};
cardName += " " + prefix;
return cardName;
}
public Karte[] initializeCardDeck() {
String[] farben = {"schell", "herz", "blatt", "eichel"};
String[] symbole = {"6", "7", "8", "9", "k", "x", "a", "u", "o"};
int totalCards = farben.length * symbole.length;
Karte[] Deck = new Karte[totalCards];
int index = 0;
for (String farbe : farben) {
for (String symbol : symbole) {
String cardId = farbe + "_" + symbol;
String cardName = getCardName(farbe, symbol);
int wert = switch (symbol) {
case "6", "9", "8", "7" -> 0;
case "k" -> 4;
case "x" -> 10;
case "a" -> 11;
case "u" -> 2;
case "o" -> 3;
default -> -1;
};
Deck[index] = new Karte(cardId, cardName, farbe, symbol, wert);
index++;
}
}
return Deck;
}
public void showTrumpf() {
Gson gson = new Gson(); Gson gson = new Gson();
String jsonData = gson.toJson("Initialisiere Kartendeck"); for (Karte karte : spielController.getTrumpfKarten()) {
session.getRemote().sendString(jsonData); String karteJson = gson.toJson(karte);
server.sendMessageToAllFrontendEndpoints(karteJson);
}
}
public void showFarbe() {
Gson gson = new Gson();
for (Karte karte : spielController.getFarbKarten()) {
String karteJson = gson.toJson(karte);
server.sendMessageToAllFrontendEndpoints(karteJson);
}
}
public void startGame() {
if (gameState) {
System.out.println("Game already started!");
server.sendMessageToAllFrontendEndpoints("Game already started!");
} else {
gameState = true;
System.out.println("Start Game");
server.sendMessageToAllFrontendEndpoints("Start Game");
}
}
public void stopGame() {
if (!gameState) {
System.out.println("no active Game!");
server.sendMessageToAllFrontendEndpoints("no active Game!");
} else {
gameState = false;
System.out.println("Stop Game");
server.sendMessageToAllFrontendEndpoints("Stop Game");
}
} }
} }

View File

@@ -0,0 +1,31 @@
package org.example.spielController;
import org.example.Karte;
import org.example.KartenUtil;
import java.util.ArrayList;
import java.util.List;
public class GeierSpielController extends SpielController {
public GeierSpielController(String farbe) {
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
List<Karte> oberKarten = KartenUtil.getKartenBySymbol(kartenList, "o");
List<Karte> farbTrumpfKarten = KartenUtil.getKartenByFarbe(kartenList, farbe);
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
farbTrumpfKarten.addAll(oberKarten);
kartenList.removeAll(farbTrumpfKarten);
this.trumpfKarten = new ArrayList<>(farbTrumpfKarten);
this.farbKarten = new ArrayList<>(kartenList);
}
public GeierSpielController() {
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
List<Karte> oberKarten = KartenUtil.getKartenBySymbol(kartenList, "o");
kartenList.removeAll(oberKarten);
this.trumpfKarten = new ArrayList<>(oberKarten);
this.farbKarten = new ArrayList<>(kartenList);
}
}

View File

@@ -0,0 +1,24 @@
package org.example.spielController;
import org.example.Karte;
import org.example.KartenUtil;
import java.util.List;
import java.util.ArrayList;
public class SauSpielController extends SpielController{
public SauSpielController(){
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
List<Karte> herzKarten = KartenUtil.getKartenByFarbe(kartenList, "herz");
herzKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
herzKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
herzKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
herzKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
kartenList.removeAll(herzKarten);
this.trumpfKarten = new ArrayList<>(herzKarten);
this.farbKarten = new ArrayList<>(kartenList);
}
}

View File

@@ -0,0 +1,30 @@
package org.example.spielController;
import org.example.Karte;
import org.example.KartenUtil;
import java.util.ArrayList;
import java.util.List;
public class SoloSpielController extends SpielController {
public SoloSpielController(String farbe) {
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
List<Karte> unterKarten = KartenUtil.getKartenBySymbol(kartenList, "u");
List<Karte> farbTrumpfKarten = KartenUtil.getKartenByFarbe(kartenList, farbe);
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
farbTrumpfKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
farbTrumpfKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
kartenList.removeAll(farbTrumpfKarten);
this.trumpfKarten = new ArrayList<>(farbTrumpfKarten);
this.farbKarten = new ArrayList<>(kartenList);
}
}

View File

@@ -0,0 +1,20 @@
package org.example.spielController;
import org.example.Karte;
import java.util.List;
public abstract class SpielController {
protected List<Karte> trumpfKarten;
protected List<Karte> farbKarten;
public List<Karte> getTrumpfKarten() {
return trumpfKarten;
}
public List<Karte> getFarbKarten() {
return farbKarten;
}
}

View File

@@ -0,0 +1,31 @@
package org.example.spielController;
import org.example.Karte;
import org.example.KartenUtil;
import java.util.ArrayList;
import java.util.List;
public class WenzSpielController extends SpielController {
public WenzSpielController(String farbe) {
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
List<Karte> unterKarten = KartenUtil.getKartenBySymbol(kartenList, "u");
List<Karte> farbTrumpfKarten = KartenUtil.getKartenByFarbe(kartenList, farbe);
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
farbTrumpfKarten.addAll(unterKarten);
kartenList.removeAll(farbTrumpfKarten);
this.trumpfKarten = new ArrayList<>(farbTrumpfKarten);
this.farbKarten = new ArrayList<>(kartenList);
}
public WenzSpielController() {
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
List<Karte> unterKarten = KartenUtil.getKartenBySymbol(kartenList, "u");
kartenList.removeAll(unterKarten);
this.trumpfKarten = new ArrayList<>(unterKarten);
this.farbKarten = new ArrayList<>(kartenList);
}
}