Homework 10



Assignment: Two problems, 20 points for #1 and 30 points for #2 (the EC this week is to extend problem #1 to include graphics). Reading: Your CS5 lecture notes and the online readings for week 10.

2 problems, 20 points for #1 and 30 points for #2


Problem 1     Connect Four     [topics: practice with Classes and Objects]

Connect four is a variation of tic-tac-toe played on a rectangular board:

Connect four is played by two players, alternating turns, with each trying to place four checkers in a row vertically, horizontally, or diagonally. One constraint in the game is that because the board stands vertically, the checkers can not be placed in any position. A checker may only be placed on top of another checker that is already sitting in a column, or it may be placed in the bottom row of an an empty column. Moreover, a checker can't be placed in a column that is full. You're task is to create a Board class that implements the necessary features for playing the connect four game. You'll also implement the CS5App class, whose static main function presents the board to two human users and allows them to play connect four with it.

The CS5App class

(Unless you do the extra credit) main is the only member in class CS5App. Your two players will be represented by characters -- the player that goes first should be assigned the value 'X' (a capital X); the other player will be 'O' (a capital O). main should do the following:

  1. Welcome the user(s) to your Connect Four program.
  2. Enter the height and width of the board the user would like to use. You should make sure the height and width are each greater than or equal to 4 and each less than or equal to 15.
  3. Create a Board object of the requested size (using the constructor from the Board class).
  4. Enter a loop that alternates between the players' turns, which involves:

The Board Class

Your Board class should have the following data members:

Recall from class that, because these data members are not modified via the static keyword, they are instance members, meaning that each Board object that is created gets its own personal set of these. (Although in this problem you'll only create one Board object in main, one could imagine this aspect of the Board class's design being useful, especially if one wanted to extend this problem so that multiple games could be played at the same time.) These members are also private, which means that only code in the Board class can access and/or modify this data directly. In general, this type of data protection is a good idea in software design, providing guarantees that other types of objects can't go in and cause havok with data associated with this class's objects. Moreover, such isolation encourages us to abstract away a class's implementation details, instead focusing on the capabilities and properties that the class provides.

We provide you with a working constructor for the Board class:

We also provide you with several working method members for the Board class, as enumerated below. But first, recall that public methods are available for use anywhere. Moreover, since none of these functions are static, to call them, you must invoke them through particular calling objects (using the dot operator). For example, suppose we had a Board object stored in variable b. To invoke the print function for this object, b.print(); would do the trick.

  • public void print() displays a Board object's content (via data) to the console. Here is an example for a 6-row, 7-column Board:
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | |O| |O| | |
    | |X|X|X|O| | |
    ---------------
     0 1 2 3 4 5 6
    
    Each checker corresponds to either player 'X' or 'O', and each column is separated by vertical bars, e.g. '|'. The columns are labeled at the bottom, making it easy for a player to enter their next move. When numbers reach double digits, only the final digit is printed, as shown in the following 15-row, 6-column example:
    | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | |
    -------------------------------
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
    
    Nonetheless, when a player enters a column for their next move, they need to enter the column's entire number. It is important to realize that the uppermost row that print displays refers to data row 0. This decision will impact the code that you write.
  • You should provide (at least) the following additional method members to the Board class:

    Sample Run

    To make things more concrete and help you test your code, here's a sample run (user input is displayed in blue). Test your code carefully before submitting it!
    Welcome to Connect Four!
    
    Please enter the number of rows and columns you would 
    like the game board to have (between 4 and 15 inclusive):  6 6
    
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    -------------
     0 1 2 3 4 5
    
    X's choice:  3
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | |X| | |
    -------------
     0 1 2 3 4 5
    
    O's choice:  4
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | |X|O| |
    -------------
     0 1 2 3 4 5
    
    X's choice:  2
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | |X|X|O| |
    -------------
     0 1 2 3 4 5
    
    O's choice:  4
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | |O| |
    | | |X|X|O| |
    -------------
     0 1 2 3 4 5
    
    X's choice:  1
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | |O| |
    | |X|X|X|O| |
    -------------
     0 1 2 3 4 5
    
    O's choice:  2
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | |O| |O| |
    | |X|X|X|O| |
    -------------
     0 1 2 3 4 5
    
    X's choice:  0
    
    
    X wins -- Congratulations!
    
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | | | | | |
    | | |O| |O| |
    |X|X|X|X|O| |
    -------------
     0 1 2 3 4 5
    

    Submission

    Be sure to submit your CS5App.java file under homework 10, problem 1.

    Extra Credit

    For extra credit this week, you may augment problem 1 so that the user can input a checker by clicking anywhere in the appropriate column with the mouse. Also, consider adding an animation that shows the "checker drop," as well as the "clear the board" effect that makes the physical game as appealing as it is. Any other additions or capabilities are also welcome. If you do this extra credit, do not submit it in place of Hw10Pr1---instead, complete the regular connect-four problem and submit it, then work on this problem. Be sure to start from the third zip file, Hw10ExCr.zip, which has a hook so that you can access mouse information from the CS5App class.

    The Hw10ExCr.zip code has an extra method named handleMousePressed in CS5App. It is called whenever the mouse button is pressed, and it prints the row and column coordinates of the mouse location (note that they are doubles). Here is one way you might approach this:

    There are a couple of other things to worry about, but that's why it's extra credit after all---Good luck!


    Problem 2     Virtual Art!     [topics: Writing a class and using objects]

    Problem 2 is this homework's Pair Programming problem and should be worked on in groups of two as described at http://www.cs.hmc.edu/cs5/pair_programming.html.

    For this problem, you'll be implementing a virtual version of Professor Art Benjamin ala HMC's Math Department fame---at least in a calendar-computing sense! (Among Prof. Benjamin's many talents is the ability to compute in his head facts about the calendar---ask him what day of the week you were born some time---in fact, you might ask him about some dates in order to obtain good test cases in which to test your program!). As with Problem 1, most of your work here will involve creating the Date class (outlined below) and creating the main method that resides inside of CS5App. (main will use the Date class extensively.)

    The CS5App class

    Your main method inside the CS5App should do the following:
    1. Welcome the user to your date-analysis program.
    2. Enter a month, day, and year of a date the user is interested in. Create an object of the Date class representing that date. You may assume here and throughout that the user will input a valid date and that the first day of every month is one.
    3. Enter a loop that always:

    The Date Class

    Your Date class should contain the following data members:

    We provide you with a working constructor for the Date class:

    We also provide you with several working method members for the Date class:

    You should provide (at least) the following additional method members to the Date class:

  • public void yesterday() should change the calling Date object by moving it one day back in time. It should not prompt the user or print out anything (that will be done elsewhere). It should, however, take leap years into account.

  • public void tomorrow() should change the Date object that called it by moving it one day forward in time. It should not prompt the user or print out anything (that will be done elsewhere). Again, it should take leap years into account.

  • public boolean isBefore(Date d) should return true if the calling Date is earlier in time than the input argument d; it returns false otherwise.

  • public boolean isAfter(Date d) should return true if the calling Date is later in time than the input argument d; it returns false otherwise.

  • public int diff(Date d, boolean b) should return the number of days between the Date object that calls the method and the Date object d that is passed as the input argument. If d is later than the calling object, the result should be positive, and if d is earlier than the calling object, the result should be negative. You should write this function by relying on some (or all) of the four preceding methods. Moreover, if b is true, all intermediate days that are calculated along the way (which correspond to the calculations needed to get this closer and closer to d) should be displayed at the console. You can then invoke diff with this flag setting in order to help you debug your code (i.e. service option 5 in main). Final note: be careful to ensure calling diff doesn't change the calling object's state.

  • public String dayOfWeek() should return a String that indicates the day of the week of the Date object that calls it. That is, this method returns one of the following Strings: "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", or "Sunday". This method should work by creating a new Date whose day of the week you already know. Then, it should call diff (with the boolean flag set to false) and take the result modulo 7 (% 7) to obtain the day of the week in question. Final note: be careful to ensure calling dayOfWeek doesn't change the calling object's state.
  • Sample Run

    Here is an example run. Notice that the date is always printed out before the menu -- as a result, you don't have to print out the date an additional time after choosing options 1, 2, or 3. (Yes, this makes option #1 quite easy to implement!)

    To save space, the menu has been replaced by <Menu Here> after the first couple of times:

    Welcome to the date calculator...
    
    Enter a date you're interested in.
      Enter a month (1-12): 10
      Enter a legal day (of that month): 28
      Enter a year: 1929
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  10/28/1929
    
    
    (0) Enter a new date of interest
    (1) Print the current date of interest
    (2) Move one day forward in time
    (3) Move one day backward in time
    (4) Day difference finder
    (5) Day difference finder (with debugging)
    (6) Find the day of the week
    
    (9) Quit
    
       Your choice:  1
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  10/28/1929
    
    <Menu Here>
    
       Your choice:  2
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  10/29/1929
    
    <Menu Here>
    
       Your choice:  3
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  10/28/1929
    
    <Menu Here>
    
       Your choice:  5
    
    Enter another valid date:
      Enter a month (1-12): 11
      Enter a legal day (of that month): 1
      Enter a year: 2004
    
    10/31/2004
    10/30/2004
    10/29/2004
    ... lots of dates omitted ...
    10/30/1929
    10/29/1929
    
    Between 10/28/1929 and 11/1/2004 there are  27398  days.
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  10/28/1929
    
    <Menu Here>
    
       Your choice:  6
    
    The date 10/28/1929 is a Monday.
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  10/28/1929
    
    <Menu Here>
    
       Your choice:  0
    
    Enter a new date of interest:
      Enter a month (1-12): 7
      Enter a legal day (of that month): 4
      Enter a year: 2076
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  7/4/2076
    
    <Menu Here>
    
       Your choice:  6
    
    The date 7/4/2076 is a Saturday.
     
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  7/4/2076
    
    <Menu Here>
    
       Your choice:  5
    
    Enter another valid date:
      Enter a month (1-12): 11
      Enter a legal day (of that month): 1
      Enter a year: 2004
    
    11/2/2004
    11/3/2004
    ... lots of dates omitted ...
    7/3/2076
    7/4/2076
    
    Between 7/4/2076 and 11/1/2004 there are -26178 days.
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  7/4/2076
    
    <Menu Here>
    
       Your choice:  4
    
    Enter another valid date:
      Enter a month (1-12): 11
      Enter a legal day (of that month): 1
      Enter a year: 2004
    
    Between 7/4/2076 and 11/1/2004 there are -26178 days.
    
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    
    The date under consideration is  7/4/2076
    
    <Menu Here>
    
       Your choice: 9
    

    Submission

    Be sure to submit your CS5App.java file under homework 10, problem 2.