Begin Coding

Since I got my design check back, I decided to start coding. This is going to be my ongoing diary of the programming.


Day 1

The first thing I did was create the game class so that it can ask questions and keep the answers. Here are my attempts at it:

The Mine class (effectively main)

Version 1 of Game Controller
I got the following errors when I tried to compile it:
	
GameController.java:76: '}' expected.
}
 ^
GameController.java:24: Return required at end of boolean askLevel().
  public boolean askLevel(){
                 ^

When I went to line 76, I realized that I must be missing some ;. When I looked, I realized that I never put a ; at the end of createGame.

When I went to line 24, I realized that I only had a return if the level did not equal zero. I added an else and it was cool. I compiled again with the updated Version 2 of Game Controller.

End of Day 1 (Version 3) of Game Controller
I am not certain that the code I created is at all pretty. I am using booleans to explain if something worked well or not. There seems to be quite a bit of if/else when not necessary. Also, I am having to use integers to ask the user what she wants. I also realized that if I give more input than I expect, the program does funky things. Also, if I give different input than it expects, it acts odd. I think that I need to wait before I address those concerns.

Also, I am starting to wonder about my design. I don't think that I addressed a couple of key points. In particular, I never addressed how the user would deal with I/O of the program and I am making it up on the fly. I don't know if that is such a good idea.


Day 2

I decided that it is time to start working on Squares. Although my design was passed by the TAs, I realized that I am not quite certain the best way to go about doing the squares versus the mines. I realized that although I signified them as separate classes in my design, it made the most sense to combine them in some fashion. Heck, all of the methods I described were identicle. So, I remembered some of my knowledge from Street and decided to make a Square class and two subclasses- MineSquare and NumberSquare. The differences in the two classes are that they redefine uncover differently. MineSquare ends the game while NumberSquare just uncovers and moves on. (Although there might be some difficulty with the uncover methods of a zero number square cause it uncovers all of its neighbors.)

I also found out that there is a method in ReadInput.java that clears the rest of the line so I will use that! While I was fixing that, I added a few elements of clarity to my questions.

Version 4 of GameController

I wrote quite a bit of code to address the first problem presented and here they are to look at:
Square and Subclasses
Grid
Version 5 of GameController

When I try compiling them, everything is fine. When I try running them, I am not so lucky... I get the following message in runtime:
java.lang.ArrayIndexOutOfBoundsException: 95
        at Grid.createGrid(Compiled Code)
        at GameController.createGame(Compiled Code)
        at GameController.startGame(Compiled Code)
        at mine.main(Compiled Code)
Ugg! I know that is not a particularaly good thing so I start trying to find the error. First, since I know that the error started in my Grid class, I go there (to the createGrid method). I look at my code and I have no idea what could possibly be wrong so I start putting in printlns hoping that it will give me a better sense. [The printlined version is available here] When I run this version, I find the following output:
Started into Grid:createGrid
Entering first for loop in Grid:createGrid
first for loop, Grid:createGrid; number: 0
java.lang.ArrayIndexOutOfBoundsException: 23
        at Grid.createGrid(Compiled Code)
        at GameController.createGame(Compiled Code)
        at GameController.startGame(Compiled Code)
        at mine.main(Compiled Code)
With this knowledge, I know that the crash happened sometime between this block of code:
      randomX = (int) (randomizer.nextDouble() * 100);
      randomY = (int) (randomizer.nextDouble() * 100);
D'oh! I am multiplying by 100 to get my randomX and Y (based on my test code) where there is no 100 x or y. I need to change that! So, tail between legs, I do.

With that fix, I run the program again to see my printout and I find that all I print is a new line for every "x" so I know that somewhere my print algorithm is wrong. I check the Square class and it is ok. Then I realize that I used println instead of print in my Grid class' printGrid method. I fix that.

With the next run, I notice that it just does not look right at all! I go back to my printGrid method and realize that I am not printing a new line for the end of every row. All is well!

With that in mind, I realize that it is time for bed. So, here is my final Day 2 version of all this code:
All of the classes in one file


Day 3

My goal today is to be able to change the node style (ie: uncover/flag) and repeat the process

I decided that the startFlow method should really be a programFlow method and that on each round, assuming that the game is not over, it should ask individualOptions. I also decided that I would just keep a private setable flag in the controller to indicate that the game is not over. I also decided that each command line should have a quit option so I added that as 0.

Although I thought that I was being smart by asking the positions generally, I decided that there are so many times whan I don't want them that I am not going to by default ask for them...

Hehe! I got repetitiveness working. Now it is time to work for the actual uncovering...

Without the looping or actual numbers, I have uncover working. I realized though that I can uncover an element that is flagged.. that is bad. I also have no unflag.

With this status, I am tired and ready to go home. All of my classes are available here


Day 4

Now it is time to add the numbers to the mines. I am going to do this when I create the all the squares.

I noticed that I did not know how to turn a number into a string but then I remember that when I want to print a number out, all I have to do is "" + the number so I did that there too.

When I tried to run the program, I got the kind message:
java.lang.ArrayIndexOutOfBoundsException: -1
        at Grid.getNeighbors(Compiled Code)
        at Grid.createGrid(Compiled Code)
        at GameController.createGame(Compiled Code)
        at GameController.startGame(Compiled Code)
        at mine.main(Compiled Code)
I took a look at my code and noticed that I was currently doing this:
  public int getNeighbors(int x, int y){
    int returnValue = 0;
    for (int iy=(y-1); iy<(y+1); iy++){
      for (int ix=(x-1); ix<(x+1); ix++){
	if (!(ix<0 || iy<0 || ix>width_ || iy>height_)){
	  // Do nothing
	}
	else if(grid_[ix][iy] == null){
	  // Do nothing
	}
	else if(grid_[ix][iy].amMine()){
	  returnValue++;
	}
      }
    }    
    return returnValue;
  }
I added printlines to try to figure out where it was crashing. D'oh! I realized that while I meant to only add things that were not, I negated the first grouping which I should not have done. When I fixed that, the problem was solved!

The next issue I am going to deal with is printing out all of my neighbors when I uncover a "0" mine. So, I added that to my uncoverSquare method in the NumberSquare. I realized that I have no way of accessing the grid via a number node. I decided that I need to pass that information into the number squares. I also realized that I needed to know what number position I was so I also need to pass that to my NumberSquare. When I tried running it, I ran into an infinite loop of errors. I realized that my Grid method:
  public void uncoverNeighbors(int x, int y){
    for (int iy=(y-1); iy<(y+1); iy++){
      for (int ix=(x-1); ix<(x+1); ix++){
	if (ix<0 || iy<0 || ix>width_ || iy>height_){
	  // Do nothing
	}
	else {
	  grid_[ix][iy].uncoverSquare();
	}
      }
    }
  }
ends up calling uncover on the same node that called it. So, I fixed that by checking to see if we are the node passed in.

This time, when I ran the program, something odd happened:
uncovering 4, 4

 x x x x x x x x
 x x x x x x x x
 x x 1 x x x x x
 x x x 0 x x x x
 x x x x 0 x x x
 x x x x x x x x
 x x x x x x x x
 x x x x x x x x
Somehow, it did not uncover all the nodes that were neighbors. Again, I checked with the Grid method. Given one run, I end up uncovering myself three times! D'oh! This:
	else if(ix==x || iy==y){
	  System.out.println("Can't uncover self");
	  // Do nothing
	}
Instead of not uncovering myself, it does not uncover most of the nodes! I changed it to an and. Another infinite loop! Arg. This time, it is because I uncover squares that have already been uncovered. So, I need to check to see if it is uncovered before I uncover it. This got rid of the infinite loop but it did not solve my problem completely. I still have nodes that do not uncover all of the neighbors. In fact, there must be a problem with my getNeighbors method because I get the following setup:
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 x x x
 0 0 0 0 0 1 1 x
 0 0 0 0 0 0 B 2
While I was trying to fix this problem, I realized that I am not making all the mines that I want to make because some mines are created on top of others. I fixed my createGrid method to affect this. Arg. I realized that, having always assumed that I should only go to the number that is less than the number I want, I missed out on the fact that I actually wanted that number as well. Now, it goes less than or equal to. Unfortunately, doing that created an ArrayIndexOutOfBoundsException because, again, I messed up my greater than signs. This time, I don't want just greater than the width_, I actually want greater than the width_-1 since we only go to width_-1. Voila! Uncovering all the appropriate nodes works!

I think that almost all of the functionality is there. I am going to go back to it tomorrow but I believe that it is almost entirely functioning! Yipee!!!

Ok, I lied. I don't have clearing working. I don't recognize when I win. But, all and all, it looks pretty good!

Today's version of the code is available here