The example used throughout this course is the Narcotic solitaire variation (also known as Fours and Perpetual Motion):
Here is its description in words:
"Perpetual Motion is a good title for a game that is apt to go on for ever, but the older name better describes its stupefying effect.
Deal four cards face up in a row. If two or more are of the same rank, put duplicates on the leftmost of them. Then deal four more across, pause, and do the same. Keep going until you run out of cards. Gather the piles from right to left, turn the whole pile upside down and start again. Whenever the four cards you deal are of the same rank, eliminate them. Win if you eventually succeed in eliminating all fifty-two. This may take years."
This solitaire variation has the essential addictive quality that we like so much in our games. Think of:
But let's not brag or digress.
A model is an abstraction of a system. A system is an organized set of communicating parts. For this assignment, your system is a solitaire variation and the parts are the elements of the game -- the deck, stacks of cards, waste piles and other elements. Modeling means constructing an abstraction of a system that focuses on "interesting aspects" and ignores details that are either irrelevant or can be decided later. Given the above variation, how should it be modeled? We can't rely on English to properly capture the subtle nuances in a clear and concise way so we need to have modeling languages that are clear, precise and unambiguous. Throughout this course, we use the Unified Modeling Language (UML) and it is a safe bet that you will use this same language in your career (until something even more powerful comes along, that is!)
While UML is quite powerful, we will focus on the following subset of its capabilities:
Use cases describe the behavior of the system as seen from the point of view of an actor manipulating the system. In this case, the system is a solitaire variation and the (only) actor is the player. The use case captures the external behavior of the system without wasting time worrying about how the behavior is to be implemented. As such, the use case is one of the most powerful abstractions developed for software engineers and you must not consider it to be trivial. In this section, we define the use cases for the Narcotic variation. Note how each use case is named and abides by a structured template which you can find in Section 2.4.1 of the textbook.
In all of these examples, the participating actor is the same (i.e., the player) so that part is omitted from the use case descriptions. The full set of use cases for the game include the following:
Use case Name: | Initialize Game |
Flow of Events: |
|
Entry Condition: | Game has not yet started |
Exit Condition: | Game is ready to play |
Quality Requirements: | none |
Use case Name: | Move card to pile on left with same rank |
Flow of Events: |
|
Entry Condition: | At least two face up cards have the same rank |
Exit Condition: | The size of the source pile has decreased by one while the size of the target pile has increased by one |
Quality Requirements: | While the card is moving there should be no "flicker" and during the movement the card should be removed from the source pile and appear "floating" above the game until it is placed on the target pile. If invalid move had been made, the card should "zip" back to appear in the source pile where it had originated from |
Use case Name: | Deal four cards |
Flow of Events: |
|
Entry Condition: | All visible cards have different ranks and the deck is not empty |
Exit Condition: | Deck is reduced by four cards |
Quality Requirements: | The four cards should simply 'appear' in their proper places in the pile; no need to animate the "dealing" of the cards. |
Use case Name: | Re-assemble Deck |
Flow of Events: |
|
Entry Condition: | The deck is empty, cards remain in the piles |
Exit Condition: | Piles are empty and deck is ready to be used again |
Quality Requirements: | The player may choose to reassemble the final piles into a deck even though more than one card with the same rank may be visible. No animation should occur and the piles should be cleared on the screen and the deck reappear in its place |
Use case Name: | Remove four cards |
Flow of Events: |
|
Entry Condition: | Four cards have just been dealt and they are of the same rank |
Exit Condition: | The cards are removed from the game |
Quality Requirements: | none |
Use case Name: | Complete Game |
Flow of Events: |
|
Entry Condition: | The four final cards in the deck have just been dealt, one to each pile, and they have the same rank |
Exit Condition: | Game is complete |
Quality Requirements: | none |
Once you have a working set of use cases (don't wait until they are perfect -- consider the benefits of iteration) your task is to develop an initial analysis class model. The goal of analysis is not to implement the system; rather it is to capture all important relationships that are evidently present given the use cases, and some relationships that can only be understood once the concepts are being modeled.
Given the use cases above, look at the nouns for a starting point:
What is a playing card? It has a suit (clubs, diamonds, hearts, spades) and a rank (Ace, 2 .. 10, Jack, Queen, King). Note that we might have considered 'rank' to be a separate concept, but it is rather a concept associated with a Card.
There are two common aspects of modeling -- data modeling and functional modeling. Once we know the structure of a card, we consider things one can do to a card during a solitaire variation (and also remind ourselves of things that cannot be done):
Things that can be done | Things that cannot be done |
|
|
In contemplating the above actions we have discovered something else that a card must know -- whether it is face up or not. Note that we don't include in the above list "get top card from deck" because that is an action to be performed on a deck not on an individual card.
At this point one would normally turn to a blank piece of paper and begin to develop a set of classes to be used to represent the solitaire variation. In this course, however, the goal is to integrate your solitaire variation into an existing program. To make this work, therefore, you will need to become familiar with a set of classes that are already prepared for you. The following diagram (extracted Feb-16-2008) is from the Kombat Solitaire classes modeled using the freely available Star UML. The document (should it be revised) may be found at this link as the analysis model diagram "Model":
As diagrams go, the above diagram contains much information that can only be understood in the context of the actual classes, which you must become familiar with. You can find these classes within the ks.common.model package. Here are the high points:
There is one last point. Since you are to implement a Solitaire variation, you will take advantage of the concept of inheritance by defining your variation to be a subclass of Solitaire. The following diagram (extracted Mar-17-2008) is from the Kombat Solitaire classes modeled using the freely available Star UML. The document (should it be revised) may be found at this link as the analysis model diagram "Solitaire":
Thus you must provide a subclass that overrides the following three methods: (a) getName() which returns the name of your variation; (b) initialize() which properly initializes all entities and visual layout of your variation to prepare it to be played; and (c) hasWon() which determines whether the game has been won, based on the entities that you have created.
In lecture and in the book you have seen the concepts of entities, boundaries, and controllers. These concepts are the fundamental building blocks towards any object-oriented design, and thus object-oriented application. We follow an object-oriented process that starts by identifying use cases which are then mapped into a set of class concepts to support the use cases. Along the way try to see how each use case can map directly to a controller which contains the logic that makes the use case happen.
See specific format for the example.
The interaction diagram will describe the objects that exist in the system and the ways in which they interact. As we will discover, a common means of dividing responsibilities among the different objects is to classify them into (a) entity objects; (b) boundary objects; and (c) controller objects.
Please review the example "StandAlone" project to see the ways that a system can be designed by separating the objects into these three categories.
In this problem, the challenge is to understand which objects are required. We first start with the model formed from a set of entity objects.
TBA
TBA