diff --git a/src/main/java/mau/mau/CardHandler.java b/src/main/java/mau/mau/CardHandler.java new file mode 100644 index 0000000..35e1091 --- /dev/null +++ b/src/main/java/mau/mau/CardHandler.java @@ -0,0 +1,68 @@ +package mau.mau; + +import mau.mau.players.Player; + +public class CardHandler { + public void handleCard(Card card, TurnTable turnTable){ + if (card != null && Referee.isMauCard(card)) { + handleMauCard(card, turnTable); + return; + } + turnTable.nextPlayer(); + } + + private void handleMauCard(Card card, TurnTable turnTable){ + TYPENUM type = card.getType(); + if (type == TYPENUM.JOKER) { + handleJoker(turnTable); + return; + } + VALUENUM value = card.getValue(); + switch (value) { + case TWO -> handleTwo(turnTable); + case SEVEN -> handleSeven(); + case EIGHT -> handleEight(turnTable); + case JACK -> handleJack(turnTable); + case KING -> handleKing(); + case ACE -> handleAce(turnTable); + } + } + + private void handleTwo(TurnTable turnTable) { + drawCards(turnTable.getNextPlayer(), 2); + turnTable.skipNextPlayer(); + } + + private void handleSeven() { + System.out.println("Sticky seven go again"); + } + + private void handleEight(TurnTable turnTable) { + turnTable.skipNextPlayer(); + } + + private void handleJack(TurnTable turnTable) { + Referee.setAllowedCards(turnTable.getCurrentPlayer().getTypeChoice()); + turnTable.nextPlayer(); + } + + private void handleKing() { + System.out.println("Kinky king go again"); + } + + private void handleAce(TurnTable turnTable) { + turnTable.reverseDirection(); + turnTable.nextPlayer(); + } + + private void handleJoker(TurnTable turnTable) { + Player nextPlayer = turnTable.getNextPlayer(); + drawCards(nextPlayer, 5); + Referee.setAllowedCards(nextPlayer.getTypeChoice()); + turnTable.skipNextPlayer(); + } + + private void drawCards(Player player, int amount) { + player.drawCards(amount); + } +} diff --git a/src/main/java/mau/mau/Game.java b/src/main/java/mau/mau/Game.java index dc64cc2..139eeed 100644 --- a/src/main/java/mau/mau/Game.java +++ b/src/main/java/mau/mau/Game.java @@ -6,11 +6,14 @@ import mau.mau.players.Player; import java.util.ArrayList; import java.util.List; +import java.util.Scanner; public class Game { private Card currentCard; private final Deck deck = new Deck(); private Dealer dealer; + private CardHandler cardHandler = new CardHandler(); + private TurnTable turnTable; private final List players = new ArrayList<>(); private int playerTurn = 0; private Boolean reverse = false; @@ -22,20 +25,32 @@ public class Game { private void setupGame() { dealer = new Dealer(deck); - Human human = new Human("Peppie's Maueria", dealer); + Scanner scanner = new Scanner(System.in); + System.out.println(Messages.ASK_FOR_PLAYER_NAME); + String input = scanner.nextLine(); + if (input.equals("")) { + input = "Koet"; + System.out.println(Messages.BAD_PLAYER_NAME); + } + Human human = new Human(input, dealer); players.add(human); players.add(new Bot("Jordan", dealer)); players.add(new Bot("MaarKoet", dealer)); + players.add(new Bot("El Tigre", dealer)); + turnTable = new TurnTable(players); dealer.dealCards(players); currentCard = dealer.getInitialCard(); } private void playGame() { while (players.size() > 1) { - Player player = players.get(playerTurn); + Player player = turnTable.getCurrentPlayer(); System.out.println("Current card: " + currentCard); Card playedCard = player.getPlay(currentCard); + if (player instanceof Bot) { + new Scanner(System.in).nextLine(); + } if(player.getHandSize() > 0) { if(playedCard != null){ playCard(playedCard); @@ -47,6 +62,7 @@ public class Game { System.out.println(player.getName() + " won!"); } else { System.out.println("You can't end the game with that card!"); + System.out.println("Take five cards as punishment!"); for (int i = 0; i < 5; i++) { player.addCardToHand(dealer.drawCard()); } @@ -54,7 +70,7 @@ public class Game { break; } players.removeIf(Player::handIsEmpty); - handleTurn(playedCard); + cardHandler.handleCard(playedCard, turnTable); } System.out.println("Game has ended"); } @@ -63,76 +79,4 @@ public class Game { currentCard = card; deck.addUsedCard(card); } - - public void handleTurn(Card card) { - if(card == null){ - incrementPlayerTurn(1); - return; - } - TYPENUM cardType = card.getType(); - VALUENUM cardValue = card.getValue(); - if (cardType == TYPENUM.JOKER) { - - incrementPlayerTurn(1); - Player player = players.get(playerTurn); - Referee.setAllowedCards(player.getTypeChoice()); - - for (int i = 0; i < 5; i++) { - player.addCardToHand(dealer.drawCard()); - } - incrementPlayerTurn(1); - return; - } - switch (cardValue) { - case TWO -> { - incrementPlayerTurn(1); - Player player = players.get(playerTurn); - for (int i = 0; i < 2; i++) { - player.addCardToHand(dealer.drawCard()); - } - incrementPlayerTurn(1); - return; - } - case SEVEN -> { - System.out.println("Sticky seven go again"); - return; - } - case KING -> { - System.out.println("Kinky king go again"); - return; - } - case EIGHT -> { - System.out.println("Eighty waity"); - incrementPlayerTurn(2); - return; - } - case JACK -> { - Player player = players.get(playerTurn); - Referee.setAllowedCards(player.getTypeChoice()); - } - case ACE -> { - reverse = !reverse; - if (players.size() == 2) { - return; - } - } - } - incrementPlayerTurn(1); - } - - private void incrementPlayerTurn(int increment) { - for (int i = 0; i < increment; i++) { - if (reverse) { - playerTurn--; - } else { - playerTurn++; - } - if (playerTurn < 0) { - playerTurn = players.size() - 1; - } - if (playerTurn >= players.size()) { - playerTurn = 0; - } - } - } } diff --git a/src/main/java/mau/mau/Messages.java b/src/main/java/mau/mau/Messages.java new file mode 100644 index 0000000..0042357 --- /dev/null +++ b/src/main/java/mau/mau/Messages.java @@ -0,0 +1,14 @@ +package mau.mau; + +public class Messages { + public static final String KEY_PLAYER_NAME = "{{playerName}}"; + public static final String KEY_CARD = "{{card}}"; + public static final String KEY_NUMBER_OF_CARDS = "{{numberOfCards}}"; + + public static final String WELCOME = "Welcome to Dutch Mau Mau!"; + public static final String ASK_FOR_PLAYER_NAME = "What shall be thy name?"; + public static final String BAD_PLAYER_NAME = "What a pathetic response, thy shall be known as Koet"; + public static final String PLAYER_PLAYED_CARD = KEY_PLAYER_NAME + " played " + KEY_CARD; + public static final String PLAYER_DRAW_CARDS = KEY_PLAYER_NAME + " drew " + KEY_NUMBER_OF_CARDS + " cards"; + public static final String PLAYER_HAS_X_CARDS = KEY_PLAYER_NAME + " now has " + KEY_NUMBER_OF_CARDS + " cards"; +} diff --git a/src/main/java/mau/mau/TurnTable.java b/src/main/java/mau/mau/TurnTable.java new file mode 100644 index 0000000..8fa8291 --- /dev/null +++ b/src/main/java/mau/mau/TurnTable.java @@ -0,0 +1,53 @@ +package mau.mau; + +import mau.mau.players.Player; + +import java.util.List; + +public class TurnTable { + private List players; + private int currentPlayerIndex; + private int direction; + + public TurnTable(List players) { + this.players = players; + this.currentPlayerIndex = 0; + this.direction = 1; + } + + public Player getCurrentPlayer() { + return players.get(currentPlayerIndex); + } + + public Player getNextPlayer() { + int nextPlayerIndex = currentPlayerIndex + direction; + if (nextPlayerIndex >= players.size()) { + nextPlayerIndex = 0; + } else if (nextPlayerIndex < 0) { + nextPlayerIndex = players.size() - 1; + } + return players.get(nextPlayerIndex); + } + + public void nextPlayer() { + currentPlayerIndex += direction; + if (currentPlayerIndex >= players.size()) { + currentPlayerIndex = 0; + } else if (currentPlayerIndex < 0) { + currentPlayerIndex = players.size() - 1; + } + } + + public void skipNextPlayer(){ + for (int i = 0; i < 2; i++) { + nextPlayer(); + } + } + + public void reverseDirection() { + direction *= -1; + if (players.size() == 2) { + nextPlayer(); + } + } +} diff --git a/src/main/java/mau/mau/players/Bot.java b/src/main/java/mau/mau/players/Bot.java index 41916d4..6015c8c 100644 --- a/src/main/java/mau/mau/players/Bot.java +++ b/src/main/java/mau/mau/players/Bot.java @@ -21,40 +21,35 @@ public class Bot extends Player { System.out.println(getName() + " played " + card); hand.remove(0); System.out.println(getName() + " now has " + hand.size() + " cards"); - new Scanner(System.in).nextLine(); return card; } else if (hand.size() == 1) { hand.add(drawCard()); System.out.println(getName() + " drew a card"); System.out.println(getName() + " now has " + hand.size() + " cards"); - new Scanner(System.in).nextLine(); return null; } for (Card card : hand) { - if(Referee.allowedTypes.isEmpty()) { + if (Referee.allowedTypes.isEmpty()) { if (Referee.isValidMove(card, currentCard)) { System.out.println(getName() + " played " + card); hand.remove(card); System.out.println(getName() + " now has " + hand.size() + " cards"); - new Scanner(System.in).nextLine(); return card; } } else { - if (Referee.allowedTypes.contains(card.getType())) { - Referee.allowedTypes.clear(); - System.out.println(getName() + " played " + card); - hand.remove(card); - System.out.println(getName() + " now has " + hand.size() + " cards"); - new Scanner(System.in).nextLine(); - return card; - } + if (Referee.allowedTypes.contains(card.getType())) { + Referee.allowedTypes.clear(); + System.out.println(getName() + " played " + card); + hand.remove(card); + System.out.println(getName() + " now has " + hand.size() + " cards"); + return card; + } } } hand.add(drawCard()); System.out.println(getName() + " drew a card"); System.out.println(getName() + " now has " + hand.size() + " cards"); - new Scanner(System.in).nextLine(); return null; } diff --git a/src/main/java/mau/mau/players/Human.java b/src/main/java/mau/mau/players/Human.java index ee937ff..0e69151 100644 --- a/src/main/java/mau/mau/players/Human.java +++ b/src/main/java/mau/mau/players/Human.java @@ -57,7 +57,7 @@ public class Human extends Player { @Override public TYPENUM getTypeChoice() { printHand(); - System.out.println("Choose a new type:"); + System.out.println("\nChoose a new type:"); System.out.println("(1) Spades"); System.out.println("(2) Hearts"); System.out.println("(3) Diamonds"); diff --git a/src/main/java/mau/mau/players/Player.java b/src/main/java/mau/mau/players/Player.java index 74aa743..ca4f115 100644 --- a/src/main/java/mau/mau/players/Player.java +++ b/src/main/java/mau/mau/players/Player.java @@ -37,10 +37,10 @@ public abstract class Player { return dealer.drawCard(); } - public Card playCard(int cardIndex) { - Card playCard = hand.get(cardIndex); - hand.remove(cardIndex); - return playCard; + public void drawCards(int cardsToDraw) { + for (int i = 0; i < cardsToDraw; i++) { + hand.add(drawCard()); + } } public int getHandSize() { diff --git a/src/main/resources/TODO.md b/src/main/resources/TODO.md index b8911b3..8a0e4a9 100644 --- a/src/main/resources/TODO.md +++ b/src/main/resources/TODO.md @@ -8,7 +8,7 @@ 4. ~~Als je laatste kaart een pestkaart is moet je 5 kaarten pakken als je hem probeert op te leggen~~ 5. 100% test coverage 6. Redesign terminal interface - * Kaarten laten zien als er een joker op je gedropt is + * ~~Kaarten laten zien als er een joker op je gedropt is~~ ## Known Bugs 1. ~~Teveel kaarten in deck na het opnieuw schudden~~ diff --git a/src/test/java/mau/mau/DeckTest.java b/src/test/java/mau/mau/DeckTest.java index 250c9da..8f24c47 100644 --- a/src/test/java/mau/mau/DeckTest.java +++ b/src/test/java/mau/mau/DeckTest.java @@ -1,4 +1,41 @@ package mau.mau; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + public class DeckTest { + + private Deck sut; + + @BeforeEach + void setUp(){ + sut = new Deck(); + } + + @Test + public void doIReceiveCardAfterDrawingTest(){ + // Act + Card card = sut.drawCard(); + boolean result = card.getClass().equals(Card.class); + + // Assert + assertTrue(result); + } + + @Test + public void isDeckEmptyWhenDrawingTheFirstCardTest() { + // Assign + int cardsToDraw = 1; + + // Act + boolean result = sut.deckIsEmpty(cardsToDraw); + + // Assert + assertFalse(result); + } + + } diff --git a/src/test/java/mau/mau/GameTest.java b/src/test/java/mau/mau/GameTest.java new file mode 100644 index 0000000..80204f8 --- /dev/null +++ b/src/test/java/mau/mau/GameTest.java @@ -0,0 +1,4 @@ +package mau.mau; + +public class GameTest { +} diff --git a/src/test/java/mau/mau/RefereeTest.java b/src/test/java/mau/mau/RefereeTest.java index 872f072..23b216b 100644 --- a/src/test/java/mau/mau/RefereeTest.java +++ b/src/test/java/mau/mau/RefereeTest.java @@ -59,6 +59,43 @@ public class RefereeTest { assertTrue(results); } + @Test + public void isTwoOfHeartsAMauCardTest(){ + //Assign + Card testCard = new Card(TYPENUM.HEARTS, VALUENUM.TWO); + + //Act + boolean result = Referee.isMauCard(testCard); + + //Assert + assertTrue(result); + } + + @Test + public void isJokerAMauCardTest(){ + //Assign + Card testCard = new Card(TYPENUM.JOKER, VALUENUM.THREE); + + //Act + boolean result = Referee.isMauCard(testCard); + + //Assert + assertTrue(result); + } + + @Test + public void isThreeOfSpadesAMauCardTest(){ + //Assign + Card testCard = new Card(TYPENUM.HEARTS, VALUENUM.THREE); + + //Act + boolean result = Referee.isMauCard(testCard); + + //Assert + assertFalse(result); + } + + @Test public void isAceOfSpadesValidEndcardTest(){ //Assign diff --git a/src/test/java/mau/mau/UtilsTest.java b/src/test/java/mau/mau/UtilsTest.java new file mode 100644 index 0000000..ed704e1 --- /dev/null +++ b/src/test/java/mau/mau/UtilsTest.java @@ -0,0 +1,57 @@ +package mau.mau; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class UtilsTest { + + @Test + public void isNumericStringNumericTest() { + //Assign + String numericString = "123"; + + //Act + boolean isNumeric = Utils.isNumeric(numericString); + + //Assert + assertTrue(isNumeric); + } + + @Test + public void isAlphabeticStringNumericTest() { + //Assign + String numericString = "Koet"; + + //Act + boolean isNumeric = Utils.isNumeric(numericString); + + //Assert + assertFalse(isNumeric); + } + + @Test + public void isEmptyStringNumericTest() { + //Assign + String numericString = ""; + + //Act + boolean isNumeric = Utils.isNumeric(numericString); + + //Assert + assertFalse(isNumeric); + } + + @Test + public void isCarriageReturnStringNumericTest() { + //Assign + String numericString = "\n"; + + //Act + boolean isNumeric = Utils.isNumeric(numericString); + + //Assert + assertFalse(isNumeric); + } +} diff --git a/src/test/java/mau/mau/players/BotTest.java b/src/test/java/mau/mau/players/BotTest.java new file mode 100644 index 0000000..779e8a1 --- /dev/null +++ b/src/test/java/mau/mau/players/BotTest.java @@ -0,0 +1,114 @@ +package mau.mau.players; + +import mau.mau.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class BotTest { + + private Bot sut; + private Dealer dealer; + private Deck deck; + private List hand; + + @BeforeEach + public void setUp() { + deck = new Deck(); + dealer = new Dealer(deck); + sut = new Bot("Koet", dealer); + hand = new ArrayList<>(); + } + + @Test + public void canBotEndTheGameWithFourOfHeartsOnThreeOfHeartsTest() { + //Assign + Card currentCard = new Card(TYPENUM.HEARTS, VALUENUM.THREE); + hand.add(new Card(TYPENUM.HEARTS, VALUENUM.FOUR)); + sut.setHand(hand); + + //Assert + assertEquals(1, sut.getHandSize()); + + //Act + sut.getPlay(currentCard); + + //Assert + assertTrue(sut.handIsEmpty()); + } + + @Test + public void canBotDrawACardTest() { + //Assign + Card currentCard = new Card(TYPENUM.SPADES, VALUENUM.THREE); + hand.add(new Card(TYPENUM.HEARTS, VALUENUM.FOUR)); + sut.setHand(hand); + + //Assert + assertEquals(1, sut.getHandSize()); + + //Act + sut.getPlay(currentCard); + + //Assert + assertEquals(2, sut.getHandSize()); + } + + @Test + public void canBotPlayACardWithSameTypeTest() { + //Assign + Card currentCard = new Card(TYPENUM.HEARTS, VALUENUM.THREE); + Card spadesFive = new Card(TYPENUM.SPADES, VALUENUM.FIVE); + Card clubsEight = new Card(TYPENUM.CLUBS, VALUENUM.EIGHT); + Card heartsNine = new Card(TYPENUM.HEARTS, VALUENUM.NINE); + hand.add(spadesFive); + hand.add(clubsEight); + hand.add(heartsNine); + sut.setHand(hand); + + //Assert + assertEquals(3, sut.getHandSize()); + + //Act + sut.getPlay(currentCard); + + //Assert + assertFalse(hand.contains(heartsNine)); + } + + @Test + public void canBotPlayACardWithSameValueTest() { + //Assign + Card currentCard = new Card(TYPENUM.DIAMONDS, VALUENUM.FIVE); + Card spadesFive = new Card(TYPENUM.SPADES, VALUENUM.FIVE); + Card clubsEight = new Card(TYPENUM.CLUBS, VALUENUM.EIGHT); + Card heartsNine = new Card(TYPENUM.HEARTS, VALUENUM.NINE); + hand.add(spadesFive); + hand.add(clubsEight); + hand.add(heartsNine); + sut.setHand(hand); + + //Assert + assertEquals(3, sut.getHandSize()); + + //Act + sut.getPlay(currentCard); + + //Assert + assertFalse(hand.contains(spadesFive)); + } + + @Test + public void canBotChooseTheTypeItHasTheMostOfTest() { + //TODO: implement test + } + + @Test + public void canBotChooseTheTypeItHasTheMostOfWhenThereIsATieTest() { + //TODO: implement test + } +} diff --git a/src/test/java/mau/mau/players/HumanTest.java b/src/test/java/mau/mau/players/HumanTest.java new file mode 100644 index 0000000..1bed762 --- /dev/null +++ b/src/test/java/mau/mau/players/HumanTest.java @@ -0,0 +1,4 @@ +package mau.mau.players; + +public class HumanTest { +} diff --git a/src/test/java/mau/mau/players/PlayerTest.java b/src/test/java/mau/mau/players/PlayerTest.java new file mode 100644 index 0000000..266b50b --- /dev/null +++ b/src/test/java/mau/mau/players/PlayerTest.java @@ -0,0 +1,4 @@ +package mau.mau.players; + +public class PlayerTest { +} diff --git a/src/test/java/tested.md b/src/test/java/tested.md index e05007c..f907002 100644 --- a/src/test/java/tested.md +++ b/src/test/java/tested.md @@ -1,17 +1,11 @@ -Bot - -Human - -Player - -~~Card~~ - -Dealer - -Deck - -Game - -~~Referee~~ - -Utils \ No newline at end of file +1. Bot +2. Human +3. Player +4. Card +5. CardHandler +6. Dealer +7. ~~Deck~~ +8. ~~Game~~ +9. ~~Referee~~ +10. TurnTable +11. ~~Utils~~