diff --git a/src/main/java/tech/mabunda/card/Card.java b/src/main/java/tech/mabunda/card/Card.java index 51327ff..6b4d460 100644 --- a/src/main/java/tech/mabunda/card/Card.java +++ b/src/main/java/tech/mabunda/card/Card.java @@ -95,6 +95,15 @@ public Color getColor() { return color; } + public void setColor(Color color) { + if (type == Type.WILD) { + this.color = color; + } + else { + System.out.println(">>> [ERROR] Cannot set color to non-wild cards."); + } + } + /** * Plays the card. Must be implemented by subclasses to define card-specific * play logic. @@ -106,16 +115,13 @@ public boolean play(GameState state) { Player player = state.getCurrentPlayer(); if (player.hasCard(this)) { - if (state.topDiscardPile().match(this)) { + if ((state.getColor() != null && state.getColor().equals(color)) || state.topDiscardPile().match(this)) { if (value.equals("SKIP") || value.equals("DRAW_TWO") || value.equals("WILD_DRAW_FOUR")) { state.setPenalty(value); } else if (value.equals("REVERSE")) { state.updateDirection(); - } else if (value.equals("WILD")) { - // TODO: implement input handling for this - // RED is just a placeholder - state.setColor(Color.RED); - } + } if (type != Type.WILD) { state.removeColor(); } + // Color for wild is set by the Game class // Remove remove from player, add to discard pile player.getHand().removeCard(this); @@ -151,13 +157,13 @@ public static Card create(String name) { String tokens[] = name.split(" "); try { return new NumberCard(Number.valueOf(tokens[1]), Color.valueOf(tokens[0])); - } catch (IllegalArgumentException iae) { + } catch (Exception e) { try { if (name.contains("DRAW")) { return new ActionCard(Action.valueOf("DRAW_TWO"), Color.valueOf(tokens[0])); } return new ActionCard(Action.valueOf(tokens[1]), Color.valueOf(tokens[0])); - } catch (Exception e) { + } catch (Exception e1) { return null; } } diff --git a/src/main/java/tech/mabunda/game/Game.java b/src/main/java/tech/mabunda/game/Game.java index e4d4642..c9604b3 100644 --- a/src/main/java/tech/mabunda/game/Game.java +++ b/src/main/java/tech/mabunda/game/Game.java @@ -4,6 +4,8 @@ import java.util.Scanner; import tech.mabunda.card.Card; +import tech.mabunda.card.enums.Color; +import tech.mabunda.card.enums.Type; import tech.mabunda.player.HumanPlayer; import tech.mabunda.player.Player; @@ -82,6 +84,9 @@ public void displayPrompt() { Player player = state.getCurrentPlayer(); System.out.println("It's " + player.getName() + "'s turn!"); System.out.println("The top card is " + state.topDiscardPile()); + if (state.getColor() != null) { + System.out.println("The color to match is " + state.getColor()); + } System.out.print("Your hand:\n\t-> "); for (Card card : player.getHand().getCards()) { @@ -98,29 +103,56 @@ private boolean handleCommand() { do { displayPrompt(); - command = sc.nextLine(); + command = sc.nextLine().toLowerCase(); + - if (command.equalsIgnoreCase("DRAW")) { + if (command.equals("draw")) { player.getHand().addCard(state.getDeck().drawCard()); - System.out.println(">>> [OK] " + player.getName() + " drew a card."); + System.out.println(">>> [OK] " + player.getName() + " drew a card.\n"); return true; } - Card cardToPlay = Card.create(command); + Card cardToPlay; + String colorToSet = ""; + + if (command.contains("wild")) { + String[] tokens = command.split(" "); + StringBuilder sb = new StringBuilder(); + sb.append(tokens[0]); + for (int i = 1; i < tokens.length - 1; i++) { + sb.append("_" + tokens[i]); + } + cardToPlay = Card.create(sb.toString()); + colorToSet = tokens[tokens.length - 1].toUpperCase(); + System.out.println(">>> card: " + sb.toString() + ", color: " + colorToSet); + + } else { + cardToPlay = Card.create(command); + } + // Check if card is valid if (cardToPlay == null) { - System.out.println(">>> [ERROR] Invalid card, please enter a valid format (e.g blue skip)!"); + System.out.println(">>> [ERROR] Invalid card, please enter a valid format (e.g blue skip)!\n"); continue; } + // Check if player has the card if (!player.hasCard(cardToPlay)) { - System.out.println(">>> [ERROR] You do not have that card, try again!"); + System.out.println(">>> [ERROR] You do not have that card, try again!\n"); continue; } + // Check if card is playable based on the current state cardPlayed = cardToPlay.play(state); if (cardPlayed) { System.out.println(">>> [OK] " + player.getName() + " played " + cardToPlay + "\n"); + + if (cardToPlay.getType() == Type.WILD) { + state.setColor(Color.valueOf(colorToSet)); + } + } + else { + System.out.println(">>> [ERROR] You cannot play " + cardToPlay + " on " + state.topDiscardPile() + "\n"); } } while (!cardPlayed); @@ -137,7 +169,6 @@ private boolean handleCommand() { */ public void start() { sc = new Scanner(System.in); - String command; Player player; while (state.getPlayers().size() > 1) { @@ -145,6 +176,7 @@ public void start() { // Check win status or penalty, skip player if either is true if (state.isWinner() || state.handlePenalty()) { + System.out.println(">>> Skipping " + player.getName() + "\n"); state.updatePlayer(); continue; } @@ -152,6 +184,7 @@ public void start() { // Process player's move handleCommand(); + // Go to next player state.updatePlayer(); } } diff --git a/src/main/java/tech/mabunda/game/GameState.java b/src/main/java/tech/mabunda/game/GameState.java index 74e367d..ce7f238 100644 --- a/src/main/java/tech/mabunda/game/GameState.java +++ b/src/main/java/tech/mabunda/game/GameState.java @@ -135,11 +135,12 @@ public boolean handlePenalty() { for (int i = 0; i < cardsToDraw; i++) { getCurrentPlayer().getHand().addCard(getDeck().drawCard()); } + System.out.println(">>> " + getCurrentPlayer().getName() + " drew " + cardsToDraw + " card(s)."); penalty = ""; return true; } - + return false; } @@ -152,6 +153,14 @@ public void setColor(Color color) { this.color = color; } + public void removeColor() { + color = null; + } + + public Color getColor() { + return color; + } + /** * Reverses the direction of play (e.g., for a reverse card). */