2 problems, 20 points for #1 and 30 points for #2
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.
(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:
Board object of the requested size (using the
constructor from the Board class).
Your Board class should have the following data members:
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:
public void addMove(int c, char player) should add the
player's checker into the next appropriate row of column
c (this function will need to scan the column to find the next
available empty row).public boolean allowsMove(int c) should
return true if the calling Board object can allow a
move into column c (because there is space available and
public boolean isFull() should return true if the calling Board
is completely full (i.e. there are no spaces left for additional moves);
otherwise, it should return false.public boolean winsFor(char player) should return
true if the calling Board is a winner for the
character player. It should return false
otherwise. You should assume that player will be an 'X' or an 'O'
(and only invoke this method with such argument values). A win can occur
horizontally, vertically, or diagonally, and there are two directions for a
diagonal win: from NW to SE and from NE to SW. Correct code must accommodate
all of these cases. Note: a few students have asked if they could
redesign this function's signature, adding an additional int
argument corresponding to the player's most recent move. Feel free to make such
improvements if they seem natural to you!
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
Be sure to submit your CS5App.java file under homework 10,
problem 1.
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:
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.)
CS5App classmain method inside the CS5App
should do the following:
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.
(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
We provide you with a working constructor for the Date class:
public Date(int m, int d, int y)
takes three input arguments: the month m, the
day d, and the year y, and initializes the data
members of the object that is being created.We also provide you with several working method members for the Date class:
public void print() prints out the Date
object that calls it in the following familiar (month/day/year) format:
11/14/2001
public boolean isLeapYear() returns true when the
Date object that is calling this function has a year that
is a leap year.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.
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
Be sure to submit your CS5App.java file under homework 10,
problem 2.