In this project, we will write a program to play a simple card game known as War. In War, a standard deck of 52 playing cards is shuffled and divided evenly among two players (the user and the computer). Players simultaneously turn over the top card of their respective decks, and the player with the high value card takes both cards, adding them to the bottom of their deck. In the case of a tie (the two cards have equal value), there is a war where players each place three cards face down and then one card face up; the player with the higher value takes all (ten) cards. In the case of another tie, this process repeats until there is a winner. For added complexity, a player may choose to shuffle their deck of cards before each battle. The game continues until one player is out of cards. For more details, see War.
In playing the game, there are several piles of cards: the two players' decks, and the piles of cards in the "battle" by each player. Cards are continually moved between these different piles. Since the cards in the pile have a specific order, we will use a List to represent these card piles.
In this assignment, you will implement two variations of the list
Abstract Data Type (ADT):
We have already provided you with a skeleton for the LinkedList class,
which you can download here:
Note that the Card object provides getters for the rank and suit, which cannot be changed once they are initialized by the constructor. It also provides a set of static final constants to represent face cards and the suits.public class Card ---------------------------------------------------------------------------------------------------------- Card(int rank, int suit) // constructor int compareRank(Card c) // returns a negative number if this object is lower in rank than c, // 0 if the cards are equal rank, and a positive number if this object // is higher in rank than c. Aces are considered 'high'. boolean equals(Card c) // returns true if the cards are the same, false otherwise int getRank() // returns the rank of the card: 2, 3, ..., 10, JACK, QUEEN, KING, ACE int getSuit() // returns the suit of the card, either CLUBS, DIAMONDS, HEARTS, SPADES String toString() // returns a string representation of the card ---------------------------------------------------------------------------------------------------------- static final int CLUBS, DIAMONDS, HEARTS, SPADES static final int JACK, QUEEN, KING, ACE
The Card class is complete as given -- you should not modify it in completing the assignment.Card c1 = new Card(Card.ACE, Card.SPADES); // creates the ace of spades Card c2 = new Card(10, Card.DIAMONDS); // creates the 10 of diamonds System.out.println(c1.compareRank(c2)); // prints 1 because Ace of spades > 10 diamonds
The List Interface
Your LinkedList class must implement the provided List interface (List.java) exactly as it is given. You are not permitted to modify List.java. In Java, an interface is a special type of construct that defines a public API. Essentially it defines a set of public methods that a class which implements that interface must have, but it doesn't provide any implementation.public Interface List ----------------------------------------------------------------------------------------- boolean add(Card x) // add the object x to the end of the list boolean add(int index, Card x) // add the object x at the specified index int size() // return the number of elements in this list Card get(int index) // return the element at the specified index Card set(int index, Card x) // replace the object at the specified index, // returning the replaced object Card remove(int index) // remove the object at the specified index // and return it boolean isEmpty() // test whether this list has no elements boolean contains(Card element) // test whether the list contains the given element int indexOf(Card element) // return the first index of the specified element // or -1 if it is not found in the list
The implements keyword in Java allows us to specify the name of an interface that the class must use, in this case, List. The standard LinkedList provides a number of other methods that you are not required to implement in this assignment. For a full list of these methods for a standard LinkedList, you can refer to the javadocs: http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html.public class LinkedList implements List { ... }
Implementing LinkedList
You must complete the provided LinkedList.java skeleton. You must also implement the inner class: Node. (Hint: Your node will need two fields: a next reference and a Card data element). Skeleton methods and explanations for LinkedList are provided in the file.
Notes:
You should see the following output when you run LinkedList.LinkedList l = new LinkedList(); l.add(new Card(Card.ACE, Card.SPADES)); l.add(new Card(2, Card.DIAMONDS)); l.add(new Card(3, Card.HEARTS)); l.add(new Card(4, Card.CLUBS)); for (int i = 3; i >= 0; i--) { System.out.println(l.get(i)); }
Add additional code to your main method to test the other methods of LinkedList. If you do not have tests for your LinkedList implementation, we cannot guarantee we can help you on later parts of the assignment.4 of clubs 3 of hearts 2 of diamonds ace of spades
The Deck object will represent complete or partial decks of cards. The deck will operate like a queue, allowing you to remove cards from the top of the deck and add cards to the bottom of the deck. It will also allow you to shuffle the cards in the deck, randomizing their order.
Building the Deck from LinkedList
While we could completely re-implement this class from scratch, the
best way is to build the Deck off of LinkedList. The Deck class
should have a LinkedList of cards as a private field. The various
methods for the Deck class will then call the corresponding methods on
the private LinkedList field to implement the functionality.
Hint: your Deck class should be much shorter than your LinkedList class. By building Deck off of LinkedList, you gain much of the functionality you need with minimal effort.
Implementing Deck
Your Deck class must conform to the following API:
Unit Testing Deck (Except shuffle())public class Deck -------------------------------------------------------------------------------------------------------------------------- Deck() // creates an empty deck void add(Card x) // add the object x to the bottom of the deck Card draw() // remove the object at the top of the deck, returning it. // if the deck is empty, returns null void fill() // replaces all current cards in deck with 52 playing cards to make it a standard deck boolean isEmpty() // test whether this deck is empty void shuffle() // randomize the order of the cards in the deck int size() // returns the number of cards in the deck
When run, this should output all of the cards in the deck, with the last card being a duplicate ace of spades.Deck deck = new Deck(); deck.fill(); deck.add(new Card(Card.ACE, Card.SPADES)); // add a duplicate ace of spades as the last card while(!deck.isEmpty()) { System.out.println(deck.draw()); }
Implementing shuffle(). Shuffling a deck of cards works very much like selection sort. However instead of picking the smallest remaining card to swap into position, you should pick a random card. There is example code for shuffling an array in Section 1.4 of the textbook (and booksite).
Since you are shuffling a linked list, not an array, you can simply move the cards into position; there is no need to swap. Moreover, you can always move cards to the very front (or very back) of the array, rather than to position i as the array version does.
Your shuffle() implementation must be entirely linked list-based. You may not use arrays.
Testing shuffle(). Add a call to shuffle() immediately after the call to fill() in the testing code above. Your deck should now print in random order, with an extra ace of spades at the end. You should get a different random order each time you run your unit test.
You can read input from the user via StdDraw.nextKeyTyped().
Here is an example of how your WarGame program should operate. You
may enhance the text of the program as you like, but the interaction
(keys the user can press and their effect) must be the same as in this
example.
> java WarGame It's a war of cards! Deck sizes: 26 (yours) vs. 26 (computer's) Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses ENTER] You drew a jack of diamonds The computer drew a 2 of diamonds You won 2 cards! Deck sizes: 27 (yours) vs. 25 (computer's) Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses ENTER] You drew a 6 of spades The computer drew a ace of spades The computer won 2 cards! Deck sizes: 26 (yours) vs. 26 (computer's) Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses ENTER] You drew a 10 of hearts The computer drew a 2 of hearts You won 2 cards! Deck sizes: 27 (yours) vs. 25 (computer's) Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses S] Your deck has been shuffled Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses ENTER] You drew a 6 of clubs The computer drew a 8 of diamonds The computer won 2 cards! Deck sizes: 26 (yours) vs. 26 (computer's) Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses ENTER] You drew a 4 of clubs The computer drew a 4 of diamonds It's a tie! Battle Again! You and the computer each lay down 3 cards. You drew a 9 of diamonds The computer drew a king of clubs The computer won 10 cards! Deck sizes: 21 (yours) vs. 31 (computer's) Press 'ENTER' to fight another battle or 'S' to shuffle your deck! [The user presses ENTER] . . . You won the war!! [The program terminates]
Write a program, AnimatedWarGame.java that plays war and draws and animates the cards using StdDraw. Submit your code and any images in your extra.zip file. You should be able to find card images you like on the internet. Here is a link to two sets of card images, but you can find many others. Make sure to credit the source of your images in your readme and in a comment in your .java file.
The LinkedList class we wrote above can contain only Card objects; however, it is often useful to implement data structures in a more generic way such that they can hold any type of data. Java provides Generics specifically for this purpose.
For extra credit, modify your LinkedList class to be based upon the interface GenericList.java instead of List.java. The methods in GenericList are exactly the same as in List, but they are based on a generic type T that is specified when the LinkedList is declared and initialized. This will enable your LinkedList to contain any type of object, not just Card objects. You will likely need to modify your other classes as well to enable them to use the generic form of the LinkedList.
If you do the extra credit, you will submit two versions of the assignment: the original (non-generic) version of all files as normal, and an extra.zip file containing new versions of all three .java files (LinkedList.java, Deck.java, WarGame.java) modified to work with the generic LinkedList. Even if one or more of these files are unchanged from your non-generic version, you should still include it in extra.zip.
Extra credit: submit a zip file named extra.zip that contains a complete version of your program (all .java files) based on Java generics where LinkedList is based on the GenericList.java interface.