In the Task1 folder there is a class Connect4Model.java. It is almost identical to the completed AbacusModel class. A couple of variable names have been changed, that's all:
- The variables with 'peg' in their name have been renamed to have column (col) in their name. While the Abacus can be drawn using either rows or columns, Connect4 uses 'columns' in a different way to 'rows', so it makes sense to reflect this in the naming of the variables.
- The array that stores the number of counters in each peg, has been renamed 'num_counters_array'. Again, the new name explains how this variable will be used in this class.
- There is no 'removeCounter() method, because this is not part of the game.
In this task, add four instance member variables to this class:
- a private integer variable called playerToGoNext
- two public static integer variables, called PLAYER_1 and PLAYER_2. As part of the declaration, assign PLAYER_1 to be 1 and PLAYER_2 to be 2.
- a two-dimensional array of integers called counters_array
A hint for how the two-dimensional array is below:
In the constructor of the Connect4Model class, set playerToGoNext to be equal to PLAYER_1.
Also in the constructor, construct the counters array to be num_of_cols by max_num_counters big. The hint for this is given below:
counters_array = new int[num_of_cols][max_num_counters]
All the extra variables required have now been added and initialised. The class should compile. Now copy over to Task 2.
In the Task2 folder, make the following two additions to the 'addCounter' method.
- if another counter can be added, set counters_array[x][y] = playerToGoNext, where
- x is the column that the user clicked in.
- y is the value of that element of num_counters_array, before 1 is added to it.
- also, if another counter can be added, swap over the value of playerToGoNext. (So if it was PLAYER_1, it is now PLAYER_2, and vice versa.)
Note that the set of conditions to determine whether "a counter can be added" has already been included at the beginning of the method.
Note also that the code to add one to an element of num_counters_array should be kept. This array is used to store the number of counters in each column, which turns out, usefully, to be the index of the element where the next counter should be added.
Copy over to the Task3 folder, and write two new methods for the Connect4Model class:
- The getNextPlayer() method does not take any parameters, and should simply return the (integer) value of playerToGoNext. One line of code. (Q: Why do we need such a simple method?
A: Because playerToGoNext is a 'private' member of this class.
Q: Why is playerToGoNext 'private'?
A: Because we don't want to allow any external classes to be able to change the value of this variable: that would interfere with the 'game logic'.)
- The getCounter(int thisCol, int thisRow)method should return the value in counters_array array, at the element indicated by thisCol and thisRow. There are three possible return values: PLAYER_1, PLAYER_2, and 0 (no counter in this grid element). Again, that is just one line of code. However, just as in the getNumCounters() method, you should check that the input parameter values are valid. If they are not valid, you should return -1.
Test your class by putting it into the YourSolutionHere folder inside the Task4 folder. Correct any problems revealed by the testing process.
In the Task5 folder there are the same AbacusFrame and AbacusPanel classes as provided in Workshop 3. Now do the following:
- Put your best version of your model class (Connect4Model.java) in the Task5 folder.
- In AbacusFrame.java and AbacusPanel.java, change all occurrences of AbacusFrame to Connect4Frame, and of AbacusPanel to Connect4Panel. Including the filenames. Take care to use the correct Capital and lower case letters in every instance.
- Just as you did in Workshop 3 (Task 6), add an instance variable to your Panel class, that will refer to an object of your (Connect4Model) model class. In the Panel constructor, make this a 'new' Connect4Model object, passing in the number of columns and rows you have in the Panel.
In the mouseClicked() method, use the addCounter() method on your Connect4Model object, passing in the correct column index. Also call repaint() as now your model has changed.
- In the paint method, paint the counters that are stored in the model. You will need two 'for' loops to do this: one inside the other, to cover all the rows and columms. There are a number of ways to organise the variables and the loops. At each element,the getCounter() method will return PLAYER_1, PLAYER_2, or zero. You can use these values to draw either a red counter, a yellow counter, or nothing.
Copy the java files from the Task5 folder into the Task6 folder.
After each player takes their turn, update the title of the application to say who's turn to go next (e.g. player 1/player2 or red/yellow). This isn't as easy as it might be, because the title is set in the Frame class, while all the other action takes place in the Panel class. This is one way to do it; there are other ways, too:
- In the Connect4Panel class, declare a member (instance) variable that will hold a reference to a Connect4Frame object. (Hint: you should already have a variable for a Connect4Model object, so it could be declared right after it. You could call it myFrame, or frame, or whatever you like.)
- Also in the Connect4Panel class, add a third parameter to its constructor: (int nc, int nr, Connect4Frame f). In the constructor, set your new member variable to be equal to f.
- In the Connect4Frame class, where the Constructor for the Connect4Panel is called, add "this" as the third parameter. (Now all your code should compile, but it won't do anything different yet.)
- Finally, in the mouseClicked() method of the Connect4Panel class, use the new member variable to access the setTitle() method, in the Connect4Frame class. Make and pass in a string that shows whose turn is next.
Copy the java files from the Task5 folder into the Task7 folder.(If you'd prefer to work with your Task6 solution, then you must follow the third point in the list below).
Here, the task is to create an applet version of the game, to be included in a web-page. This is surprisingly easy:
- Make a copy of the file Connect4Frame.java, and call it Connect4Applet.java. Inside it, rename Connect4Frame to Connect4Applet and JFrame to JApplet.
- In the constructor for the Connect4Applet, delete everything except for the last two lines of this method.
- If you are working with your solution to Task6, then in this constructor, use "null" instead of "this", when you construct the Panel class. In the mouseClicked() method of the Connect4Panel class, only make the call to the setTitle() method if the Connect4Frame object is not equal to null.
- You can run your Applet class though Textpad (usually CTRL+3), but you can also write some html to embed it in a webpage, as shown below.
<title> a simple applet wrapper </title>
<applet code="Connect4Applet.class" width="200" height="200"> </applet>
(You will need to put all your class files in the same folder as the html file. Alternatively, use the CODEBASE attribute to specify a different folder - this is handy when including more than one applet.)
(Complete this task in the Task8 folder). Allow each player to click anywhere in the board, rather than filling up each column from the bottom. Hint: delete num_counters_array from your code, it's not useful in this case.
(Complete this task in the Task9 folder). In the Connect4Model class, modify the getNextPlayer() method to return -1 if player 1 has won (has 4 in a row), and -2 if player 2 has won. Use these return values elsewhere in your program to indicate to the players if and when either of them has won!
A++ Solution for workshop 4