Commit 11aab9b1 authored by Vansh V. Tibrewal's avatar Vansh V. Tibrewal
Browse files

Extensive tests for faroShuffle added

parent eaca888d
No related merge requests found
Showing with 81 additions and 22 deletions
+81 -22
...@@ -9,10 +9,7 @@ import org.junit.jupiter.params.provider.CsvSource; ...@@ -9,10 +9,7 @@ import org.junit.jupiter.params.provider.CsvSource;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
...@@ -93,6 +90,10 @@ public class DeckTests { ...@@ -93,6 +90,10 @@ public class DeckTests {
return inner; return inner;
} }
private static List<Card> cloneList(List<Card> list) {
return (ArrayList<Card>) ((ArrayList<Card>) list).clone();
}
@Test @Test
@DisplayName("hasNoCards returns true on an empty deck") @DisplayName("hasNoCards returns true on an empty deck")
public void testHasNoCardsEmpty() { public void testHasNoCardsEmpty() {
...@@ -174,7 +175,7 @@ public class DeckTests { ...@@ -174,7 +175,7 @@ public class DeckTests {
List<Card> ref = new ArrayList<>(); List<Card> ref = new ArrayList<>();
for (int i = 1; i < 10; i++) { for (int i = 1; i < 10; i++) {
final int drawCount = i; // should throw an exception for numCards drawn (deck has numCards - 1 cards) final int drawCount = i; // should throw an exception for numCards drawn (deck has numCards - 1 cards)
final List<Card> inp = (ArrayList<Card>) ((ArrayList<Card>) ref).clone(); final List<Card> inp = cloneList(ref);
assertThrowsExactly(EmptyDeckException.class, () -> newDeck(inp).draw(drawCount)); assertThrowsExactly(EmptyDeckException.class, () -> newDeck(inp).draw(drawCount));
ref.add(new Card(null, null)); ref.add(new Card(null, null));
} }
...@@ -213,25 +214,83 @@ public class DeckTests { ...@@ -213,25 +214,83 @@ public class DeckTests {
assertEquals(List.of(), getList(deck)); assertEquals(List.of(), getList(deck));
} }
//TODO: write more tests for faroShuffle? @Test
//public void faroShuffle() { @DisplayName("faroShuffle of decks with 0-3 cards work as expected (no effect on 0-2, swap last 2 cards for 3)")
public void testFaroShuffleSmall() {
List<Card> ref = new ArrayList<>();
Deck deck = newDeck(cloneList(ref));
for (int i = 0; i < 2; i++) {
deck.faroShuffle();
assertEquals(ref, getList(deck));
}
ref.add(new Card(Rank.ACE, null));
deck = newDeck(cloneList(ref));
for (int i = 0; i < 2; i++) {
deck.faroShuffle();
assertEquals(ref, getList(deck));
}
ref.add(new Card(Rank.TWO, null));
deck = newDeck(cloneList(ref));
for (int i = 0; i < 5; i++) {
deck.faroShuffle();
assertEquals(ref, getList(deck));
}
ref.add(new Card(Rank.THREE, null));
deck = newDeck(cloneList(ref));
List<Card> swapped = List.of(new Card(Rank.ACE, null), new Card(Rank.THREE, null), new Card(Rank.TWO, null));
for (int i = 0; i < 10; i++) {
deck.faroShuffle();
if (i % 2 == 0) assertEquals(swapped, getList(deck));
else assertEquals(ref, getList(deck));
}
}
public class CardIterator implements Iterator<Card> {
private Rank[] ranks = Rank.values();
private Suit[] suits = Suit.values();
private int rankIdx = 0;
private int suitIdx = 0;
@Override
public boolean hasNext() {
return rankIdx < ranks.length && suitIdx < suits.length;
}
@Override
public Card next() {
Card card = new Card(ranks[rankIdx], suits[suitIdx]);
suitIdx++;
if (suitIdx >= suits.length) {
suitIdx = 0;
rankIdx++;
}
return card;
}
}
@Test @Test
public void testPerfectFaroShuffle() { @DisplayName("faroShuffle of decks with 1-52 cards works as expected via perfect shuffle properties")
Deck d = new Deck(); public void testFaroShuffleBig() {
Field dl = Reflection.getFieldByType(Deck.class, List.class); Iterator<Card> cardGen = new CardIterator();
assert dl != null; List<Card> ref = new ArrayList<>();
List<Card> curr = Reflection.getFieldValue(Deck.class, dl.getName(), d); for (int i = 0; i < 52; i++) {
assert curr != null; ref.add(cardGen.next());
List<Card> initCopy = curr.stream().toList(); Deck deck = newDeck(cloneList(ref));
for (int i = 0; i < 7; i++) { int size = ref.size();
d.faroShuffle(); int modBy = size;
curr = Reflection.getFieldValue(Deck.class, dl.getName(), d); if (size % 2 == 0) modBy -= 1;
assertNotEquals(initCopy, curr); long pow = 1;
boolean firstMatch = 1 % modBy != 1;
for (int shuffles = 1; shuffles < 63; shuffles++) {
pow *= 2;
if (pow % modBy == 1) {
for (int j = 0; j < shuffles; j++) {
deck.faroShuffle();
if (firstMatch) assertNotEquals(ref, getList(deck));
}
firstMatch = false;
assertEquals(ref, getList(deck));
}
}
} }
d.faroShuffle(); }
curr = Reflection.getFieldValue(Deck.class, dl.getName(), d);
assertEquals(initCopy, curr);
}
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment