Vous êtes sur la page 1sur 6

GinRummy

John Korecki
CSE 331
8/6/2004

GinRummy is a card game written in C++ that uses cards.dll to draw cards on a
win32 API based GUI. It serves two purposes. The first, like any game, is to be played.
The second purpose is as an educational tool. Open source Win32 programs are hard to
find and open source win32 programs using cards.dll are even harder to find. By placing
GinRummy on sourceforge.net, it can hopefully aid other programmers in making
applications using win32 and cards.dll. The program has 3 difficulty levels which set the
skill with which the computer opponent will play. Turns are taken drawing from the deck
or discard pile into the hand. Then, one card is selected to discard onto the discard pile.
As soon as all cards are involved in a grouping of three or more, game play ends. A
grouping is defined as a set of cards of the same value or as a straight which is cards of
consecutive value of the same suit. After one player or the other wins, the winners score
is shown and a new game may be started.
Not including the data structures created to underlay the hand class, there are a
total of 8 classes. The rummyCard class forms the prime data type for the rummyHand
class, the rummyDeck class, the rummyDiscard class. Each of these classes pass
rummyCards back and forth between each other, based on whether a discard or draw
function is called. There are two rummyHands, each belonging to the two player classes,
human and computer. Because much of the functionality of the human and computer
classes is in common, both inherit from the player class. Finally, the rummyGame class
contains the human player, and computer player, the discard deck, and the draw deck.
The rummyGame interfaces with the win32 functionality so that after one game object is
created, all other functionality is accessed through the rummyGame object. For an easier
view of these interactions, the UML diagram is included. To examine different data

structure efficiency, the rummyHand class was written to be compatible with the STL
vector, STL list, a custom written myVector class and a custom written myList class.
The myVector class and myList class both have an exceptions class that help to
detect error. The GinRummy program does not handle errors during runtime, but the
myList and myVector throwing errors allows for programming by showing errors during
debugging. Other basic error handling mechanisms are in place, such as testing
preconditions on some vital functions.
The rummyHand class interacts with its underlying data structure in a variety of
ways. First, rummyCards need to be inserted into the hand in a sorted manner. Also,
rummyCards need to be deleted from the hand after being discarded. Also, to make the
game easier for the player to find cards, as well as making it easier for the game to
determine if a hand has won. Since both a vector and a list could be used in these
situations, the two were times against each other to see which would be the most efficient
to use. In addition, myVector and myList were developed to see if a bare-bones
implementation of a vector or list would be even more efficient than the STL list and
vector.
The myVector class has a very simple API, mainly because there is not much of a
vectors functionality that GinRummy requires. myVector has a void constructor and a
copy constructor define, but no other constructors. It also has the functions size( ) and
empty( ); Size returns an integer representing the size of the vector. Empty returns true if
the vectors size is zero and false otherwise. pop_back( ) takes no argument and removes
the element at the back of the vector and reduces the size by one. push_back( ) inserts the
parameter passed to it into the vector at the back and increases the size by one. The

bracket operator ( [] ) returns the element in the vector at the location passed into the
brackets.
The next group of myVector functions deal with the iterator class built for
myVector. begin() returns an iterator pointing at the first element in the vector and end()
returns() an iterator pointing at the last element in the vector. insert(iter,item) takes the
item indicated and inserts it at the position indicated by iterator. erase(iter) performs the
opposite operation and erases the element in the vector at the position indicated by iter.
The API for myList is the same because it contains all of the same functions, including
the bracket operator.
The efficiency analysis focused primarily on the insert function of the hand class
using all four of the data structures that make up the hand. It is expected that for an insert
operation, the total time needed insert would be much less for a list or myList object,
while the vector or myVector would take much more time. It is also expected that the
myList and myVector structures would be faster at an insert than their STL counterparts
because of the minimal nature.
This however, was not the case. Finding the average of 500 trials inserting 2000
shuffled decks of 52 cards, the STL vector took the least amount of time, 0.4603 seconds.
The object of type myList came in second, taking 0.5172 seconds to complete all of its
insertions. Next were myVector (0.5276 seconds) and the STL list (0.5949 seconds).
These results seemed counter intuitive and not at all correct, so a second trial was
set up to test the data structures against each other. Instead of using the insert function
from the rummyhand class, the insert function of each individual data structure would be

timed instead. It is possible that the insert function or rummyHand somehow masks the
true complexity of the insert functions for the data structures.
Upon going back over the algorithm inside of rummyHand to insert, one line was
missing from the algorithm: the line to insert into the underlying structure! The line was
intact in the GinRummy source, but not in the tester file. After quickly fixing the error,
the results were more plausible and inline with the original hypothesis. The average time
for the traversal to the correct position and insertion of an item for of 25 trials of 50
shuffled decks of 52 cards with a STL vector was 6.641 seconds. The STL list faired
better, with a time of 4.492. myVector clocked at 3.787. myList ran with a time of 2.947.
This data fits the hypothesis and can be explained rationally by the definition of the list
and vector. It seems to be the case that myVector and myList also performed better than
their STL counterparts.
Even though the initial round of timings was in error, it did show another
interesting comparison about the data structures: time to traverse. On average, the STL
vector was the quickest structure to find a particular value, starting at the end. By
comparison, the STL list had the worst time. This result is easily explained by the
structure of the list vs that of the vector. Because a list is not random access and uses
pointers to link between data elements, the time to move from one pointer to the next in
the STL list should be greater than that of the vector, and that is indeed the case.
The best choice for the GinRummy game in terms of efficiency appears to be
myList. Given the multiple insertions throughout the game, myList performs the best
over time. While the difference is negligible at the size the hand operates, ever little bit
counts.

Vous aimerez peut-être aussi