diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Card.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Card.java new file mode 100644 index 000000000..0f18fdd19 --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Card.java @@ -0,0 +1,66 @@ +package com.codedifferently.lesson16.danielsonobject; + +import java.util.Objects; +import lombok.Getter; + +@Getter +public class Card { + private final Suit suit; + private final int rank; + + public Card(Suit suit, int rank) { + if (rank < 1 || rank > 15) { + throw new IllegalArgumentException("Rank must be between 1 and 15"); + } + this.suit = suit; + this.rank = rank; + } + + public Suit getSuit() { + return suit; + } + + public int getRank() { + return rank; + } + + public Card compareTo(Card other) { + if (this.rank > other.rank) { + return this; + } else if (this.rank < other.rank) { + return other; + } else { + return null; // They are equal + } + } + + @Override + public String toString() { + if (suit == Suit.NONE) { + return "Joker"; + } else if (2 <= rank && rank <= 10) { + return rank + " of " + suit.toString(); + } else { + String face; + switch (this.rank) { + case 11 -> face = "Jack"; + case 12 -> face = "Queen"; + case 13 -> face = "King"; + default -> face = "Ace"; + } + return face + " of " + suit.toString(); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Card card)) return false; + return rank == card.rank && suit == card.suit; + } + + @Override + public int hashCode() { + return Objects.hash(suit, rank); + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Deck.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Deck.java new file mode 100644 index 000000000..b3186d1ed --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Deck.java @@ -0,0 +1,84 @@ +package com.codedifferently.lesson16.danielsonobject; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Random; + +public class Deck { + private final Random rand = new Random(); + private final String brand; + private final ArrayList cards; + private int max_size = 54; + + public Deck(String brand) { + this.brand = brand; + this.cards = new ArrayList<>(); + for (Suit suit : Suit.values()) { + if (suit == Suit.NONE) { + cards.add(new Card(Suit.NONE, 14)); // This will represent the Jokers. + cards.add(new Card(Suit.NONE, 15)); + } else { + for (int rank = 1; rank <= 13; rank++) { + cards.add(new Card(suit, rank)); + } + } + } + } + + public String getBrand() { + return brand; + } + + public void shuffle() { + Collections.shuffle(cards); + } + + public Card draw() { + if (cards.isEmpty()) { + throw new DeckException("There are no Cards to draw"); + } + return cards.removeFirst(); + } + + public int getSize() { + return cards.size(); + } + + public ArrayList getCards() { + return cards; + } + + public void addToDeck(Card card) throws DeckException { + if (cards.size() + 1 > max_size) { + throw new DeckException("Deck limit reached"); + } + cards.addFirst(card); + } + + public void shuffleIntoDeck(Card card) throws DeckException { + if (cards.size() + 1 > max_size) { + throw new DeckException("Deck limit reached"); + } + int insert = rand.nextInt(0, max_size); + + cards.add(insert, card); + } + + public void removeJokers() throws JokerException { + if (max_size == 52) { + throw new JokerException("There are already no Jokers"); + } + cards.removeIf(card -> card.getSuit() == Suit.NONE); + max_size = 52; + } + + public void addJokers() throws JokerException { + if (max_size == 52) { + max_size = 54; + shuffleIntoDeck(new Card(Suit.NONE, 14)); + shuffleIntoDeck(new Card(Suit.NONE, 15)); + } else if (max_size == 54) { + throw new JokerException("Jokers are already accounted for"); + } + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/DeckException.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/DeckException.java new file mode 100644 index 000000000..31eb1deed --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/DeckException.java @@ -0,0 +1,7 @@ +package com.codedifferently.lesson16.danielsonobject; + +public class DeckException extends IllegalStateException { + DeckException(String message) { + super(message); + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/JokerException.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/JokerException.java new file mode 100644 index 000000000..1c47515bb --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/JokerException.java @@ -0,0 +1,7 @@ +package com.codedifferently.lesson16.danielsonobject; + +public class JokerException extends Exception { + public JokerException(String message) { + super(message); + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Suit.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Suit.java new file mode 100644 index 000000000..955e36da9 --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/danielsonobject/Suit.java @@ -0,0 +1,9 @@ +package com.codedifferently.lesson16.danielsonobject; + +public enum Suit { + NONE, + HEARTS, + DIAMONDS, + CLUBS, + SPADES +} diff --git a/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/danielsonobject/CardTest.java b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/danielsonobject/CardTest.java new file mode 100644 index 000000000..cae8cc5fa --- /dev/null +++ b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/danielsonobject/CardTest.java @@ -0,0 +1,45 @@ +package com.codedifferently.lesson16.danielsonobject; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.Test; + +public class CardTest { + // Test cases for Card class + @Test + public void testCardCreation() { + Card card = new Card(Suit.HEARTS, 10); + assertThat(card.getSuit()).isEqualTo(Suit.HEARTS); + assertThat(card.getRank()).isEqualTo(10); + + card = new Card(Suit.SPADES, 3); + assertThat(card.getSuit()).isEqualTo(Suit.SPADES); + assertThat(card.getRank()).isEqualTo(3); + + assertThatThrownBy(() -> new Card(Suit.HEARTS, 0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Rank must be between 1 and 15"); + } + + @Test + public void JokerCreation() { + Card card = new Card(Suit.NONE, 14); + assertThat(card.getSuit()).isEqualTo(Suit.NONE); + assertThat(card.getRank()).isEqualTo(14); + } + + @Test + public void testCompareTo() { + Card card1 = new Card(Suit.HEARTS, 10); + Card card2 = new Card(Suit.SPADES, 3); + Card card3 = new Card(Suit.DIAMONDS, 10); + Card card4 = new Card(Suit.NONE, 14); // Joker + + assertThat(card1.compareTo(card2)).isEqualTo(card1); // 10 > 3 + assertThat(card2.compareTo(card1)).isEqualTo(card1); // 3 < 10 + assertThat(card1.compareTo(card4)).isEqualTo(card4); // 10 < Joker + assertThat(card4.compareTo(card2)).isEqualTo(card4); // Joker > + assertThat(card1.compareTo(card3)).isNull(); // 10 + } +} diff --git a/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/danielsonobject/DeckTest.java b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/danielsonobject/DeckTest.java new file mode 100644 index 000000000..0e77286df --- /dev/null +++ b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/danielsonobject/DeckTest.java @@ -0,0 +1,114 @@ +package com.codedifferently.lesson16.danielsonobject; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.ArrayList; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class DeckTest { + Deck deck; + + @BeforeEach + public void setUp() { + deck = new Deck("Bicycle"); + } + + @Test + public void Deckexists() { + Deck deck = new Deck("Bicycle"); + assertThat(deck).isNotNull(); + } + + @Test + public void getCards() { + ArrayList cards = deck.getCards(); + assertThat(cards).isNotNull(); + } + + @Test + public void removeJokerTest() throws JokerException { + deck.removeJokers(); + assertEquals(deck.getSize(), 52); + for (Card card : deck.getCards()) { + if (card.getRank() == 14) { + fail("There is still a Joker in the deck"); + } + } + } + + @Test + public void addJokerTest() throws JokerException { + assertThatThrownBy(() -> deck.addJokers()) + .isInstanceOf(JokerException.class) + .hasMessage("Jokers are already accounted for"); + + deck.removeJokers(); + deck.addJokers(); + assertEquals(deck.getSize(), 54); + int count = 0; + for (Card card : deck.getCards()) { + if (card.getSuit() == Suit.NONE) { + count++; + } + } + assertEquals(2, count); + } + + @Test + public void brandTest() { + assertEquals("Bicycle", deck.getBrand()); + assertEquals("Copag", new Deck("Copag").getBrand()); + } + + @Test + public void drawTest() { + Card card1 = deck.draw(); + Card card2 = deck.draw(); + + assertNotEquals(card1, card2); + + assertEquals(52, deck.getSize()); + } + + @Test + public void sizeTest() { + assertEquals(deck.getSize(), 54); + } + + @Test + public void addToDeckTest() { + int initialSize = deck.getSize(); + Card card1 = deck.draw(); + deck.addToDeck(card1); + assertEquals(card1, deck.getCards().getFirst()); + assertEquals(initialSize, deck.getSize()); + } + + @Test + public void DeckExceptionTest() { + assertThatThrownBy(() -> deck.addToDeck(new Card(Suit.HEARTS, 1))) + .isInstanceOf(DeckException.class) + .hasMessage("Deck limit reached"); + + for (int x = 0; x < 54; x++) { + deck.draw(); + } + assertThatThrownBy(() -> deck.draw()) + .isInstanceOf(DeckException.class) + .hasMessage("There are no Cards to draw"); + } + + @Test + public void shuffleTest() { + Deck copy = new Deck("Bicyle"); + assertEquals(deck.getCards(), copy.getCards()); + deck.shuffle(); + assertNotEquals(deck.getCards(), copy.getCards()); + assertEquals(deck.getSize(), copy.getSize()); + } +}