Created
November 3, 2015 23:58
-
-
Save Michael0x2a/f581e1afb1203708f2e1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Michael Lee | |
// Section AP | |
// Tuesday, April 14, 2015 | |
// Sample program: ListDeck.java | |
// | |
// This class represents a deck of cards, which you can shuffle | |
// and manipulate. | |
import java.util.*; | |
public class ListDeck implements Deck { | |
private List<String> cards; | |
private Random random; | |
// Creates an empty deck of cards. | |
public ListDeck() { | |
this.cards = new ArrayList<String>(); | |
this.random = new Random(); | |
} | |
// Returns the number of cards in the deck. | |
public int size() { | |
return this.cards.size(); | |
} | |
// Returns 'true' if the deck contains no cards, returns 'false' otherwise. | |
public boolean isEmpty() { | |
return this.cards.isEmpty(); | |
} | |
// Removes and returns the card currently at the top of the deck. | |
// | |
// Preconditions: | |
// - The deck is not empty (otherwise throws NoSuchElementException) | |
public String dealCard() { | |
this.failIfUnableToRemove(1); | |
return this.cards.remove(this.cards.size() - 1); | |
} | |
// Returns the requested amount of cards from the top of the deck. | |
// | |
// Preconditions: | |
// - "amount" must not be negative (otherwise throws IllegalArgumentException) | |
// - "amount" must not exceed the size of the deck | |
// (otherwise throws NoSuchElementException) | |
// | |
// Postconditions: | |
// - Returns a new Deck containing the cards, with the card at the | |
// top of this deck located at the bottom of the returned one. | |
public Deck dealCards(int amount) { | |
this.failIfUnableToRemove(amount); | |
Deck output = new ListDeck(); | |
// Cycle through cards to transfer them | |
for (int i = 0; i < amount; i++) { | |
output.addCard(this.dealCard()); | |
} | |
return output; | |
} | |
// Adds a card to the top of the deck. | |
// | |
// Preconditions: | |
// - The card is not null | |
public void addCard(String card) { | |
this.cards.add(card); | |
} | |
// Moves all the cards in the other deck to this one. | |
// | |
// Preconditions: | |
// - "other" must not be null | |
// | |
// Postconditions: | |
// - The other deck will be emptied of all cards | |
public void mergeDeck(Deck other) { | |
while (!other.isEmpty()) { | |
this.cards.add(other.dealCard()); | |
} | |
} | |
// Randomly shuffles the cards in the deck in place. | |
public void shuffle() { | |
// Implements the Fisher-Yates shuffle algorithm | |
// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle | |
for (int currIndex = 0; currIndex < this.cards.size(); currIndex++) { | |
// Selects a random card beyond this one (apparently, selecting | |
// literally any card results in an imperfect, not fully random | |
// shuffle, according to math). | |
int randIndex = this.randomInt(currIndex, this.cards.size() - 1); | |
this.swap(currIndex, randIndex); | |
} | |
} | |
// Returns a copy of the contents of the card as a list without modifying | |
// the deck itself. | |
// | |
// Postconditions: | |
// - The card at the top of the deck will be placed at the end of the list. | |
public List<String> toList() { | |
// Making a copy so that if the client modifies the returned list, | |
// they won't modify the field. | |
return new ArrayList<String>(this.cards); | |
} | |
// Returns a string representing this deck. | |
// | |
// Postconditions: | |
// - Each card will be separated by comma, surrounded by brackets | |
// - The card at the top of the deck will be placed at the end of the string. | |
// | |
// Example of output: | |
// | |
// [King of Spades, 9 of Hearts, Ace of Clubs, 4 of Spades, ...] | |
// | |
public String toString() { | |
return this.cards.toString(); | |
} | |
// Swaps the two cards at the given indexes. | |
// | |
// Preconditions: | |
// - The two indexes must be valid indexes (ie 0 <= index < size) | |
private void swap(int indexA, int indexB) { | |
String cardA = this.cards.get(indexA); | |
String cardB = this.cards.get(indexB); | |
this.cards.set(indexA, cardB); | |
this.cards.set(indexB, cardA); | |
} | |
// Returns a random int from min to max, inclusive. | |
// | |
// Preconditions: | |
// - 'max' must be greater then or equal to min. | |
// | |
// Postcondition: | |
// - Returns a random int from min <= output <= max | |
private int randomInt(int min, int max) { | |
// Adding '1' to make sure the output is completely inclusive. | |
return this.random.nextInt((max - min) + 1) + min; | |
} | |
// Throws an NoSuchElementException if it is not possible to remove | |
// "n" cards from the deck, otherwise does nothing. | |
private void failIfUnableToRemove(int n) { | |
if (this.size() < n) { | |
throw new NoSuchElementException("Deck doesn't contain enough cards"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment