The Usefulness Of A Partner
It's time for another status update about my Lines game. After my last post, I began rewriting the game to clean everything up. I feel much better about the way things are written now, but I have yet again run into a problem that further solidifies my belief that my biggest weakness in programming is finding the non-critical bugs, and I need someone that is good at that type of thing.
I believe I am almost finished with my new version of the game, but I am stuck trying to build an algorithm that checks for matching pieces. In my previous version of the game, I found a design online that I slightly modified and implemented into the game. Based on what I learned from that, I intended to create my own methods. Without directly looking at the previous code but remembering some of the ideas, I am creating an algorithm that is my own.
Based on what I have been seeing online, I am understanding the usefulness of creating a method once, and passing it different variables to perform different functions. I know that seems relatively obvious, but I shall explain. My friend, who has been working on the same project, wrote 4 separate methods to check for matching pieces in his code. I set out to create 1 method and, based on what I passed it, perform checks on all 4 different directions. I have the same method called 6 times (row, column, slant down moving right, slant down moving down, slant up moving right, slant up moving up) per iteration. This allows me to make changes in only 1 place; however, you end up with odd results if you do not plan accordingly.
After a bit of planning and a couple of rewrites, I believe I have an acceptable method of checking for matches, except that it doesn't work at all how it should. My code does not detect matches most of the time, and, when it does, it seems to choose every other piece in the matching row and a few other random pieces around the board. I cannot seem to find the source of my issue, but that leads me to the subject of this post: working with a partner.
While I appreciate everything my friend has been doing to help me, there is one major problem: he lives in Romania, and I live in U.S. While the wonders of modern technology allow us to easily communicate, the 8 hour time difference causes a problem. There is also a small bit of a language barrier, but it is not too much of an issue; I am good with puzzles and he understands English is not his first language. :-P He is also very busy with school, so there is barely any time for us to have conversations about what we are working on.
I have been attempting to get my cousin into Java programming, but he doesn't stick to most things very well. He and I are quite similar, and I think he would enjoy designing software once he gets into it.
Having another person provides many benefits over working by yourself:
You can bounce ideas off each other and brainstorm about projects.
You can work on the same project but work on it separately. The two versions could be compared to learn other approaches to the same tasks.
You can check each other's work. One may be strong with detail, while the other is strong at the overall structure issues.
You can play off of each other's strengths. One may be proficient at designing the general algorithm ideas, while the other may be proficient with the technical implementation of the algorithms.
The list goes on and on with the benefits of having someone else to work with. While the person you are collaborating with is important, you can usually benefit in some way even if they are not ideal.
To clear up my comments about my code, I am attaching 2 small portions of it. The first bit of code is the loop that calls the methods to check each row/column/diagonal.
//check for at least 5 pieces in a row public void checkMatch() { int cells = GUI.numCells; //only for readablity in below code matchMade = false; //reset match made for(int i = 0; i < cells; i++) { processRow(0, 1, i, 0); //check a row processRow(i, 0, 0, 1); //check a column processRow(0, 1, i, 1); //check a diagonal slant down, moving right if(i > 0) processRow(i, 1, 0, 1); //check a diagonal slant down, moving down processRow(0, 1, cells - i, -1); //check a diagonal slant up, moving right if(i > 0) processRow(0, 1, cells - i, -1); //check a diagonal slant up, moving up //the ones with if statements prevent checking diagonals twice } }
The other bit of code is the actual method that processes each row/column/diagonal.
//check an entire row/column/diagonal for matches private void processRow(int x, int xMod, int y, int yMod) { //FIXME checking rows does not work. odd results if a match is made int matchCount = 0; //number of matching cells in a row Color matchColor = null; //color to be matched for(int i = 0; i < GUI.numCells; i++) { int xi = x + xMod*i; int yi = y + yMod*i; if(xi >= 0 && xi < GUI.numCells && yi >= 0 && yi < GUI.numCells) { //ensure the indices are within the grid bounds if(piece(xi, yi) == null) { //reset if there is an empty cell matchCount = 0; matchColor = null; matchedPieces.clear(); } else { if(matchColor == null) { //the previous cell was empty, so initialize the color and list matchCount++; matchColor = piece(xi, yi).color; matchedPieces.add(piece(xi, yi)); } else if(piece(xi, yi).color.equals(matchColor)) { //the current piece matches the previous piece matchCount++; matchedPieces.add(piece(xi, yi)); } else { //the prevous cell was not empty, but the current piece does not match if(matchCount >= 5) { updateResults(matchCount, matchedPieces); matchMade = true; removePieces = true; } //reset matched piece count and the color matchCount = 1; matchColor = piece(xi, yi).color; //reset and initialize the matched pieces list matchedPieces.clear(); matchedPieces.add(piece(xi, yi)); } } } } }