Programming Assignment

Due:

Please make sure you adhere to the policies on academic honesty.

Please see the general programming webpage for details about the programming environment for this course, and specifically for directions in how to submit your programming assignment electronically.

The files you need for this assignment can be downloaded here.


Contents:

  • Overview
  • Files you will need
  • Requirements and Suggestions
  • Testing and Special Cases
  • Files to Submit
  • Unfamiliar with playing cards?
  • Extra Credit

  • Overview

    Your goal for this program will be to design a class Hand which will be used to simulate playing a game of cards. Every card will have a "suit" and a "value" specified. Your task is to implement the following two routines:

    For the routine insertCard(c), you may assume that the card is given with a valid suit and value. Furthermore, you do not need to worry about whether a new card is identical to an existing card. Just keep them both, as if they are two different cards. (In fact, those who have played Pinochle know that your hand may indeed have two cards with identical value and suit).

    The semantics of the playDown(suit) routine is meant to model the rules of many common games (e.g., Hearts, Bridge, Pinochle) which require a player to "follow suit" when possible. Because of this requirement, players often find it convenient to organize their hand so that all cards of the same suit are consecutive in the hand (though the order of the suits, and the order of the cards within a particular suit may remain arbitrary).

    A naive implementation for maintaining cards of the same suit grouped might still require a linear walk through the entire hand. When inserting a new card, one might have to walk from one end of the list until finding other cards of the same suit (or realizing that there are none). Similarly, when trying to play a card of a particular suit, one might have to scan the entire hand.

    A better approach is to maintain four "fingers" into the hand, one for each suit, allowing insertions and deletions to be implemented in constant time (no matter how large the size of the hand becomes). You are required to implement this constant time approach based on the use of underyling List and Position ADTs. A single List will be used to store all cards, and each "finger" will be represented by a Position in that List.


    Files you will Need

    The files you need for this assignment can be downloaded here.

    For this assignment, we will be providing you with what might seem like an enormous number of different files which you will need in your project. We will briefly discuss the purpose of each file:


    Requirements and Suggestions

    In the end, meeting the requirements for this assignment can be easy. A perfect solution can be written using less than 40 lines of additional code in Hand.java (not counting the extra credit). At the same time, past students have submitted solutions in excess of 300 additional lines of code yet flawed.

    Our real goal of this programming assignment is to give you familiarity with the List and Position ADTs from the text. In a sense, you will be stepping to the other side of the wall we often discuss when defining interfaces in this class. That is, you will not be required to implement the List data structure; the book as already done this and we will provide you with the implementation. All you need to know is the high-level List ADT, and how to use the methods it provides to accomlish the task at hand. Although the program does not necessarily involve a great deal of work, you should expect to use a good deal of time in learning the proper syntax and semantics of the List interface.

    Our strict requirement for this assignment is that you must store all of the cards in a single instantiation of the List ADT (that is, you cannot create four separate lists for the four suits). Within that list, you should use the Position abstracton to somehow represent where, in the large list, cards of a given suit might be found. This will allow you to insert or remove desired cards without having to traverse the entire list.

    The rest of the design details are left to your choice. We will add a few words of advice though.

  • The first advice is to note that the four suits are distinct, but the treatment of them is symmetrical. Though we talk about them as clubs, diamonds, etc. you will note that the Card class defines the suit as an int, with value in {0, 1, 2, 3}. This is for convenience. For example, rather than making four separate variables for the four positions, we suggest that you use an array of four positions defined as:
      Position finger[4];
    
    In this way, you can start writing code with syntax finger[s] rather than writing code with a variable SpadeFinger and then having to cut-and-paste that code for HeartFinger and so on.

    In general, the temptation to "cut-and-paste" when coding is always to be avoided. The problem with such "cut-and-paste" coding is that your program gets unnecessarily longer, you potentially duplicate unseen bugs to many places in your code, which you will later have to track down, and you might create new bugs as you slighly modify the pasted portions. If you ever find yourself tempted to cut-and-paste you should step back and think about whether your code could be redesigned.

  • There are two reasonable ways to approach the use of Position's for locating cards of a given suit. The direct approach is to have a Position for each suit which literally represents the position in the list where a card of the suit can be found. Of course, there become special cases, such as how the Position should appear when there are no cards of a given suit.

    An alternative is to use a "sentinel" approach to attempt to reduce the number of special cases. For this assignment, such an approach might be to initially insert four "artificial" cards into the list to serve as bookmarks (or should that be bookends). In this way, even if the hand does not contains any cards of a given suit, a bookmark for that suit can still be found.


  • Testing and Special Cases

    We will again ask each student to submit a file "inputfile" which we will use in a round-robin competition. The assignment is worth 10 points. Eight points will be awarded based on our own evaluation of your assignment. One additional point will be awarded fractionally based on how well your program performs on other students' inputs. The final point will be awarded fractionally based on how well your input fools other students' programs.

    You will find in developing your program that many different special case exists for this assignment. These range from how to represent a "finger" when a hand contains zero cards of a particular suit, as well as simply being careful in dealing with the List interface in a way so that you do not end up with any unwanted exceptions.

    Your file should be formatted perfectly to work as input to CardsDriver. You may use at most 100 commands, and you are not allowed to call the extra credit methods (as students are not required to implement these).


    Files to Submit

    You should submit at least three files:


    Unfamiliar with playing cards?

    If you are not familiar with cards or card games, do not worry. All that really matters for this assignment is that a card is defined as a member of the cross-product . Feel free to ask if you have additional questions.


    Extra Credit (1 point)

    You may receive 1 additional point if you implement the following two routines in Hand.java:

    Iterators (and the ObjectIterator ADT) are discussed in Chapter 5.5 of the text. From your point of view, it might seem easy to imagine code which walks through the List your maintain (or a subset of that list). The purpose of an iterator is to give the user sequential access to a particular group of objects, while still managing to avoid giving away information about the details of your implementation (such as the fact that you decided to use a List).

    There is not necessarily a great deal of code required to implement these methods, however it will require a very clear understanding of the abstractions involved. In particular, ObjectIterator is simply an interface, and you will have to create a new class which will implement this interface. Of course, designing such a class requires very close interaction with the Hand class which you will have already defined.


    Last modified: 6 September 2002