refactored a lot and added possibility to play games on DedicatedServer (#43)

This commit is contained in:
Valentin Heiserer
2024-04-19 16:15:51 +02:00
committed by GitHub
parent 6259d0bef3
commit cab2d36f48
31 changed files with 492 additions and 155 deletions

View File

@@ -1,6 +1,5 @@
package org.schafkopf;
import com.google.gson.JsonObject;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
@@ -25,9 +24,12 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.schafkopf.cardreader.UsbCardReader;
import org.schafkopf.player.BotPlayer;
import org.schafkopf.player.LocalPlayer;
import org.schafkopf.player.Player;
/** Main Class that represents the Backend Server. */
public class BackendServer {
public class BackendServer implements MessageSender {
private final Server server;
private final ServerConnector connector;
private CountDownLatch nfcLatch = new CountDownLatch(1);
@@ -39,6 +41,8 @@ public class BackendServer {
private final List<FrontendEndpoint> frontendEndpoints = new ArrayList<>();
private DedicatedServerConnection dedicatedServerConnection;
/** Creates an Instance of the Backend Server. */
public BackendServer() throws URISyntaxException, IOException {
server = new Server();
@@ -48,7 +52,9 @@ public class BackendServer {
connector.setPort(address.getPort());
server.addConnector(connector);
schafkopfGame = new Schafkopf(this);
schafkopfGame = new Schafkopf(new Player[]{new BotPlayer(), new LocalPlayer(this),
new LocalPlayer(this),
new LocalPlayer(this)}, this);
new UsbCardReader(this);
@@ -86,6 +92,13 @@ public class BackendServer {
startHttpServer();
URI uri = new URI("http://localhost:8081"); // Replace with your target URL
Desktop.getDesktop().browse(uri);
startDedicatedServerConnectionThread();
}
private void startDedicatedServerConnectionThread() {
dedicatedServerConnection = new DedicatedServerConnection(this);
dedicatedServerConnection.connect();
}
private void startHttpServer() {
@@ -147,7 +160,6 @@ public class BackendServer {
/** The main entrypoint of the Application. */
public static void main(String[] args) throws Exception {
BackendServer server = new BackendServer();
server.setPort(8080);
server.start();
server.join();
}
@@ -166,10 +178,6 @@ public class BackendServer {
context.addFilter(cors, "*", types);
}
private void setPort(int port) {
connector.setPort(port);
}
private void start() throws Exception {
server.start();
}
@@ -191,23 +199,12 @@ public class BackendServer {
*
* @param message Message to send (String).
*/
public void sendMessageToAllFrontendEndpoints(String message) {
private void sendMessageToAllFrontendEndpoints(String message) {
for (FrontendEndpoint endpoint : frontendEndpoints) {
endpoint.sendMessage(message);
}
}
/**
* Sends Message to all Frontend Instances.
*
* @param message Message to send (JsonObject).
*/
public void sendMessageToAllFrontendEndpoints(JsonObject message) {
for (FrontendEndpoint endpoint : frontendEndpoints) {
endpoint.sendMessage(message.toString());
}
}
/** method to call to wait for NFC input. */
public String waitForCardScan() throws InterruptedException {
this.readingMode = true;
@@ -234,4 +231,13 @@ public class BackendServer {
this.uidString = uidString;
nfcLatch.countDown();
}
public void startDedicatedServerGame() {
dedicatedServerConnection.start();
}
@Override
public void sendMessage(String message) {
sendMessageToAllFrontendEndpoints(message);
}
}

View File

@@ -0,0 +1,101 @@
package org.schafkopf;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
/** Main Class that represents the Backend Server. */
@WebSocket
public class DedicatedServerConnection {
private final MessageSender messageSender;
private final CountDownLatch closeLatch;
private static Session session;
public DedicatedServerConnection(MessageSender messageSender) {
this.messageSender = messageSender;
this.closeLatch = new CountDownLatch(1);
}
@OnWebSocketConnect
public void onConnect(Session session) {
this.session = session;
System.out.println("Connected to server.");
}
@OnWebSocketMessage
public void onMessage(String message) {
messageSender.sendMessage(message);
System.out.println("Received message from server: " + message);
}
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
System.out.println("Connection closed: " + reason);
closeLatch.countDown();
}
@OnWebSocketError
public void onError(Throwable cause) {
System.err.println("Error occurred: " + cause.getMessage());
}
/** Main Class that represents the Backend Server. */
public static void sendMessage(String message) {
try {
session.getRemote().sendString(message);
System.out.println("Sent message to server: " + message);
} catch (Exception e) {
System.err.println("Error sending message: " + e.getMessage());
}
}
public void awaitClose() throws InterruptedException {
closeLatch.await();
}
/** Main Class that represents the Backend Server. */
public void connect() {
Thread connectionThread = new Thread(() -> {
try {
String serverUri = "ws://localhost:8085/";
WebSocketClient client = new WebSocketClient();
try {
client.start();
//DedicatedServerConnection socketClient = new DedicatedServerConnection();
HeartbeatSender heartbeatSender = new HeartbeatSender(this);
heartbeatSender.start(); // Start sending heartbeat messages
URI uri = new URI(serverUri);
ClientUpgradeRequest request = new ClientUpgradeRequest();
client.connect(this, uri, request);
System.out.println("Connecting to : " + uri);
this.awaitClose();
} catch (Exception e) {
System.err.println("Error connecting to server: " + e.getMessage());
} finally {
try {
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
System.err.println("Error starting dedicated server connection: " + e.getMessage());
}
});
connectionThread.start();
start();
}
public static void start() {
sendMessage("START_GAME");
}
}

View File

@@ -37,17 +37,10 @@ public class FrontendEndpoint extends WebSocketAdapter {
backendServer.schafkopfGame.stopGame();
}
if (message.contains("showtrumpf")) {
backendServer.schafkopfGame.showTrumpf();
if (message.contains("startdedicated")) {
backendServer.startDedicatedServerGame();
}
if (message.contains("showfarben")) {
backendServer.schafkopfGame.showFarbe();
}
if (message.contains("setgame")) {
backendServer.schafkopfGame.setGame(message);
}
}
@Override

View File

@@ -1,80 +0,0 @@
package org.schafkopf;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
/** GameState. */
public class GameState {
public GamePhase getGamePhase() {
return this.gamePhase;
}
/** GamePhase. */
public enum GamePhase {
CHOOSE_GAME("Spiel muss gewählt werden"),
GAME_START("Warten auf das Legen einer Karte"),
TRICK_START("Warten auf das Legen einer Karte"),
WAIT_FOR_CARD("Warten auf das Legen einer Karte"),
PLAYER_CARD("Warten auf das Legen einer Karte"),
PLAYER_TRICK("Spieler sticht"),
GAME_STOP("Spieler sticht");
// Add more phases as needed
private final String description;
GamePhase(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
private GamePhase gamePhase;
private Integer currentPlayer; // Using Integer to allow for null
private Karte card;
private KartenFarbe color;
private boolean trumpf;
// Constructors, getters, and setters
public GameState(GamePhase phase) {
this.gamePhase = phase;
}
public GameState(GamePhase phase, Integer player) {
this.gamePhase = phase;
this.currentPlayer = player;
}
/** GameState. */
public GameState(GamePhase phase, Integer player, Karte card, KartenFarbe color, boolean trumpf) {
this.gamePhase = phase;
this.currentPlayer = player;
this.card = card;
this.color = color;
this.trumpf = trumpf;
}
/** GameState. */
public GameState(GamePhase phase, Integer player, Karte card) {
this.gamePhase = phase;
this.currentPlayer = player;
this.card = card;
}
/** GameState. */
public JsonObject getJson() {
Gson gson = new Gson();
JsonObject jsonObject = new JsonObject();
jsonObject.add("gamestate", gson.toJsonTree(this));
return jsonObject;
}
}

View File

@@ -0,0 +1,26 @@
package org.schafkopf;
import java.util.Timer;
import java.util.TimerTask;
/** Creates an Instance of the Backend Server. */
public class HeartbeatSender {
private static final int HEARTBEAT_INTERVAL = 15000; // 1 minute
private final DedicatedServerConnection client;
public HeartbeatSender(DedicatedServerConnection client) {
this.client = client;
}
/** Creates an Instance of the Backend Server. */
public void start() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
client.sendMessage("HEARTBEAT SYN"); // Send a heartbeat message
}
}, HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL);
}
}

View File

@@ -1,193 +0,0 @@
package org.schafkopf;
import org.schafkopf.GameState.GamePhase;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenUtil;
import org.schafkopf.player.BotPlayer;
import org.schafkopf.player.LocalPlayer;
import org.schafkopf.player.Player;
import org.schafkopf.spielcontroller.FarbGeierController;
import org.schafkopf.spielcontroller.FarbSoloController;
import org.schafkopf.spielcontroller.FarbWenzController;
import org.schafkopf.spielcontroller.GeierController;
import org.schafkopf.spielcontroller.SauSpielController;
import org.schafkopf.spielcontroller.SpielController;
import org.schafkopf.spielcontroller.WenzController;
/** The main class representing the Schafkopf game. */
public class Schafkopf {
private final BackendServer server;
/** The game controller. This is the class that implements the game logic. */
private SpielController spiel = new SauSpielController(0, KartenFarbe.EICHEL);
private final Player[] player = {
new BotPlayer(), new LocalPlayer(this), new LocalPlayer(this), new LocalPlayer(this)
};
private GameState gameState = new GameState(GamePhase.GAME_STOP);
private Thread spielThread;
/**
* Constructor for the Schafkopf class.
*
* @param server The backend server associated with the game.
*/
Schafkopf(BackendServer server) {
this.server = server;
System.out.println("SchaffKopfGame erstellt");
}
public Player[] getPlayer() {
return player;
}
/** Sends all Trumpf Karten of the current GameType to the Frontend. */
public void showTrumpf() {
server.sendMessageToAllFrontendEndpoints(spiel.getTrumpfKarten().getJson());
}
/** Sends all Farb Karten of the current GameType to the Frontend. */
public void showFarbe() {
server.sendMessageToAllFrontendEndpoints(spiel.getFarbKarten().getJson());
}
/** Waits for a Card and returns a Karte Object. */
public Karte wartetAufKarte() {
String uid = null;
System.out.println("Starte Warten auf Karte");
try {
uid = server.waitForCardScan();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Karte karte = KartenUtil.getIdOfUid(uid);
if (karte == null) {
System.out.println("Ungültige Karte");
return wartetAufKarte();
}
System.out.println("Karte gescannt: " + karte.getName());
System.out.println("Beende Warten auf Karte");
return karte;
}
/** Set GameState to "started" and start Game Thread. */
public void startGame() {
if (gameState.getGamePhase() != GamePhase.GAME_STOP) {
System.out.println("Game already started!");
server.sendMessageToAllFrontendEndpoints("Game already started!");
} else {
gameState = new GameState(GamePhase.GAME_START);
setAndSendGameState(gameState);
System.out.println("Start Game");
// KartenListe botHand = KartenUtil.zieheZufallsHand(8);
KartenListe botHand = new KartenListe();
botHand.addKarten(Karte.EICHEL_7);
botHand.addKarten(Karte.SCHELL_7);
botHand.addKarten(Karte.BLATT_7);
botHand.addKarten(Karte.EICHEL_X);
botHand.addKarten(Karte.HERZ_X);
botHand.addKarten(Karte.HERZ_7);
botHand.addKarten(Karte.EICHEL_U);
botHand.addKarten(Karte.EICHEL_O);
for (Player currentPlayer : player) {
if (currentPlayer instanceof BotPlayer botPlayer) {
// Perform actions specific to BotPlayer
botPlayer.setCards(botHand); // Replace with the actual method you want to call
}
}
spielThread = new Thread(() -> new Spielablauf(this, spiel));
spielThread.start();
}
}
/** Set GameState to "stopped" and interrupt Game Thread. */
public void stopGame() {
if (gameState.getGamePhase() == GamePhase.GAME_STOP) {
System.out.println("no active Game!");
server.sendMessageToAllFrontendEndpoints("no active Game!");
} else {
gameState = new GameState(GamePhase.GAME_STOP);
setAndSendGameState(gameState);
}
spielThread.interrupt();
}
/** Set GameType. */
public void setGame(String message) {
System.out.println("Set Game: " + message);
server.sendMessageToAllFrontendEndpoints("Set Game: " + message);
switch (message) {
case "setgame:herzsolo":
this.spiel = new FarbSoloController(0, KartenFarbe.HERZ);
break;
case "setgame:blattsolo":
this.spiel = new FarbSoloController(0, KartenFarbe.BLATT);
break;
case "setgame:eichelsolo":
this.spiel = new FarbSoloController(0, KartenFarbe.EICHEL);
break;
case "setgame:schellsolo":
this.spiel = new FarbSoloController(0, KartenFarbe.SCHELL);
break;
case "setgame:wenz":
this.spiel = new WenzController(0);
break;
case "setgame:geier":
this.spiel = new GeierController(0);
break;
case "setgame:eichelwenz":
this.spiel = new FarbWenzController(0, KartenFarbe.EICHEL);
break;
case "setgame:herzwenz":
this.spiel = new FarbWenzController(0, KartenFarbe.HERZ);
break;
case "setgame:blattwenz":
this.spiel = new FarbWenzController(0, KartenFarbe.BLATT);
break;
case "setgame:schellwenz":
this.spiel = new FarbWenzController(0, KartenFarbe.SCHELL);
break;
case "setgame:eichelgeier":
this.spiel = new FarbGeierController(0, KartenFarbe.EICHEL);
break;
case "setgame:herzgeier":
this.spiel = new FarbGeierController(0, KartenFarbe.HERZ);
break;
case "setgame:blattgeier":
this.spiel = new FarbGeierController(0, KartenFarbe.BLATT);
break;
case "setgame:schellgeier":
this.spiel = new FarbGeierController(0, KartenFarbe.SCHELL);
break;
case "setgame:sauspiel":
this.spiel = new SauSpielController(0, KartenFarbe.EICHEL);
break;
default:
System.out.println("Ungültiges Spiel");
}
}
public void setAndSendGameState(GameState gameState) {
this.gameState = gameState;
this.server.sendMessageToAllFrontendEndpoints(this.gameState.getJson());
}
public GameState getGameState() {
return this.gameState;
}
}

View File

@@ -1,86 +0,0 @@
package org.schafkopf;
import org.schafkopf.GameState.GamePhase;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.player.Player;
import org.schafkopf.spielcontroller.SpielController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** The main class that controlls the game flow. */
public class Spielablauf {
private static final Logger logger = LoggerFactory.getLogger(Spielablauf.class);
private final KartenListe gespielteKarten = new KartenListe();
private final KartenListe tischKarten = new KartenListe();
private final SpielController spiel;
private final Player[] players;
private final Schafkopf schafkopf;
Spielablauf(Schafkopf schafkopf, SpielController spiel) {
this.schafkopf = schafkopf;
this.spiel = spiel;
this.players = schafkopf.getPlayer();
playRound();
}
private void playRound() {
int startingPlayer = 0;
logger.info("Starte Stiche");
for (int i = 0; i < 8; i++) {
logger.info("Stich: {}", i);
startingPlayer = playTrick(startingPlayer);
}
schafkopf.stopGame();
}
private int playTrick(int startingPlayer) {
schafkopf.setAndSendGameState(new GameState(GamePhase.TRICK_START));
for (int i = 0; i < 4; i++) {
int currentPlayer = (i + startingPlayer) % 4;
logger.info("Spieler ist dran: {}", currentPlayer);
schafkopf.setAndSendGameState(new GameState(GamePhase.WAIT_FOR_CARD, currentPlayer));
Karte playedCard = players[currentPlayer].play(spiel, tischKarten, gespielteKarten);
tischKarten.addKarten(playedCard);
schafkopf.setAndSendGameState(
new GameState(
GamePhase.PLAYER_CARD,
currentPlayer,
playedCard,
tischKarten.getByIndex(0).getFarbe(),
spiel.isTrumpf(tischKarten.getByIndex(0))));
}
int stichSpieler = SpielController.welcheKarteSticht(tischKarten);
logger.info("Stiche ende");
int winningPlayerIndex = (startingPlayer + stichSpieler) % 4;
logger.warn("Karte sticht: {}", winningPlayerIndex);
schafkopf.setAndSendGameState(
new GameState(
GamePhase.PLAYER_TRICK, winningPlayerIndex, tischKarten.getByIndex(stichSpieler)));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
logger.error("error sleep");
}
gespielteKarten.addKarten(tischKarten);
tischKarten.clear();
return winningPlayerIndex;
}
}

View File

@@ -1,6 +1,7 @@
package org.schafkopf.cardreader;
import com.fazecast.jSerialComm.SerialPort;
import com.sun.tools.jconsole.JConsoleContext;
import io.github.cdimascio.dotenv.Dotenv;
import java.io.UnsupportedEncodingException;
import org.schafkopf.BackendServer;
@@ -10,7 +11,7 @@ public class UsbCardReader extends CardReader {
private volatile boolean isRunning = true;
Dotenv dotenv = Dotenv.configure().directory("./").load();
private final String comPort = dotenv.get("COM_PORT");
private String comPort = null;
/**
* Creates an Instance of the KartenLeser.
@@ -19,7 +20,6 @@ public class UsbCardReader extends CardReader {
*/
public UsbCardReader(BackendServer server) {
super(server);
new Thread(this::run).start();
}
@@ -27,29 +27,46 @@ public class UsbCardReader extends CardReader {
isRunning = false;
}
/** run the reader. */
/** Run the reader. */
public void run() {
SerialPort[] ports = SerialPort.getCommPorts();
SerialPort selectedPort = null;
// SerialPort[] ports = SerialPort.getCommPorts();
//
// for (SerialPort port : ports) {
// if (port.openPort()) {
// System.out.println(port.getSystemPortName());
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// // Read any data available on the serial port
// byte[] initialBuffer = new byte[port.bytesAvailable()];
// int initialBytesRead = port.readBytes(initialBuffer, initialBuffer.length);
// String initialData = null;
// try {
// initialData = new String(initialBuffer, 0, initialBytesRead, "UTF-8").trim();
// } catch (UnsupportedEncodingException e) {
// throw new RuntimeException(e);
// }
// System.out.print("Raw data: ");
// for (byte b : initialBuffer) {
// System.out.print(b + " ");
// }
// System.out.println(initialData);
// if (initialData.contains("Adafruit PN532 NFC Marker")) {
// comPort = port.getSystemPortName();
// }
// }
// }
for (SerialPort port : ports) {
if (port.getSystemPortName().equals(this.comPort)) {
selectedPort = port;
break;
}
}
comPort = dotenv.get("COM_PORT");
if (selectedPort == null) {
System.out.println(this.comPort + " not found");
if (comPort == null) {
System.out.println("Adafruit PN532 NFC device not found");
return;
}
if (ports.length == 0) {
System.out.println("No serial ports found");
return;
}
SerialPort serialPort = selectedPort; // You may need to adjust this based on your setup
SerialPort serialPort = SerialPort.getCommPort(comPort);
serialPort.setBaudRate(115200);
if (serialPort.openPort()) {
@@ -60,8 +77,9 @@ public class UsbCardReader extends CardReader {
if (serialPort.bytesAvailable() > 0) {
byte[] buffer = new byte[serialPort.bytesAvailable()];
int bytesRead = serialPort.readBytes(buffer, buffer.length);
String data = new String(buffer, 0, bytesRead, "UTF-8").trim();
// Process the received data
server.nfcGelesen(data);
}

View File

@@ -1,43 +0,0 @@
package org.schafkopf.player;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenUtil;
import org.schafkopf.spielcontroller.SpielController;
/** Player that represents the Bot. */
public class BotPlayer extends Player {
private KartenListe eigeneKarten;
private KartenListe unbekannteKarten = KartenUtil.initializeSchafKopfCardDeck();
public BotPlayer() {
// TODO document why this constructor is empty
}
@Override
public Karte play(SpielController spiel, KartenListe tischKarten, KartenListe gespielteKarten) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Karte card = spiel.welcheKarteSpielIch(true, gespielteKarten, eigeneKarten, tischKarten);
eigeneKarten.removeKarten(card);
System.out.println("Eigene Karte legen");
return card;
}
/** Set the Cards of the Player. */
public void setCards(KartenListe cards) {
System.out.println("Eigene Karte setzen");
this.eigeneKarten = cards;
this.unbekannteKarten = KartenUtil.initializeSchafKopfCardDeck();
this.unbekannteKarten.removeKarten(eigeneKarten);
System.out.println("Eigene Karte fertig");
}
}

View File

@@ -1,8 +1,9 @@
package org.schafkopf.player;
import org.schafkopf.Schafkopf;
import org.schafkopf.BackendServer;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenUtil;
import org.schafkopf.spielcontroller.SpielController;
/**
@@ -10,14 +11,35 @@ import org.schafkopf.spielcontroller.SpielController;
*/
public class LocalPlayer extends Player {
private final Schafkopf schafkopf;
private final BackendServer server;
public LocalPlayer(Schafkopf schafkopf) {
this.schafkopf = schafkopf;
public LocalPlayer(BackendServer server) {
this.server = server;
}
@Override
public Karte play(SpielController spiel, KartenListe tischKarten, KartenListe gespielteKarten) {
return schafkopf.wartetAufKarte();
return wartetAufKarte();
}
/** Waits for a Card and returns a Karte Object. */
private Karte wartetAufKarte() {
String uid = null;
System.out.println("Starte Warten auf Karte");
try {
uid = server.waitForCardScan();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Karte karte = KartenUtil.getIdOfUid(uid);
if (karte == null) {
System.out.println("Ungültige Karte");
return wartetAufKarte();
}
System.out.println("Karte gescannt: " + karte.getName());
System.out.println("Beende Warten auf Karte");
return karte;
}
}

View File

@@ -1,11 +0,0 @@
package org.schafkopf.player;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.spielcontroller.SpielController;
/** Class that represents one Player of the game. */
public abstract class Player {
public abstract Karte play(
SpielController spiel, KartenListe tischKarten, KartenListe gespielteKarten);
}

View File

@@ -1,36 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenSymbol;
import org.schafkopf.karte.KartenUtil;
/** SpielController that implements Logic of a Farb Geier. */
public class FarbGeierController extends SoloController {
/**
* Create instance of SpielController.
*
* @param farbe Trumpffarbe of the Farb Geier.
*/
public FarbGeierController(int activePlayer, KartenFarbe farbe) {
super(activePlayer);
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
KartenListe oberKarten = kartenList.getKarten(KartenSymbol.OBER);
KartenListe farbTrumpfKarten = kartenList.getKarten(farbe);
farbTrumpfKarten.removeKarten(KartenSymbol.OBER);
farbTrumpfKarten.addKarten(oberKarten);
kartenList.removeKarten(farbTrumpfKarten);
this.trumpfKarten = new KartenListe(farbTrumpfKarten);
this.farbKarten = new KartenListe(kartenList);
}
public Karte welcheKarteSpielIch(
boolean istSpieler,
KartenListe gespielteKarten,
KartenListe meineHand,
KartenListe tischKarten) {
return null;
}
}

View File

@@ -1,40 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenSymbol;
import org.schafkopf.karte.KartenUtil;
/** SpielController that implements Logic of a Farb Solo. */
public class FarbSoloController extends SoloController {
/**
* Create instance of SpielController.
*
* @param farbe Trumpffarbe of the Farb Solo.
*/
public FarbSoloController(int activePlayer, KartenFarbe farbe) {
super(activePlayer);
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
KartenListe unterKarten = kartenList.getKarten(KartenSymbol.UNTER);
KartenListe farbTrumpfKarten = kartenList.getKarten(farbe);
farbTrumpfKarten.removeKarten(KartenSymbol.UNTER);
farbTrumpfKarten.removeKarten(KartenSymbol.OBER);
farbTrumpfKarten.addKarten(kartenList.getKarten(KartenSymbol.UNTER));
farbTrumpfKarten.addKarten(kartenList.getKarten(KartenSymbol.OBER));
kartenList.removeKarten(farbTrumpfKarten);
this.trumpfKarten = new KartenListe(farbTrumpfKarten);
this.farbKarten = new KartenListe(kartenList);
}
public Karte welcheKarteSpielIch(
boolean istSpieler,
KartenListe gespielteKarten,
KartenListe meineHand,
KartenListe tischKarten) {
return null;
}
}

View File

@@ -1,36 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenSymbol;
import org.schafkopf.karte.KartenUtil;
/** SpielController that implements Logic of a Farb Wenz. */
public class FarbWenzController extends SoloController {
/**
* Create instance of SpielController.
*
* @param farbe Trumpffarbe of the Farb Wenz.
*/
public FarbWenzController(int activePlayer, KartenFarbe farbe) {
super(activePlayer);
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
KartenListe unterKarten = kartenList.getKarten(KartenSymbol.UNTER);
KartenListe farbTrumpfKarten = kartenList.getKarten(farbe);
farbTrumpfKarten.removeKarten(KartenSymbol.UNTER);
farbTrumpfKarten.addKarten(unterKarten);
kartenList.removeKarten(farbTrumpfKarten);
this.trumpfKarten = new KartenListe(farbTrumpfKarten);
this.farbKarten = new KartenListe(kartenList);
}
public Karte welcheKarteSpielIch(
boolean istSpieler,
KartenListe gespielteKarten,
KartenListe meineHand,
KartenListe tischKarten) {
return null;
}
}

View File

@@ -1,24 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenSymbol;
import org.schafkopf.karte.KartenUtil;
/**
* SpielController that implements Logic of a Geier Game.
*/
public class GeierController extends GeierWenzController {
/**
* Create instance of Geier Game.
*/
public GeierController(int activePlayer) {
super(activePlayer);
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
KartenListe oberKarten = kartenList.getKarten(KartenSymbol.OBER);
kartenList.removeKarten(oberKarten);
this.trumpfKarten = new KartenListe(oberKarten);
this.farbKarten = new KartenListe(kartenList);
}
}

View File

@@ -1,20 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenListe;
/**
* SpielController that implements Logic of a Geier/Wenz Game.
*/
public class GeierWenzController extends SoloController {
public GeierWenzController(int activePlayer) {
super(activePlayer);
}
@Override
public Karte welcheKarteSpielIch(boolean istSpieler, KartenListe gespielteKarten,
KartenListe meineHand, KartenListe tischKarten) {
return null;
}
}

View File

@@ -1,58 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
/** SpielController that implements Logic of a Sau Spiel Game. */
public class SauSpielController extends StandardController {
KartenFarbe suchFarbe;
/** Class that represents one Card of the game. */
public SauSpielController(int activePlayer, KartenFarbe farbe) {
super(activePlayer);
this.suchFarbe = farbe;
}
/** choose witch Card should be played with the right Game logic. */
public Karte welcheKarteSpielIch(
boolean istSpieler,
KartenListe gespielteKarten,
KartenListe meineHand,
KartenListe tischKarten) {
System.out.println("Ich spiele eine Karte Sauspiel");
int spielerNummer = tischKarten.size();
switch (spielerNummer) {
case 0:
if (istSpieler) {
return meineHand.getLast();
} else {
return meineHand.getByIndex(0);
}
case 1:
if (istSpieler) {
return farbeZugeben(meineHand, tischKarten.getByIndex(0), 2);
} else {
return farbeZugeben(meineHand, tischKarten.getByIndex(0), 0);
}
case 2:
if (istSpieler) {
return farbeZugeben(meineHand, tischKarten.getByIndex(0), 2);
} else {
return farbeZugeben(meineHand, tischKarten.getByIndex(0), 0);
}
case 3:
if (istSpieler) {
return farbeZugeben(meineHand, tischKarten.getByIndex(0), 2);
} else {
return farbeZugeben(meineHand, tischKarten.getByIndex(0), 0);
}
default:
System.out.println("Ungültige SpielerNummer");
}
return null;
}
}

View File

@@ -1,19 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenListe;
/**
* abstract Class that represents Logic of a Solo like Game.
*/
public abstract class SoloController extends SpielController {
SoloController(int activePlayer) {
super(activePlayer);
}
public Karte welcheKarteSpielIch(
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten) {
return null;
}
}

View File

@@ -1,133 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenUtil;
/** Base Class of Game Controllers. */
public abstract class SpielController {
protected static KartenListe trumpfKarten;
protected static KartenListe farbKarten;
protected static int activePlayer;
public SpielController(int activePlayer) {
this.activePlayer = activePlayer;
}
/**
* Create instance of SpielController.
*
* @param meineHand Cards one Player holds.
* @param ersteKarte color the Player has to play.
* @param mode Mode the player chooses a Card if multiple are available.
*/
public static Karte farbeZugeben(KartenListe meineHand, Karte ersteKarte, int mode) {
KartenListe hand = new KartenListe(meineHand);
sortiereKarten(hand);
boolean trumpfGespielt = trumpfKarten.containsKarte(ersteKarte);
KartenListe handTrumpfKarten = hand.removeKarten(trumpfKarten);
KartenListe handfarbKarten;
if (trumpfGespielt) {
handfarbKarten = handTrumpfKarten;
} else {
handfarbKarten = hand.getKarten(ersteKarte.getFarbe());
}
if (handfarbKarten.size() == 1) {
return handfarbKarten.getByIndex(0);
} else if (handfarbKarten.size() > 1) {
return switch (mode) {
case 0 -> // Abspatzen
handfarbKarten.getByIndex(0);
case 1, 2 -> // Stechen // Schmieren
handfarbKarten.getLast();
default -> null;
};
}
if (handfarbKarten.isEmpty()) {
switch (mode) {
case 0: // Abspatzen
return hand.getByIndex(0);
case 1: // Schmieren
return hand.getLast();
case 2: // Stechen
if (!handTrumpfKarten.isEmpty()) {
return handTrumpfKarten.getLast(); // trumpf reinspielen
} else {
return hand.getByIndex(0); // wenn kein Trumpf und farblos, abschpatzen
}
default:
return null;
}
}
return null;
}
/**
* sorts Cards, so they are in the right order for the active game.
*
* @param karten Trumpffarbe of the Farb Geier.
*/
public static void sortiereKarten(KartenListe karten) {
KartenListe kartenReihenfolge = new KartenListe(farbKarten);
kartenReihenfolge.addKarten(trumpfKarten);
KartenListe kartenListe = KartenUtil.initializeSchafKopfCardDeck();
kartenListe.removeKarten(karten);
kartenReihenfolge.removeKarten(kartenListe);
karten.clear();
karten.addKarten(kartenReihenfolge);
}
/**
* checks, which card has the highest strength and will win one Stich.
*
* @param karten Cards to check.
*/
public static int welcheKarteSticht(KartenListe karten) {
KartenListe kartenNew = new KartenListe(karten);
sortiereKarten(kartenNew);
KartenListe farbTischKarten = kartenNew.removeKarten(trumpfKarten);
System.out.println("trumpfKarten:");
System.out.println(trumpfKarten.getJson());
if (!farbTischKarten.isEmpty()) {
System.out.println("trumpfkarten:");
System.out.println(farbTischKarten.getJson());
return karten.indexOf(farbTischKarten.getLast());
} else {
KartenFarbe firstColor = karten.getByIndex(0).getFarbe();
KartenListe firstColorCards = kartenNew.removeKarten(firstColor);
System.out.println("firstcolor:");
System.out.println(firstColorCards.getJson());
return karten.indexOf(firstColorCards.getLast());
}
}
public abstract Karte welcheKarteSpielIch(
boolean istSpieler,
KartenListe gespielteKarten,
KartenListe meineHand,
KartenListe tischKarten);
public KartenListe getTrumpfKarten() {
return trumpfKarten;
}
public boolean isTrumpf(Karte card) {
return trumpfKarten.containsKarte(card);
}
public KartenListe getFarbKarten() {
return farbKarten;
}
}

View File

@@ -1,33 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.Karte;
import org.schafkopf.karte.KartenFarbe;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenSymbol;
import org.schafkopf.karte.KartenUtil;
/** SpielController that has the standard Card Deck for Sauspiel, Bettel und Co. */
public abstract class StandardController extends SpielController {
StandardController(int activePlayer) {
super(activePlayer);
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
KartenListe herzKarten = kartenList.getKarten(KartenFarbe.HERZ);
herzKarten.removeKarten(KartenSymbol.UNTER);
herzKarten.removeKarten(KartenSymbol.OBER);
herzKarten.addKarten(kartenList.getKarten(KartenSymbol.UNTER));
herzKarten.addKarten(kartenList.getKarten(KartenSymbol.OBER));
kartenList.removeKarten(herzKarten);
this.trumpfKarten = new KartenListe(herzKarten);
this.farbKarten = new KartenListe(kartenList);
}
public abstract Karte welcheKarteSpielIch(
boolean istSpieler,
KartenListe gespielteKarten,
KartenListe meineHand,
KartenListe tischKarten);
}

View File

@@ -1,25 +0,0 @@
package org.schafkopf.spielcontroller;
import org.schafkopf.karte.KartenListe;
import org.schafkopf.karte.KartenSymbol;
import org.schafkopf.karte.KartenUtil;
/**
* SpielController that implements Logic of a Wenz Game.
*/
public class WenzController extends GeierWenzController {
/**
* Create instance of Wenz Game.
*/
public WenzController(int activePlayer) {
super(activePlayer);
this.activePlayer = activePlayer;
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
KartenListe unterKarten = kartenList.getKarten(KartenSymbol.UNTER);
kartenList.removeKarten(unterKarten);
this.trumpfKarten = new KartenListe(unterKarten);
this.farbKarten = new KartenListe(kartenList);
}
}