Browse Source

Merge branch 'GameUI' into 'main'

add Game UI

See merge request fdai7736/onses!30
main
fdai7736 11 months ago
parent
commit
a42c838a13
  1. 3
      README.md
  2. 44
      src/main/java/de/hsfulda/onses/App.java
  3. 32
      src/main/java/de/hsfulda/onses/controllers/AppController.java
  4. 102
      src/main/java/de/hsfulda/onses/controllers/CardController.java
  5. 4
      src/main/java/de/hsfulda/onses/controllers/Controller.java
  6. 92
      src/main/java/de/hsfulda/onses/controllers/GameController.java
  7. 40
      src/main/java/de/hsfulda/onses/controllers/GameOverController.java
  8. 30
      src/main/java/de/hsfulda/onses/controllers/PlayerController.java
  9. 25
      src/main/java/de/hsfulda/onses/models/Card.java
  10. 3
      src/main/java/de/hsfulda/onses/models/Game.java
  11. 4
      src/main/java/de/hsfulda/onses/models/Player.java
  12. 52
      src/main/java/de/hsfulda/onses/services/GameService.java
  13. 30
      src/main/java/de/hsfulda/onses/services/PlayerService.java
  14. 6
      src/main/resources/de/hsfulda/onses/views/app.fxml
  15. 11
      src/main/resources/de/hsfulda/onses/views/game.fxml
  16. 22
      src/main/resources/de/hsfulda/onses/views/gameOver.fxml
  17. 10
      src/test/java/de/hsfulda/onses/CardTest.java
  18. 89
      src/test/java/de/hsfulda/onses/GameServiceTest.java
  19. 4
      src/test/java/de/hsfulda/onses/GuiTest.java
  20. 11
      src/test/java/de/hsfulda/onses/PlayerTest.java

3
README.md

@ -1,5 +1,8 @@
# Onses - Uno Game # Onses - Uno Game
## Disclaimer for Tests
**!!Do not move the mouse while tests are running!!**
## git setup after clone ## git setup after clone
```shell ```shell
git config user.name "<FD-Nummer>" git config user.name "<FD-Nummer>"

44
src/main/java/de/hsfulda/onses/App.java

@ -1,18 +1,54 @@
package de.hsfulda.onses; package de.hsfulda.onses;
import de.hsfulda.onses.controllers.AppController; import de.hsfulda.onses.controllers.AppController;
import de.hsfulda.onses.controllers.Controller;
import de.hsfulda.onses.services.GameService; import de.hsfulda.onses.services.GameService;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage; import javafx.stage.Stage;
import java.io.IOException;
public class App extends Application { public class App extends Application {
private Stage stage;
private Controller controller;
private final GameService gameService;
public App() {
this(new GameService());
}
public App(GameService gameService) {
this.gameService = gameService;
}
@Override @Override
public void start(Stage stage) throws Exception {
final AppController appController = new AppController(new GameService(), stage);
public void start(Stage stage) {
this.stage = stage;
final AppController appController = new AppController(this, this.gameService);
stage.setScene(new Scene(new Label("Loading...")));
stage.setOnCloseRequest(e -> controller.destroy());
stage.setTitle("Onses - Uno");
stage.setScene(new Scene(appController.render()));
show(appController);
stage.show(); stage.show();
} }
public void show(Controller controller) {
try {
final Parent parent = controller.render();
stage.getScene().setRoot(parent);
} catch (IOException e) {
throw new RuntimeException(e);
}
if(this.controller != null) {
this.controller.destroy();
}
this.controller = controller;
stage.setTitle(controller.getTitle());
}
} }

32
src/main/java/de/hsfulda/onses/controllers/AppController.java

@ -1,13 +1,11 @@
package de.hsfulda.onses.controllers; package de.hsfulda.onses.controllers;
import de.hsfulda.onses.App;
import de.hsfulda.onses.Main; import de.hsfulda.onses.Main;
import de.hsfulda.onses.models.Game;
import de.hsfulda.onses.services.GameService; import de.hsfulda.onses.services.GameService;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.stage.Stage;
import java.io.IOException; import java.io.IOException;
import java.util.Objects; import java.util.Objects;
@ -15,26 +13,32 @@ import java.util.Objects;
public class AppController implements Controller { public class AppController implements Controller {
private final GameService gameService; private final GameService gameService;
private final Stage stage;
private final App app;
public AppController(GameService gameService, Stage stage) {
this.gameService = gameService;
this.stage = stage;
public AppController(App app, GameService gameService) {
this.app = app;
this.gameService = gameService;
} }
@Override @Override
public Parent render() throws IOException { public Parent render() throws IOException {
GameController gameController = new GameController(gameService);
GameController gameController = new GameController(app, gameService);
final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/app.fxml"))); final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/app.fxml")));
Button button = (Button) parent.lookup("#startGameBtn"); Button button = (Button) parent.lookup("#startGameBtn");
button.setOnAction(e -> { button.setOnAction(e -> {
try {
stage.setScene(new Scene(gameController.render()));
stage.setTitle("Onses - Uno Game");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
app.show(gameController);
}); });
return parent; return parent;
} }
@Override
public String getTitle() {
return "Onses - Uno";
}
@Override
public void destroy() {
}
} }

102
src/main/java/de/hsfulda/onses/controllers/CardController.java

@ -2,51 +2,98 @@ package de.hsfulda.onses.controllers;
import de.hsfulda.onses.Main; import de.hsfulda.onses.Main;
import de.hsfulda.onses.models.Card; import de.hsfulda.onses.models.Card;
import de.hsfulda.onses.models.Player;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import java.beans.PropertyChangeListener;
import java.io.IOException; import java.io.IOException;
import java.util.Objects; import java.util.Objects;
public class CardController implements Controller { public class CardController implements Controller {
private Card card;
private final Card card;
private final Player player;
public CardController(Card card) {
private PropertyChangeListener cardSelectedChangeListener;
private PropertyChangeListener cardColorChangeListener;
public CardController(Card card, Player player) {
this.card = card; this.card = card;
this.player = player;
} }
@Override @Override
public Parent render() throws IOException { public Parent render() throws IOException {
final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/card.fxml"))); final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/card.fxml")));
final Pane mainPane = (Pane) parent.lookup("#cardPane"); final Pane mainPane = (Pane) parent.lookup("#cardPane");
final Label cardName = (Label) parent.lookup("#labelName"); final Label cardName = (Label) parent.lookup("#labelName");
switch(card.getColor()) {
case RED -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: red"));
case BLUE -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: blue"));
case GREEN -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: green"));
case YELLOW -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: yellow"));
default -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: black"));
if(!card.isFacedown()) {
switch(card.getColor()) {
case RED -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: red"));
case BLUE -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: blue"));
case GREEN -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: green"));
case YELLOW -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: yellow"));
default -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: black"));
}
}
if(card.isFacedown()) {
cardName.setText("Card");
} else {
switch(card.getValue()) {
case ONE -> cardName.setText("1");
case TWO -> cardName.setText("2");
case THREE -> cardName.setText("3");
case FOUR -> cardName.setText("4");
case FIVE -> cardName.setText("5");
case SIX -> cardName.setText("6");
case SEVEN -> cardName.setText("7");
case EIGHT -> cardName.setText("8");
case NINE -> cardName.setText("9");
case SKIP -> cardName.setText("skip player");
case CHOOSE -> cardName.setText("wish card");
case DRAWTWO -> cardName.setText("+2");
case REVERSE -> cardName.setText("reverse");
case CHOOSEDRAW -> cardName.setText("+4");
}
} }
switch(card.getValue()) {
case ONE -> cardName.setText("1");
case TWO -> cardName.setText("2");
case THREE -> cardName.setText("3");
case FOUR -> cardName.setText("4");
case FIVE -> cardName.setText("5");
case SIX -> cardName.setText("6");
case SEVEN -> cardName.setText("7");
case EIGHT -> cardName.setText("8");
case NINE -> cardName.setText("9");
case SKIP -> cardName.setText("skip player");
case CHOOSE -> cardName.setText("wish card");
case DRAWTWO -> cardName.setText("+2");
case REVERSE -> cardName.setText("reverse");
if(player != null && !player.isEnemy()) {
mainPane.setOnMousePressed(e -> {
Card oldCard = player.getCurrentCard();
if(oldCard != null) {
oldCard.setSelected(false);
}
player.setCurrentCard(card);
card.setSelected(true);
});
} }
cardSelectedChangeListener = e -> {
boolean oldValue = (boolean) e.getOldValue();
if(oldValue) {
mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-border-color: black"));
} else {
mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-border-color: pink"));
}
};
card.listeners().addPropertyChangeListener(Card.PROPERTY_SELECTED, cardSelectedChangeListener);
cardColorChangeListener = e -> {
switch((Card.Color)e.getNewValue()) {
case RED -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: red"));
case BLUE -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: blue"));
case GREEN -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: green"));
case YELLOW -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: yellow"));
default -> mainPane.setStyle(addStyle(mainPane.getStyle(), "-fx-background-color: black"));
}
};
card.listeners().addPropertyChangeListener(Card.PROPERTY_COLOR, cardColorChangeListener);
return parent; return parent;
} }
@ -54,4 +101,15 @@ public class CardController implements Controller {
private String addStyle(String oldStyle, String newStyle) { private String addStyle(String oldStyle, String newStyle) {
return oldStyle + "; " + newStyle; return oldStyle + "; " + newStyle;
} }
@Override
public String getTitle() {
return "Onses - Uno Game";
}
@Override
public void destroy() {
card.listeners().removePropertyChangeListener(Card.PROPERTY_SELECTED, cardSelectedChangeListener);
card.listeners().removePropertyChangeListener(Card.PROPERTY_COLOR, cardColorChangeListener);
}
} }

4
src/main/java/de/hsfulda/onses/controllers/Controller.java

@ -6,4 +6,8 @@ import java.io.IOException;
public interface Controller { public interface Controller {
Parent render() throws IOException; Parent render() throws IOException;
void destroy();
String getTitle();
} }

92
src/main/java/de/hsfulda/onses/controllers/GameController.java

@ -1,5 +1,6 @@
package de.hsfulda.onses.controllers; package de.hsfulda.onses.controllers;
import de.hsfulda.onses.App;
import de.hsfulda.onses.Main; import de.hsfulda.onses.Main;
import de.hsfulda.onses.models.Card; import de.hsfulda.onses.models.Card;
import de.hsfulda.onses.models.Game; import de.hsfulda.onses.models.Game;
@ -9,16 +10,26 @@ import javafx.scene.Parent;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import java.beans.PropertyChangeListener;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
public class GameController implements Controller { public class GameController implements Controller {
private final GameService gameService; private final GameService gameService;
private final Game game; private final Game game;
public GameController(GameService gameService) {
private final App app;
private PropertyChangeListener lastPlayedCardPropertyChangeListener;
private PropertyChangeListener gameOverListener;
private final ArrayList<Controller> controllers = new ArrayList<>();
public GameController(App app, GameService gameService) {
this.app = app;
this.gameService = gameService; this.gameService = gameService;
this.game = gameService.getGame(); this.game = gameService.getGame();
} }
@Override @Override
public Parent render() throws IOException { public Parent render() throws IOException {
final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/game.fxml"))); final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/game.fxml")));
@ -26,22 +37,79 @@ public class GameController implements Controller {
final Pane enemyPane = (Pane) parent.lookup("#enemyPane"); final Pane enemyPane = (Pane) parent.lookup("#enemyPane");
final Pane playerPane = (Pane) parent.lookup("#playerPane"); final Pane playerPane = (Pane) parent.lookup("#playerPane");
final Button playButton = (Button) parent.lookup("#playCardBtn"); final Button playButton = (Button) parent.lookup("#playCardBtn");
final Button drawCardButton = (Button) parent.lookup("#drawCardBtn");
final Button exitGameButton = (Button) parent.lookup("#exitBtn");
final Button wishRedButton = (Button) parent.lookup("#btnWishRed");
final Button wishBlueButton = (Button) parent.lookup("#btnWishBlue");
final Button wishGreenButton = (Button) parent.lookup("#btnWishGreen");
final Button wishYellowButton = (Button) parent.lookup("#btnWishYellow");
CardController lastPlayedCardController = new CardController(game.getLastPlayedCard());
CardController lastPlayedCardController = new CardController(game.getLastPlayedCard(), null);
PlayerController playerController = new PlayerController(gameService.getGame().getPlayerService().getPlayerList().getFirst()); PlayerController playerController = new PlayerController(gameService.getGame().getPlayerService().getPlayerList().getFirst());
PlayerController enemyController = new PlayerController(gameService.getGame().getPlayerService().getPlayerList().getLast()); PlayerController enemyController = new PlayerController(gameService.getGame().getPlayerService().getPlayerList().getLast());
game.listeners().addPropertyChangeListener(Game.PROPERTY_LAST_PLAYED_CARD, e -> {
controllers.add(lastPlayedCardController);
controllers.add(playerController);
controllers.add(enemyController);
wishRedButton.setOnAction(e -> {
Card currentSelectedCard = game.getPlayerService().getPlayerList().getFirst().getCurrentCard();
currentSelectedCard.setColor(Card.Color.RED);
});
wishBlueButton.setOnAction(e -> {
Card currentSelectedCard = game.getPlayerService().getPlayerList().getFirst().getCurrentCard();
currentSelectedCard.setColor(Card.Color.BLUE);
});
wishGreenButton.setOnAction(e -> {
Card currentSelectedCard = game.getPlayerService().getPlayerList().getFirst().getCurrentCard();
currentSelectedCard.setColor(Card.Color.GREEN);
});
wishYellowButton.setOnAction(e -> {
Card currentSelectedCard = game.getPlayerService().getPlayerList().getFirst().getCurrentCard();
currentSelectedCard.setColor(Card.Color.YELLOW);
});
lastPlayedCardPropertyChangeListener = e -> {
lastPlayedCardPane.getChildren().removeAll(); lastPlayedCardPane.getChildren().removeAll();
try { try {
lastPlayedCardPane.getChildren().add(new CardController((Card) e.getNewValue()).render());
CardController tmp = new CardController((Card) e.getNewValue(), null);
controllers.add(tmp);
lastPlayedCardPane.getChildren().add(tmp.render());
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
};
game.listeners().addPropertyChangeListener(Game.PROPERTY_LAST_PLAYED_CARD, lastPlayedCardPropertyChangeListener);
gameOverListener = e -> {
app.show(new GameOverController(app));
};
game.listeners().addPropertyChangeListener(Game.PROPERTY_GAME_OVER, gameOverListener);
exitGameButton.setOnAction(e -> {
app.show(new AppController(app, new GameService()));
}); });
playButton.setOnAction(e -> { playButton.setOnAction(e -> {
gameService.playCard(new Card().setColor(Card.Color.GREEN).setValue(Card.Value.ONE));
Card cardToPlay = game.getPlayerService().getPlayerList().getFirst().getCurrentCard();
if(cardToPlay.getValue().equals(Card.Value.CHOOSE) || cardToPlay.getValue().equals(Card.Value.CHOOSEDRAW)) {
if(!cardToPlay.getColor().equals(Card.Color.BLACK)) {
if(cardToPlay.getPlayer() != null) {
gameService.playCard(cardToPlay);
}
}
} else if(gameService.legalMove(cardToPlay)){
if(cardToPlay.getPlayer() != null) {
gameService.playCard(cardToPlay);
}
}
});
drawCardButton.setOnAction(e -> {
gameService.drawCard(1);
}); });
@ -51,4 +119,18 @@ public class GameController implements Controller {
return parent; return parent;
} }
@Override
public String getTitle() {
return "Onses - Uno Game";
}
@Override
public void destroy() {
for (Controller controller : controllers) {
controller.destroy();
}
game.listeners().removePropertyChangeListener(Game.PROPERTY_LAST_PLAYED_CARD, lastPlayedCardPropertyChangeListener);
game.listeners().removePropertyChangeListener(Game.PROPERTY_GAME_OVER, gameOverListener);
}
} }

40
src/main/java/de/hsfulda/onses/controllers/GameOverController.java

@ -0,0 +1,40 @@
package de.hsfulda.onses.controllers;
import de.hsfulda.onses.App;
import de.hsfulda.onses.Main;
import de.hsfulda.onses.services.GameService;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import java.io.IOException;
import java.util.Objects;
public class GameOverController implements Controller {
private final App app;
public GameOverController(App app) {
this.app = app;
}
@Override
public Parent render() throws IOException {
final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/gameOver.fxml")));
final Button newGameButton = (Button) parent.lookup("#newGameBtn");
newGameButton.setOnAction(e -> {
app.show(new GameController(app, new GameService()));
});
return parent;
}
@Override
public void destroy() {
}
@Override
public String getTitle() {
return null;
}
}

30
src/main/java/de/hsfulda/onses/controllers/PlayerController.java

@ -8,6 +8,7 @@ import javafx.scene.Parent;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import java.beans.PropertyChangeListener;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
@ -15,10 +16,13 @@ import java.util.Objects;
public class PlayerController implements Controller { public class PlayerController implements Controller {
private final Player player; private final Player player;
private final ArrayList<Controller> controllers = new ArrayList<>();
private PropertyChangeListener playerDeckChangeListener;
public PlayerController(Player player) { public PlayerController(Player player) {
this.player = player; this.player = player;
} }
@Override @Override
public Parent render() throws IOException { public Parent render() throws IOException {
final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/player.fxml"))); final Parent parent = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("views/player.fxml")));
@ -26,22 +30,38 @@ public class PlayerController implements Controller {
final HBox cards = (HBox) parent.lookup("#cardsHBox"); final HBox cards = (HBox) parent.lookup("#cardsHBox");
for(Card card : player.getPlayerDeck()) { for(Card card : player.getPlayerDeck()) {
cards.getChildren().add(new CardController(card).render());
CardController newCardController = new CardController(card, player);
controllers.add(newCardController);
cards.getChildren().add(newCardController.render());
} }
player.listeners().addPropertyChangeListener(Player.PROPERTY_PLAYER_DECK, e -> {
playerDeckChangeListener = e -> {
cards.getChildren().clear(); cards.getChildren().clear();
for(Card card : player.getPlayerDeck()) { for(Card card : player.getPlayerDeck()) {
try { try {
cards.getChildren().add(new CardController(card).render());
cards.getChildren().add(new CardController(card, player).render());
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
});
};
player.listeners().addPropertyChangeListener(Player.PROPERTY_PLAYER_DECK, playerDeckChangeListener);
playerNameLabel.setText("Test");
playerNameLabel.setText(player.getPlayerName());
return parent; return parent;
} }
@Override
public String getTitle() {
return "Onses - Uno Game";
}
@Override
public void destroy() {
for (Controller controller : controllers) {
controller.destroy();
}
player.listeners().removePropertyChangeListener(Player.PROPERTY_PLAYER_DECK, playerDeckChangeListener);
}
} }

25
src/main/java/de/hsfulda/onses/models/Card.java

@ -7,11 +7,16 @@ public class Card {
public final static String PROPERTY_COLOR = "color"; public final static String PROPERTY_COLOR = "color";
public final static String PROPERTY_VALUE = "value"; public final static String PROPERTY_VALUE = "value";
public final static String PROPERTY_SELECTED = "selected";
protected PropertyChangeSupport listeners; protected PropertyChangeSupport listeners;
private Color color; private Color color;
private Value value; private Value value;
private boolean facedown = false; private boolean facedown = false;
private boolean selected;
private Player player;
public enum Color { public enum Color {
RED, BLUE, GREEN, YELLOW, BLACK; RED, BLUE, GREEN, YELLOW, BLACK;
@ -51,6 +56,26 @@ public class Card {
return this; return this;
} }
public boolean isSelected() {
return selected;
}
public Card setSelected(boolean selected) {
final boolean oldValue = this.selected;
this.selected = selected;
this.firePropertyChange(PROPERTY_SELECTED, oldValue, selected);
return this;
}
public Player getPlayer() {
return player;
}
public Card setPlayer(Player player) {
this.player = player;
return this;
}
public PropertyChangeSupport listeners() { public PropertyChangeSupport listeners() {
if(this.listeners == null) { if(this.listeners == null) {
this.listeners = new PropertyChangeSupport(this); this.listeners = new PropertyChangeSupport(this);

3
src/main/java/de/hsfulda/onses/models/Game.java

@ -10,6 +10,7 @@ public class Game {
public final static String PROPERTY_LAST_PLAYED_CARD = "lastPlayedCard"; public final static String PROPERTY_LAST_PLAYED_CARD = "lastPlayedCard";
public final static String PROPERTY_DRAW_CARD_DECK = "drawCardDeck"; public final static String PROPERTY_DRAW_CARD_DECK = "drawCardDeck";
public final static String PROPERTY_GAME_OVER = "gameOver";
protected PropertyChangeSupport listeners; protected PropertyChangeSupport listeners;
@ -70,7 +71,9 @@ public class Game {
} }
public void setGameOver(boolean gameOver) { public void setGameOver(boolean gameOver) {
final boolean oldValue = this.gameOver;
this.gameOver = gameOver; this.gameOver = gameOver;
this.firePropertyChange(PROPERTY_GAME_OVER, oldValue, gameOver);
} }
public boolean getGameOver() { public boolean getGameOver() {

4
src/main/java/de/hsfulda/onses/models/Player.java

@ -7,6 +7,7 @@ import java.util.ArrayList;
public class Player { public class Player {
public final static String PROPERTY_PLAYER_DECK = "playerDeck"; public final static String PROPERTY_PLAYER_DECK = "playerDeck";
public final static String PROPERTY_CURRENT_CARD = "currentCard";
protected PropertyChangeSupport listeners; protected PropertyChangeSupport listeners;
@ -22,6 +23,7 @@ public class Player {
} }
public void addCardToPlayerDeck(Card card) { public void addCardToPlayerDeck(Card card) {
card.setPlayer(this);
final ArrayList<Card> oldplayerDeck = new ArrayList<>(this.playerDeck); final ArrayList<Card> oldplayerDeck = new ArrayList<>(this.playerDeck);
playerDeck.add(card); playerDeck.add(card);
this.firePropertyChange(PROPERTY_PLAYER_DECK, oldplayerDeck, playerDeck); this.firePropertyChange(PROPERTY_PLAYER_DECK, oldplayerDeck, playerDeck);
@ -74,7 +76,9 @@ public class Player {
} }
public Player setCurrentCard(Card currentCard) { public Player setCurrentCard(Card currentCard) {
final Card oldCard = this.currentCard;
this.currentCard = currentCard; this.currentCard = currentCard;
this.firePropertyChange(PROPERTY_CURRENT_CARD, oldCard, currentCard);
return this; return this;
} }

52
src/main/java/de/hsfulda/onses/services/GameService.java

@ -54,20 +54,16 @@ public class GameService {
player = game.getPlayerService().getPlayerList().getLast(); player = game.getPlayerService().getPlayerList().getLast();
} }
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
player.getPlayerDeck().add(game.getDrawCardDeck().getFirst().setFacedown(isFaceDown));
Card newCard = game.getDrawCardDeck().getFirst().setFacedown(isFaceDown).setPlayer(player);
player.addCardToPlayerDeck(newCard);
game.getDrawCardDeck().removeFirst(); game.getDrawCardDeck().removeFirst();
} }
if (amount == 1 && !player.getPlayerDeck().isEmpty()) { if (amount == 1 && !player.getPlayerDeck().isEmpty()) {
Card drawnCard = player.getPlayerDeck().getLast();
if (legalMove(drawnCard)) {
player.getPlayerService().removeCardFromPlayerDeck(drawnCard);
playCard(drawnCard);
}
else nextPlayer();
nextPlayer();
if (!game.getPlayerService().getCurrentTurn()) game.getPlayerService().botMove();
} }
} }
if (amount != 1) {
if (amount == 7) {
nextPlayer(); nextPlayer();
} }
} }
@ -82,32 +78,9 @@ public class GameService {
public void chooseColor() { public void chooseColor() {
// Abfrage Farbe // Abfrage Farbe
Card.Color color = Card.Color.BLUE; //Vorübergehend Blau
game.changeLastPlayedCardColor(color);
if (!game.getPlayerService().getCurrentTurn()){
int min = 0;
int max = 3;
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
switch (randomNum){
case 0:
color = Card.Color.BLUE;
game.changeLastPlayedCardColor(color);
break;
case 1:
color = Card.Color.RED;
game.changeLastPlayedCardColor(color);
break;
case 2:
color = Card.Color.YELLOW;
game.changeLastPlayedCardColor(color);
break;
case 3:
color = Card.Color.GREEN;
game.changeLastPlayedCardColor(color);
break;
}
if (game.getPlayerService().getCurrentTurn()) {
Card.Color color = Card.Color.BLUE; //Vorübergehend Blau
game.changeLastPlayedCardColor(color);
} }
} }
@ -133,6 +106,9 @@ public class GameService {
} }
public void playCard(Card card) { public void playCard(Card card) {
if(card.getPlayer() != null) {
card.getPlayer().removeCardFromPlayerDeck(card);
}
// add lastPlayedCard back to drawCardDeck // add lastPlayedCard back to drawCardDeck
this.addLastPlayedCardToDrawCardDeck(); this.addLastPlayedCardToDrawCardDeck();
game.setLastPlayedCard(card); game.setLastPlayedCard(card);
@ -145,11 +121,11 @@ public class GameService {
nextPlayer(); nextPlayer();
break; break;
case CHOOSE: case CHOOSE:
chooseColor();
//chooseColor();
nextPlayer(); nextPlayer();
break; break;
case CHOOSEDRAW: case CHOOSEDRAW:
chooseColor();
//chooseColor();
nextPlayer(); nextPlayer();
drawCard(4); drawCard(4);
break; break;
@ -177,8 +153,6 @@ public class GameService {
if (card.getValue() == lastCard.getValue()) legalMoveFound = true; // same value if (card.getValue() == lastCard.getValue()) legalMoveFound = true; // same value
if (card.getColor() == Card.Color.BLACK) legalMoveFound = true; // Color Black
return legalMoveFound; return legalMoveFound;
} }

30
src/main/java/de/hsfulda/onses/services/PlayerService.java

@ -6,6 +6,7 @@ import de.hsfulda.onses.models.Card;
import de.hsfulda.onses.services.GameService; import de.hsfulda.onses.services.GameService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random;
public class PlayerService { public class PlayerService {
@ -46,8 +47,8 @@ public class PlayerService {
} }
public PlayerService() { public PlayerService() {
addPlayerToList(new Player().setPlayerService(this));
addPlayerToList(new Player().setPlayerService(this));
addPlayerToList(new Player().setPlayerService(this).setPlayerName("Player"));
addPlayerToList(new Player().setPlayerService(this).setPlayerName("Bot"));
} }
public void removeCardFromPlayerDeck(Card card) { public void removeCardFromPlayerDeck(Card card) {
@ -57,7 +58,7 @@ public class PlayerService {
} else { } else {
player = playerList.getLast(); player = playerList.getLast();
} }
player.getPlayerDeck().remove(card);
player.removeCardFromPlayerDeck(card);
} }
public void botMove() { public void botMove() {
@ -66,11 +67,32 @@ public class PlayerService {
if (getGame().getGameService().legalMove(this.playerList.getLast().getPlayerDeck().get(i))) { if (getGame().getGameService().legalMove(this.playerList.getLast().getPlayerDeck().get(i))) {
Card playCard = this.playerList.getLast().getPlayerDeck().get(i); Card playCard = this.playerList.getLast().getPlayerDeck().get(i);
this.removeCardFromPlayerDeck(playCard); this.removeCardFromPlayerDeck(playCard);
if (playCard.getValue() == Card.Value.CHOOSE || playCard.getValue() == Card.Value.CHOOSEDRAW)
{
int min = 0;
int max = 3;
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
switch (randomNum){
case 0:
playCard.setColor(Card.Color.BLUE);
break;
case 1:
playCard.setColor(Card.Color.RED);
break;
case 2:
playCard.setColor(Card.Color.YELLOW);
break;
case 3:
playCard.setColor(Card.Color.GREEN);
break;
}
}
getGame().getGameService().playCard(playCard); getGame().getGameService().playCard(playCard);
break; break;
} }
} }
if (lastPlayedCard == game.getLastPlayedCard()) {
if (lastPlayedCard == game.getLastPlayedCard() && !playerList.getLast().getPlayerDeck().isEmpty()) {
game.getGameService().drawCard(1); game.getGameService().drawCard(1);
} }
} }

6
src/main/resources/de/hsfulda/onses/views/app.fxml

@ -5,14 +5,14 @@
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<AnchorPane prefHeight="456.0" prefWidth="683.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1">
<AnchorPane prefHeight="690.0" prefWidth="1254.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
<Label layoutX="252.0" layoutY="96.0" text="Uno Game" AnchorPane.leftAnchor="252.0" AnchorPane.topAnchor="96.0">
<Label layoutX="537.0" layoutY="147.0" text="Uno Game" AnchorPane.leftAnchor="537.0" AnchorPane.topAnchor="147.0">
<font> <font>
<Font size="34.0" /> <Font size="34.0" />
</font> </font>
</Label> </Label>
<Button fx:id="startGameBtn" layoutX="274.0" layoutY="257.0" mnemonicParsing="false" text="Start Game" AnchorPane.leftAnchor="274.0" AnchorPane.topAnchor="257.0">
<Button fx:id="startGameBtn" layoutX="559.0" layoutY="345.0" mnemonicParsing="false" text="Start Game" AnchorPane.leftAnchor="559.0" AnchorPane.topAnchor="345.0">
<font> <font>
<Font size="19.0" /> <Font size="19.0" />
</font> </font>

11
src/main/resources/de/hsfulda/onses/views/game.fxml

@ -13,12 +13,12 @@
<Cursor fx:constant="HAND" /> <Cursor fx:constant="HAND" />
</cursor> </cursor>
</Button> </Button>
<Button fx:id="btnWishRed" layoutX="1160.0" layoutY="507.0" mnemonicParsing="false" style="-fx-background-color: red; -fx-pref-width: 30px; -fx-pref-height: 30px; -fx-cursor: pointer;" AnchorPane.bottomAnchor="153.0" AnchorPane.rightAnchor="64.0">
<Button fx:id="btnWishRed" layoutX="1160.0" layoutY="507.0" mnemonicParsing="false" style="-fx-background-color: red; -fx-pref-width: 30px; -fx-pref-height: 30px;" AnchorPane.bottomAnchor="153.0" AnchorPane.rightAnchor="64.0">
<cursor> <cursor>
<Cursor fx:constant="HAND" /> <Cursor fx:constant="HAND" />
</cursor> </cursor>
</Button> </Button>
<Button fx:id="btnWishGreen" layoutX="1160.0" layoutY="549.0" mnemonicParsing="false" style="-fx-background-color: green; -fx-pref-width: 30px; -fx-pref-height: 30px; -fx-cursor: pointer;" AnchorPane.bottomAnchor="111.0" AnchorPane.rightAnchor="64.0">
<Button fx:id="btnWishGreen" layoutX="1160.0" layoutY="549.0" mnemonicParsing="false" style="-fx-background-color: green; -fx-pref-width: 30px; -fx-pref-height: 30px;" AnchorPane.bottomAnchor="111.0" AnchorPane.rightAnchor="64.0">
<cursor> <cursor>
<Cursor fx:constant="HAND" /> <Cursor fx:constant="HAND" />
</cursor> </cursor>
@ -36,10 +36,15 @@
<Pane fx:id="playerPane" layoutX="18.0" layoutY="460.0" prefHeight="228.0" prefWidth="950.0" style="-fx-border-color: red;" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="18.0" AnchorPane.rightAnchor="286.0" /> <Pane fx:id="playerPane" layoutX="18.0" layoutY="460.0" prefHeight="228.0" prefWidth="950.0" style="-fx-border-color: red;" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="18.0" AnchorPane.rightAnchor="286.0" />
<Pane fx:id="enemyPane" layoutX="18.0" layoutY="14.0" prefHeight="228.0" prefWidth="950.0" style="-fx-border-color: red;" AnchorPane.leftAnchor="18.0" AnchorPane.rightAnchor="286.0" AnchorPane.topAnchor="10.0" /> <Pane fx:id="enemyPane" layoutX="18.0" layoutY="14.0" prefHeight="228.0" prefWidth="950.0" style="-fx-border-color: red;" AnchorPane.leftAnchor="18.0" AnchorPane.rightAnchor="286.0" AnchorPane.topAnchor="10.0" />
<Pane fx:id="lastPlayedCardPane" layoutX="112.0" layoutY="245.0" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="200.0" prefWidth="130.0" AnchorPane.leftAnchor="112.0" AnchorPane.topAnchor="245.0" /> <Pane fx:id="lastPlayedCardPane" layoutX="112.0" layoutY="245.0" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="200.0" prefWidth="130.0" AnchorPane.leftAnchor="112.0" AnchorPane.topAnchor="245.0" />
<Button layoutX="404.0" layoutY="329.0" mnemonicParsing="false" text="Draw Card" AnchorPane.leftAnchor="404.0" AnchorPane.topAnchor="329.0">
<Button fx:id="drawCardBtn" layoutX="404.0" layoutY="329.0" mnemonicParsing="false" text="Draw Card" AnchorPane.leftAnchor="404.0" AnchorPane.topAnchor="329.0">
<font> <font>
<Font size="18.0" /> <Font size="18.0" />
</font> </font>
</Button> </Button>
<Button fx:id="exitBtn" layoutX="1048.0" layoutY="53.0" mnemonicParsing="false" text="return to menu" AnchorPane.rightAnchor="62.0" AnchorPane.topAnchor="53.0">
<font>
<Font size="16.0" />
</font>
</Button>
</children> </children>
</AnchorPane> </AnchorPane>

22
src/main/resources/de/hsfulda/onses/views/gameOver.fxml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="690.0" prefWidth="1254.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label layoutX="504.0" layoutY="158.0" text="Game Over" AnchorPane.leftAnchor="504.0" AnchorPane.topAnchor="158.0">
<font>
<Font size="43.0" />
</font>
</Label>
<Button fx:id="newGameBtn" layoutX="569.0" layoutY="329.0" mnemonicParsing="false" text="New Game" AnchorPane.leftAnchor="569.0" AnchorPane.topAnchor="329.0">
<font>
<Font size="17.0" />
</font>
</Button>
</children>
</AnchorPane>

10
src/test/java/de/hsfulda/onses/CardTest.java

@ -87,4 +87,14 @@ public class CardTest {
} }
@Test
@DisplayName("test if card is selected")
void testIfCardIsSelected() {
Card card = new Card().setSelected(true);
assertTrue(card.isSelected());
card.setSelected(false);
assertFalse(card.isSelected());
}
} }

89
src/test/java/de/hsfulda/onses/GameServiceTest.java

@ -1,4 +1,3 @@
package de.hsfulda.onses; package de.hsfulda.onses;
import com.sun.jdi.ArrayReference; import com.sun.jdi.ArrayReference;
@ -120,37 +119,6 @@ public class GameServiceTest {
assertEquals(expected, answer); assertEquals(expected, answer);
} }
@Test
@DisplayName("legalMoveColorBlack")
public void legalMoveColorBlack() {
// arrange
Card input = new Card().setColor(Card.Color.BLACK).setValue(Card.Value.CHOOSE);
boolean expected = true;
// act
GameService gameService = new GameService();
gameService.setTest(true);
gameService.getGame().setLastPlayedCard(new Card().setColor(Card.Color.YELLOW).setValue(Card.Value.THREE));
boolean answer = gameService.legalMove(input);
// assert
assertEquals(expected, answer);
}
@Test
@DisplayName("legalMoveColorBlackCHOOSEDRAW")
public void legalMoveColorBlackCHOOSEDRAW() {
// arrange
Card input = new Card().setColor(Card.Color.BLACK).setValue(Card.Value.CHOOSEDRAW);
boolean expected = true;
// act
GameService gameService = new GameService();
gameService.setTest(true);
gameService.getGame().setLastPlayedCard(new Card().setColor(Card.Color.GREEN).setValue(Card.Value.FIVE));
boolean answer = gameService.legalMove(input);
// assert
assertEquals(expected, answer);
}
@Test @Test
@DisplayName("ShuffelDeck") @DisplayName("ShuffelDeck")
@ -225,41 +193,6 @@ public class GameServiceTest {
assertEquals(expected, gameService.getGame().getPlayerService().getCurrentTurn()); assertEquals(expected, gameService.getGame().getPlayerService().getCurrentTurn());
} }
@Test
@DisplayName("ChooseTest")
public void ChooseTest() {
GameService gameService = new GameService();
gameService.setTest(true);
boolean expected = true;
boolean answer = false;
gameService.playCard(new Card().setValue(Card.Value.CHOOSE).setColor(Card.Color.BLACK));
if (gameService.getGame().getLastPlayedCard().getColor() != Card.Color.BLACK) {
answer = true;
}
assertEquals(expected, answer);
}
@Test
@DisplayName("ChooseDrawTest")
public void ChooseDrawTest() {
GameService gameService = new GameService();
gameService.setTest(true);
boolean expected = true;
boolean answer = false;
gameService.playCard(new Card().setValue(Card.Value.CHOOSEDRAW).setColor(Card.Color.BLACK));
if (gameService.getGame().getLastPlayedCard().getColor() != Card.Color.BLACK) {
answer = true;
}
assertEquals(expected, answer);
}
@Test @Test
@DisplayName("DrawByChoiceForceKeep") @DisplayName("DrawByChoiceForceKeep")
public void DrawByChoiceForceKeep() { public void DrawByChoiceForceKeep() {
@ -323,26 +256,6 @@ public class GameServiceTest {
assertEquals(expected, answer); assertEquals(expected, answer);
} }
@Test
@DisplayName("DrawByChoiceForcePlay")
public void DrawByChoiceForcePlay() {
GameService gameService = new GameService();
gameService.setTest(true);
Card input = new Card().setColor(Card.Color.RED).setValue(Card.Value.ONE);
gameService.getGame().getDrawCardDeck().clear();
gameService.getGame().getPlayerService().setCurrentTurn(true);
gameService.getGame().setLastPlayedCard(new Card().setColor(Card.Color.RED).setValue(Card.Value.SEVEN));
gameService.getGame().addCardToDrawCardDeck(input);
gameService.getGame().getPlayerService().getPlayerList().getFirst().addCardToPlayerDeck(new Card().setColor(Card.Color.BLUE).setValue(Card.Value.TWO));
gameService.drawCard(1);
Card answer = gameService.getGame().getPlayerService().getPlayerList().getFirst().getPlayerDeck().getLast();
assertNotEquals(input, answer);
}
@Test @Test
@DisplayName("CheckThatBotDeckHasSevenCardsAfterGameStart") @DisplayName("CheckThatBotDeckHasSevenCardsAfterGameStart")
public void CheckThatBotDeckHasSevenCardsAfterGameStart() { public void CheckThatBotDeckHasSevenCardsAfterGameStart() {
@ -436,7 +349,7 @@ public class GameServiceTest {
gameService.getGame().getPlayerService().getPlayerList().getLast().getPlayerDeck().add(card); gameService.getGame().getPlayerService().getPlayerList().getLast().getPlayerDeck().add(card);
gameService.getGame().getPlayerService().setCurrentTurn(false); gameService.getGame().getPlayerService().setCurrentTurn(false);
gameService.playCard(card);
gameService.getGame().getPlayerService().botMove();
if (gameService.getGame().getLastPlayedCard().getColor() != Card.Color.BLACK){ if (gameService.getGame().getLastPlayedCard().getColor() != Card.Color.BLACK){
answer = true; answer = true;

4
src/test/java/de/hsfulda/onses/GuiTest.java

@ -10,11 +10,13 @@ import static org.testfx.matcher.control.LabeledMatchers.*;
public class GuiTest extends ApplicationTest { public class GuiTest extends ApplicationTest {
private Stage stage; private Stage stage;
private App app;
@Override @Override
public void start(Stage stage) throws Exception { public void start(Stage stage) throws Exception {
this.stage = stage; this.stage = stage;
new App().start(stage);
app = new App();
app.start(stage);
} }
@Test @Test

11
src/test/java/de/hsfulda/onses/PlayerTest.java

@ -114,4 +114,15 @@ public class PlayerTest {
player.setCurrentCard(card); player.setCurrentCard(card);
assertEquals(card, player.getCurrentCard()); assertEquals(card, player.getCurrentCard());
} }
@Test
@DisplayName("Set Player by Card")
void testPlayerSetByCard() {
Player player = new Player();
Card card = new Card();
assertNull(card.getPlayer());
player.addCardToPlayerDeck(card);
assertEquals(player, card.getPlayer());
}
} }
Loading…
Cancel
Save