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:


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

  1. 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.

  2. 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).

  3. Write a prodecure for displaying to output for one case (as in the above example).

  4. 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.