diff --git a/src/CardTest.java b/src/CardTest.java new file mode 100644 index 0000000..146cb85 --- /dev/null +++ b/src/CardTest.java @@ -0,0 +1,14 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class CardTest { + + @Test + + void constructorWorks() { + Card card = new Card(1, Card.Suit.CLUBS); + assertEquals(1, card.number); + assertEquals(Card.Suit.CLUBS, card.suit); + } +} \ No newline at end of file diff --git a/src/Game.java b/src/Game.java index ac6319e..27e7e63 100644 --- a/src/Game.java +++ b/src/Game.java @@ -1,18 +1,18 @@ public class Game { final Players players = new Players(); + private Pile deck; /** * @param numberOfCards Total number of cards * @param numberOfPlayers Total number of players */ public Game(int numberOfCards, int numberOfPlayers) { - Pile deck = Pile.createDeck(numberOfCards); + deck = Pile.createDeck(numberOfCards); int cardsPerPlayer = deck.size() / numberOfPlayers; for (int i = 0; i < numberOfPlayers; i++) { Player player = new Player(String.valueOf(i), deck.take(cardsPerPlayer)); players.add(player); } - players.play(); } diff --git a/src/GameTest.java b/src/GameTest.java index 82b7319..b65d8ca 100644 --- a/src/GameTest.java +++ b/src/GameTest.java @@ -16,8 +16,8 @@ class GameTest { @Test void createDeck() { assertEquals(2, game.players.size()); - for (int i = 0; i < 2; i++) { - assertEquals(20, game.players.get(i).drawPile.size()); + for (Player player : game.players) { + assertEquals(40 / 2, player.drawPile.size()); } } diff --git a/src/Main.java b/src/Main.java index 6b0c323..9a2a480 100644 --- a/src/Main.java +++ b/src/Main.java @@ -3,8 +3,14 @@ */ public class Main { + /** + * The entry point of application. + * + * @param args the input arguments + */ public static void main(String[] args) { - new Game(10, 2); + Game game = new Game(10, 2); + game.players.play(); System.out.print(Out.get()); } } diff --git a/src/Out.java b/src/Out.java index 68cc084..f6a0a3b 100644 --- a/src/Out.java +++ b/src/Out.java @@ -1,18 +1,49 @@ import java.util.ArrayList; +/** + * The type Out. + */ public class Out { + /** + * The Output. + */ static final ArrayList output = new ArrayList<>(); - private Out() { throw new IllegalStateException("Utility class"); } + /** + * Instantiates a new Out. + */ + protected Out() { throw new IllegalStateException("Utility class"); } + /** + * Gets output. + * + * @return the output + */ + public static ArrayList getOutput() { + return output; + } + + /** + * Println. + * + * @param string the string + */ public static void println(String string) { output.add(string); } + /** + * Println. + */ public static void println() { println(""); } + /** + * Get string. + * + * @return the string + */ public static String get() { StringBuilder string = new StringBuilder(); for (String s : output) { diff --git a/src/OutTest.java b/src/OutTest.java new file mode 100644 index 0000000..87fab77 --- /dev/null +++ b/src/OutTest.java @@ -0,0 +1,20 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class OutTest { + + @Test + void printlnStoresString() { + Out.getOutput().clear(); + Out.println(); + assertEquals("\n", Out.get()); + Out.println("Hello"); + assertEquals("\nHello\n", Out.get()); + } + + @Test + void throwsException() { + assertThrows(IllegalStateException.class, Out::new); + } +} \ No newline at end of file diff --git a/src/Pile.java b/src/Pile.java index 0a4eb40..008f109 100644 --- a/src/Pile.java +++ b/src/Pile.java @@ -3,7 +3,16 @@ import java.util.Collections; import java.util.Random; import java.util.stream.IntStream; +/** + * The type Pile. + */ public class Pile extends ArrayList { + /** + * Create deck pile. + * + * @param numberOfCards the number of cards + * @return the pile + */ public static Pile createDeck(int numberOfCards) { Pile deck = new Pile(); for (int number = 1; number <= numberOfCards; number++) { @@ -15,6 +24,12 @@ public class Pile extends ArrayList { return deck; } + /** + * Take pile. + * + * @param number the number + * @return the pile + */ public Pile take(int number) { Pile taken = new Pile(); for (int i = 0; i < number; i++) { @@ -27,6 +42,8 @@ public class Pile extends ArrayList { /** * Fisher-Yates shuffle() * https://stackoverflow.com/questions/1519736/random-shuffling-of-an-array + * + * @param random the random */ public void shuffle(Random random) { for (int i = this.size() - 1; i > 0; i--) { @@ -34,15 +51,29 @@ public class Pile extends ArrayList { } } + /** + * Shuffle. + */ public void shuffle() { Random random = new Random(); shuffle(random); } + /** + * Occurrences long. + * + * @param max the max + * @return the long + */ public long occurrences(int max) { return IntStream.range(0, size()).filter(i -> get(i).number == max).count(); } + /** + * Gets max. + * + * @return the max + */ public Card getMax() { Card max = get(0); for (int i = 1; i < this.size(); i++) { diff --git a/src/PileTest.java b/src/PileTest.java index 3bdb290..b27e895 100644 --- a/src/PileTest.java +++ b/src/PileTest.java @@ -1,3 +1,4 @@ +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.Random; @@ -5,17 +6,16 @@ import java.util.Random; import static org.junit.jupiter.api.Assertions.*; class PileTest { + Pile pile = new Pile(); @Test void shuffleEmptyPile() { - Pile pile = new Pile(); pile.shuffle(); assertEquals(0, pile.size()); } @Test void shuffleOneCard() { - Pile pile = new Pile(); pile.add(new Card(1, Card.Suit.CLUBS)); pile.shuffle(); assertEquals(1, pile.size()); @@ -24,7 +24,6 @@ class PileTest { @Test void shuffleCards() { - Pile pile = new Pile(); pile.add(new Card(1, Card.Suit.CLUBS)); pile.add(new Card(2, Card.Suit.DIAMONDS)); pile.add(new Card(3, Card.Suit.HEARTS)); @@ -41,4 +40,47 @@ class PileTest { assertEquals(Card.Suit.HEARTS, pile.get(3).suit); assertEquals(4, pile.size()); } + + @Test + void createDeck() { + pile = Pile.createDeck(1); + assertEquals(1, pile.get(0).number); + assertEquals(1, pile.get(1).number); + assertEquals(1, pile.get(2).number); + assertEquals(1, pile.get(3).number); + assertEquals(4, pile.size()); + } + + @Test + void createDeckWith40Cards() { + pile = Pile.createDeck(10); + assertEquals(40, pile.size()); + } + + @Test + void take() { + Pile taken; + pile = Pile.createDeck(2); + assertEquals(2 * 4, pile.size()); + taken = pile.take(0); + assertEquals(0, taken.size()); + assertEquals(2 * 4, pile.size()); + taken = pile.take(3); + assertEquals(3, taken.size()); + assertEquals(2 * 4 - 3, pile.size()); + } + + @Test + void occurrences() { + pile = Pile.createDeck(2); + assertEquals(4, pile.occurrences(1)); + assertEquals(4, pile.occurrences(2)); + assertEquals(0, pile.occurrences(3)); + } + + @Test + void getMax() { + pile = Pile.createDeck(2); + assertEquals(2, pile.getMax().number); + } } \ No newline at end of file diff --git a/src/Player.java b/src/Player.java index 6b5b312..3a86471 100644 --- a/src/Player.java +++ b/src/Player.java @@ -1,14 +1,37 @@ +/** + * The type Player. + */ public class Player { + /** + * The Name. + */ final String name; + /** + * The Draw pile. + */ final Pile drawPile; + /** + * The Discard pile. + */ final Pile discardPile; + /** + * Instantiates a new Player. + * + * @param name the name + * @param drawPile the draw pile + */ public Player(String name, Pile drawPile) { this.name = name; this.drawPile = drawPile; this.discardPile = new Pile(); } + /** + * Draw card. + * + * @return the card + */ public Card draw() { if (drawPile.isEmpty()) { discardPile.shuffle(); @@ -20,6 +43,11 @@ public class Player { return draw; } + /** + * Cards count int. + * + * @return the int + */ public int cardsCount() { return drawPile.size() + discardPile.size(); } diff --git a/src/PlayerTest.java b/src/PlayerTest.java new file mode 100644 index 0000000..ee8813d --- /dev/null +++ b/src/PlayerTest.java @@ -0,0 +1,37 @@ +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PlayerTest { + Player player; + Pile pile; + + @BeforeEach + void setUp() { + pile = Pile.createDeck(1); + player = new Player("0", pile); + } + + @Test + void drawWithEmptyDrawPile() { + int n = player.drawPile.size(); + player.discardPile.addAll(player.drawPile.take(n)); + assertEquals(0, player.drawPile.size()); + assertEquals(n, player.discardPile.size()); + player.draw(); + assertEquals(n - 1, player.drawPile.size()); + assertEquals(0, player.discardPile.size()); + } + + @Test + void draw() { + Card card = player.draw(); + assertEquals(1, card.number); + } + + @Test + void cardsCount() { + assertEquals(4, player.cardsCount()); + } +} \ No newline at end of file diff --git a/src/Players.java b/src/Players.java index e027bf1..ea10b25 100644 --- a/src/Players.java +++ b/src/Players.java @@ -1,22 +1,34 @@ import java.util.ArrayList; +/** + * The type Players. + */ public class Players extends ArrayList { private final Pile pot = new Pile(); private final Pile draws = new Pile(); + /** + * Play. + */ public void play() { - while (playersLeft() != 1) { - draws.clear(); - for (Player player : this) { - String output = String.format("Player %s (%d cards)", player.name, player.cardsCount()); - Card card = player.draw(); - draws.add(card); - Out.println(String.format("%s: %d - %s", output, card.number, card.suit)); + if (size() > 0) { + while (playersLeft() > 1) { + draws.clear(); + for (Player player : this) { + String output = String.format("Player %s (%d cards)", player.name, player.cardsCount()); + Card card = player.draw(); + draws.add(card); + Out.println(String.format("%s: %d - %s", output, card.number, card.suit)); + } + pot.addAll(draws); + givePotOnWin(); + } + if (size() == 0) { + Out.println("No winner in the game!"); + } else { + Out.println(String.format("Player %s wins the game!", get(0).name)); } - pot.addAll(draws); - givePotOnWin(); } - Out.println(String.format("Player %s wins the game!", get(0).name)); } private int playersLeft() { diff --git a/src/PlayersTest.java b/src/PlayersTest.java new file mode 100644 index 0000000..7bca363 --- /dev/null +++ b/src/PlayersTest.java @@ -0,0 +1,73 @@ +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PlayersTest { + Players players = new Players(); + + @BeforeEach + void setUp() { + Out.getOutput().clear(); + } + + @Test + void playForZeroPlayers() { + players.play(); + assertEquals("", Out.get()); + } + + @Test + void playForOnePlayerMakesHimAWinner() { + Player player = new Player("0", Pile.createDeck(1)); + players.add(player); + players.play(); + assertEquals("Player 0 wins the game!\n", Out.get()); + } + + @Test + void playWithSameCardsHasNoWinner() { + Player player = new Player("0", Pile.createDeck(1)); + players.add(player); + player = new Player("1", Pile.createDeck(1)); + players.add(player); + players.play(); + assertTrue(Out.get().contains("No winner in this round")); + assertTrue(Out.get().contains("No winner in the game!")); + } + + @Test + void playWithTwoPlayers() { + Pile deck = new Pile(); + deck.add(new Card(1, Card.Suit.CLUBS)); + deck.add(new Card(2, Card.Suit.DIAMONDS)); + deck.add(new Card(3, Card.Suit.HEARTS)); + deck.add(new Card(4, Card.Suit.SPADES)); + Player player = new Player("0", deck.take(2)); + players.add(player); + player = new Player("1", deck.take(2)); + players.add(player); + players.play(); + assertTrue(Out.get().contains("Player 1 wins this round")); + assertTrue(Out.get().contains("Player 1 wins the game!")); + } + + @Test + void playerOneWinningFourCards() { + Pile deck = new Pile(); + deck.add(new Card(1, Card.Suit.CLUBS)); + deck.add(new Card(2, Card.Suit.DIAMONDS)); + deck.add(new Card(1, Card.Suit.HEARTS)); + deck.add(new Card(4, Card.Suit.SPADES)); + Player player = new Player("0", deck.take(2)); + players.add(player); + player = new Player("1", deck.take(2)); + players.add(player); + players.play(); + assertTrue(Out.get().contains("No winner in this round")); + assertTrue(Out.get().contains("Player 1 wins this round")); + assertTrue(Out.get().contains("Player 1 wins the game!")); + assertEquals("1", players.get(0).name); + assertEquals(4, players.get(0).cardsCount()); + } +} \ No newline at end of file