Programming Project Two
CS 130 - Rieck - Fall 2005
Due date: Monday, November 21
(Programming Projects are to be treated as "take home exams". See the policy statement
in the syllabus. You may not work with other students except perhaps to discuss the project
at the conceptual level. You may get help from me though at any level. )
Submitting and grading
    You will write a MASM assembly language program that will work as described below, or
come as close as you are able to get in the limited time. This can be 16-bit or 32-bit, but
I highly recommend 16-bit, so that you will be able to use CodeView to debug.
I think it will be worth this effort so that you can watch what happens
to your (array of) data as it is being processed. the stack by keeping
an eye on the stack pointer and the stack segment portion of memory.
Give your .asm file the name ...ProjectTwo.asm, but
replace ... with your last name. Submit a printout of your
final program (hardcopy). Also, e-mail me your .asm file as
an attachment.
    Here is a sense of how I plan to grade. In the first
instance, I will focus on how much of the assignment objectives you are
able to implement, and whether or not you pay attention to the details
as discussed below. To a lesser extent, I will consider how elegantly
and efficiently you are able to implement the assignment, and how well
you comment your code.
Outline of the program objectives
Basically, using Masm, you will implement a solution to a problem from
the 2005 ACM North Central North American Regional Programming Contest,
specifically "Problem 5: Blackjack Prognostication." First I will list
the exact statement of the problem from the contest. Then I will explain
some small changes I would like to make to the assignment.
The original problem
The game of Blackjack (as defined here) is played with a deck containing
no more than 500 cards, on each of which is printed an integer in the
range 1 to 10. In each game there are two players: you and the house. At
the beginning of each game the first card is dealt to you, the next is
dealt to the house, the next one to you, and finally another is dealt to
the house.
The goal of the game is to obtain a set of cards with a total larger
than your opponent's total, without exceeding 21. A card containing the
integer "1" can be counted for either 1 or 11, as desired by the player.
This rule applies to you and to the house. After the first four cards
are dealt, you may draw as many additional cards from the deck as you
wish, but you must stop if your total exceeds 21. Then the house is
required to draw cards from the deck until its total is 17 or larger
(counting a 1 as 11, if possible, without exceeding 21).
When both you and the house have finished taking cards, the totals of
the cards you each hold are compared to determine the outcome. If Y is
your total and H is the house's total, here are the six possible
outcomes:
- Y <= 21, H <= 21 and Y > H, which means you win;
- Y <= 21, H <= 21 and Y < H, which means the house wins;
- Y <= 21, H <= 21 and Y = H, which means a tie;
- Y <= 21 and H > 21, which means you win;
- Y > 21 and H <= 21, which means the house wins;
- Y > 21 and H > 21, which means a tie.
In this problem you are told the number and order of the cards in the
deck, and are to determine the manner in which you should play (that is,
how many cards you should draw in each game) in order to obtain the most
favorable outcome (for you). A win is better than a tie, and a tie is
better than a loss. Play as many games as possible. If necessary, reuse
the deck (in exactly the same order as originally input) from its
beginning to complete the last game. Figure out how to draw the smallest
number of cards required to yield the best possible outcome for each
game (for you).
Let's consider an example. Suppose the deck contains the cards 1, 2, 3,
4, 5, 6, 7, 8, 9 and 10, in that order. At the beginning of the first
game you would have 1 and 3 (a total of 14, counting the 1 as 11) and
the house would have 2 and 4. If you choose to draw no more cards, the
house then would draw 5 and 6, yielding a total of 17, and the house
would win. If you had taken one more card, you'd then have 1, 3 and 5 (a
total of 19, again counting 1 as 11); the house would then draw 6 and 7,
yielding a total of 19 - a tie. If you took 2 additional cards, you'd
have 1, 3, 5 and 6 (a total of 15, counting 1 as 1), and the house would
draw 7 and 8 for a total of 21 - you would lose. Finally, if you try
taking 3 additional cards, you would have 1, 3, 5, 6 and 7, for a total
of 22. The house would draw 8 and 9, for a total of 23. This would be a
tie, since both you and the house exceeded 21. The first tie (with total
of 19) requires the smallest number of cards to yield the best possible
outcome, so you should draw only one additional card in this game.
Since the deck has not yet been exhausted, we can play another game. The
first card not used in the previous game is 8, so you are dealt 8 and
10. The house is dealt 9 and 1 (since we start reusing the deck to
complete the game). You have 18, and the house has 20 (counting 1 as
11), so the house would win if you opt not to take any more cards. If
you take an additional card, you'd have 8, 10 and 2, giving a total of
20. The house has a total of 20, so this would be a tie. If you take two
additional cards, you'd have 8, 10, 2 and 3, for a total of 23. The
house, with 20, would still win. The best outcome for you is a tie.
Since the deck has been completely used, no more games should be played;
the best overall outcome (for you) is 0 wins, 2 ties and 0 losses.
Input. The input will contain multiple cases. Each case consists
of an integer N (1 <= N <= 500) than specifies the number of cards in
the deck, followed by the deck - N additional integers, each in the
range 1 to 10. Input for the last case (deck) will be followed with the
integer 0.
Output. For each case, first display the case number (they start
with 1 and increment sequentially). Then display the number of games you
won, the number of ties, and the number of games you lost, with
appropriate labes for the values.
Sample Input.
10 1 2 3 4 5 6 7 8 9 10 13 8 4 9 1 4 9 2 10 7 3 1 4 4 20 4 6 3 7 10 1 5
5 6 10 1 8 4 4 10 9 2 2 1 5 0
Sample Output.
Case 1: wins=0, losses=0, ties=2
Case 2: wins=1, losses=0, ties=1
Case 3: wins=3, losses=1, ties=0
My extra requirements
- Write a procedure whose only duty is to prompt the user for input
(once) and then get the input for an entire array of (double) words,
that is terminated by value zero. Don't ask the user how many numbers
will be entered. Just keep taking integer input from the user until the
user enters the value zero.
- Write a procedure that tests to see whether or not the user gave
proper input (as in the above example). Remember that there can be
multiple decks (for "multiple cases"), but each deck should contain no
more than 500 cards. Let's also assume that each deck is required to
contain at least 4 cards. Each deck is specified by first indicating how
many cards in the deck, followed by a list of card values (each being 1
to 10).
- Write a prodecure for displaying to output for one case (as in the
above example).
- Strive to modularize your program in other ways, by creating
procedures to do various tasks. Have your procedures protect registers
that are not used to return information to the place where the
procedure is invoked. Don't forget that you are not allowed to
use USES, PUSHA, PUSHAD, .... (see directions from
Project One). Put header comments at the start of each procedure to
explain what the procedure if for, what info is passed into it, and how,
and what info is returned by it, and how.