Created
November 3, 2015 23:58
-
-
Save Michael0x2a/97e03aab6797bea60878 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 | |
// Tuesday, April 14, 2015 | |
// Sample program: StackDeck.java | |
// | |
// This class represents a deck of cards, which you can shuffle | |
// and manipulate. | |
import java.util.*; | |
public class StackDeck implements Deck { | |
private Stack<String> cards; | |
// Creates an empty deck of cards. | |
public StackDeck() { | |
this.cards = new Stack<String>(); | |
} | |
// 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.pop(); | |
} | |
// 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); | |
StackDeck output = new StackDeck(); | |
this.transfer(this.cards, output.cards, amount); | |
return output; | |
} | |
// Adds a card to the top of the deck. | |
// | |
// Preconditions: | |
// - The card is not null | |
public void addCard(String card) { | |
this.cards.push(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.push(other.dealCard()); | |
} | |
} | |
// Randomly shuffles the cards in the deck in place. | |
public void shuffle() { | |
// Implements a riffle shuffle -- splits the deck in two, | |
// and splices the two together. | |
// Note: this is an _imperfect_ shuffle. It doesn't actually | |
// randomly shuffle the deck in any way, making this a rigged deck. | |
int half = this.size() / 2; | |
Stack<String> temp1 = new Stack<String>(); | |
Stack<String> temp2 = new Stack<String>(); | |
// Split the deck in two | |
this.transfer(this.cards, temp1, half); | |
this.transfer(this.cards, temp2); // move everything else | |
// Take one card at a time from each half and add it back | |
for (int j = 0; j < half; j++) { | |
this.cards.push(temp1.pop()); | |
this.cards.push(temp2.pop()); | |
} | |
// Take care of the last card if we have an odd number of cards | |
if (!temp2.isEmpty()) { | |
this.cards.push(temp2.pop()); | |
} | |
} | |
// 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() { | |
Stack<String> temp = new Stack<String>(); | |
List<String> output = new ArrayList<String>(); | |
// Move cards to temp stack, reversing it. The bottom card is now | |
// at the top of the stack. | |
this.transfer(this.cards, temp); | |
// Moves everything back, and adds to the list in the correct order | |
while (!temp.isEmpty()) { | |
String card = this.move(temp, this.cards); | |
output.add(card); | |
} | |
return output; | |
} | |
// 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() { | |
if (this.isEmpty()) { | |
return "[]"; | |
} else { | |
Stack<String> temp = new Stack<String>(); | |
String output = this.move(this.cards, temp); | |
// Note: adds to the back of the string, not the front | |
// (so I can fencepost) | |
while (!this.cards.isEmpty()) { | |
String card = this.move(cards, temp); | |
output = card + ", " + output; | |
} | |
// Restores the stack | |
this.transfer(temp, this.cards); | |
return "[" + output + "]"; | |
} | |
} | |
// Transfers everything in the 'src' stack to the 'dest' stack. | |
// | |
// Preconditions: | |
// - Neither stack should be null | |
private void transfer(Stack<String> src, Stack<String> dest) { | |
this.transfer(src, dest, src.size()); | |
} | |
// Transfers the top 'amount' of elements from the 'src' stack to | |
// the 'dest' stack. | |
// | |
// Preconditions: | |
// - Neither stack should be null | |
// - The src stack must have at least 'amount' number of elements | |
// - The amount must not be negative | |
private void transfer(Stack<String> src, Stack<String> dest, int amount) { | |
for (int i = 0; i < amount; i++) { | |
dest.push(src.pop()); | |
} | |
} | |
// Moves one element from 'src' to 'dest', but returns that one element. | |
// | |
// Preconditions: | |
// - Neither stack should be null. | |
// - The 'src' stack must have at least one element. | |
private String move(Stack<String> src, Stack<String> dest) { | |
String card = src.pop(); | |
dest.push(card); | |
return card; | |
} | |
// 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