2. Part: The LogicOk, here we go with Part 2. For now, forget everything you did in Part 1, you won't need it for this part. Well, some of the ideas you had in Part 1 might still be helpful. So, don't forget EVERYTHING. And no, I did not say that you should erase your source code of part 1...The goal of Part 2 is to implement the class Connect4Logic. This module has two main functions:
Keeping track of the state of the gameIn order to keep track of all discs that have been inserted already, we have to find an appropriate data model. In real life it is the standup board that helps us remember where the inserted discs end up. With this help our brain is then able to constantly scan for "winning sequences" of four equallycolored discs. However, the board is only a convenience. You can also play this game without a board, for example by drawing a chart on a piece of paper and then painting in colored circles (or just drawing circles and crosses, which is typically done when playing tictactoe). Taking this a step further, you could even play Connect Four without any utensils. You can just announce your column choice to your opponent and then you both remember the current disc setting. I'm pretty sure that this is the way how MENSA members play it: "Seven", "Three", "Six", "Oh man, I lose again?!"So, how should we represent the board in our logic module? We basically need a matrix with the appropriate number of rows and columns. This matrix could contain integer values which indicate whether a disc has been placed in a certain location and, if so, which player the disc belongs to. Having two players, the matrix entries would be 0 (no disc), 1 (disc of player 1) or 2 (disc of player 2). (What would be the values at the beginning of a game?) A very efficient data structure for representing a matrix in Java is a 2dimensional array. Such a 2dimensional array is very similar to our standard array, only that it offers two index dimensions. Following statement declares a 2dimensional integer array with name matrix: int [] [] matrix; The appropriate command to create the array would be: matrix = new int[row][col]; where row and col are integer values specifying the number of desired rows and columns of this matrix. In order to put for example a value 7 into the second row and third column you would use matrix[1][2] = 7; 1. Task If you haven't created class Connect4Logic, yet, it is now time to do so. After creating the class, we need to set up the disc matrix appropriately.
2. Task Now we need to add a method that let's us insert a disc into a column. This method determines the appropriate row and makes a note in the disc matrix. The header of this method should be exactly as follows: public void insertDisc(int column, int player) where column is the column (enumerated from left to right, starting with 1) in which the disc should be placed. Furthermore, player specifies one of two players (either 1 or 2). At this point, we don't care about disc colors. We are not concerned with the display at all! 3. Task Having created the insertDisc() method, we would like to test it out. However, we have one big problem here. Although we insert a few discs, we don't see anything! It's not like in Part 1 where we added a disc and had the confirmation (in form of a colored circle) right away on the screen. Now, it's only an entry in a matrix, which is stored somewhere deep down in a computer's memory. How can we visualize this matrix? Well, one way to do it is to use BlueJ's "Inspect" functionality. We can inspect the matrix and see its current setting. Do this! Create an object of type Connect4Logic and insert a few discs. Then, inspect the object and look for the matrix entries. Do you find the numbers in there? You should! But this is tedious, very tedious! Therefore, create a helper method public void printMatrix(), which prints the contents of the matrix to the terminal window. It should print the matrix contents row by row, with one row per line. This way we can nicely visualize the matrix contents whenever we want to check it. Later on, at the end of the project, we just declare this method as "private". This way it won't show up in the documentation and no one will be able to call it. For now, though, you want to leave it as "public" so you can call it from the BlueJ workbench. Determining the winnerAt this point you should be able to insert discs into the matrix, keep track of the discs, and visualize the matrix for testing purposes. This means your logic module is now able to keep track of the state of the game and the next step is to determine when we have a winner.This functionality can be implemented in many different ways. The steps that we outline below point out one possible solution. It's one approach that we think is easily understandable. However, we don't claim that it is the best way to implement this logic module, nor do we even know whether it's really so easily understandable. But this is what programming is often about. It's all about choices. Since there is typically no "right" way, you just have to make a decision and then follow through with it. At the end, you often find out that there might have been a better (faster, more efficient, more elegant, or whatever) way. Well, if you have enough time, you throw away your source code and do it again. This time, being more experienced and knowing better what the outcome should be. For now let us just try to create a working solution, without worrying too much about the elegance of the code. What we want to have at the end of this step is a method that determines whether a certain player has a winning sequence. Specifically, you should have a method like this: public boolean checkForWinner(int player) This method takes as a parameter the number of the player and returns true if this player has a winning sequence of discs. If not, it returns false. The following steps are only a suggestion. If you want to come up with your own solution, that's perfectly fine with me. As long as the checkForWinner() method is working! 4. Task The questions to ask here are, what is a "winning sequence" for a certain player and how can it be determined? While the first question is quite easy to answer, the second question appears to be rather tricky. We need an algorithm that can find any sequence of four discs with the same color inside our matrix. To make it easier, let's consider following different types of "winning sequences" and treat them independently:
Let's first only look at a horizontal sequence. To do this we can write a helper method, e.g., checkHorizontal(int p), which takes as a parameter the number of the player and returns whether this player has a horizontal winning sequence. Inside this method we could apply following search strategy:
Once you have the horizonal check working, write a method for the vertical sequence check. It is very similar! The same is true for both of the diagonal sequence checks. Write a method for each of them and always make sure that the four checks that you do in order to detect a sequence are in valid index ranges for the matrix array. Please, see me if you have problems with these methods. 5. Task After you have writting the individual check methods, it should be quite easy to finish up thecheckForWinner() method. All that this method now needs to do is call the individual check methods one after the other and return true if one of them returns true. If all the individual checks are false,checkForWinner() also returns false. Milestone for 2. PartYou should now have a working Connect4Logic class. You should be able to deal with boards of various sizes and you should be able to insert a disc into a certain column calling the appropriate method. The interface of your class Connect4Logic should look exactly like this. You can check this in BlueJ by selecting the "Interface" view from the drop down menu on the top right corner (by default it shows "Implementation").Note that the Interface Documentation doesn't show any helper methods that were written. In order to hide your helper methods, which are only used inside your class and should never be called by another object from outside the class, you can declare them as "private" instead of "public". Deliverables:
