Code pass 1

[Here is all the code I wrote. My methodology is listed below.] So, first I'll create the Constants interface.

Okay, now I'll work on Square. So, uncover(), check(), and flag() will all be abstract, and I'll redefine those in the subclass, since a Mine and an EmptySquare will react in different ways. I'll be able to define the React method though. That will just delegate to the appropiate Mode. Which means the Square will need a reference the ModeHolder. So how will it get created? Hmmm, the Square shouldn't instantiate it itself. I guess it will have to be passed in.

So, I'll add that to the constructor. So what is creating the ModeHolder? I guess it would make the most sense to have the Game create it. So I'll make it contained by the Game.

[updated to new OMT design]

Okay, Square is looking all set. I'll create the two subclasses now. The Mine subclass won't do anything more. For now though, I'll have the overridden methods just print out that they were called, for debugging purposes.

When writing the EmptySquare subclass, I ran into a problem. How will the number of neighbors be specified? I'll just pass it in as a parameter to the constructor, and hopefully that will work okay.

How about the ModeHolder and UserMode now? They seem pretty straightforward. One thing I'll do for robustness's sake is to check to see if the Square passed in is null before calling any methods on it. I'll print out an error message if that is the case.

Now, on to the Board class! This looks like a pretty big class. So, the constructor looks pretty straightforward. I've created the array of squares. However, I have the feeling that filling it up will proably be a decent chunk of code. So I'll put that into a different method, so the Board constructor is not too huge. So I'll call this method setupBoard. So, I'll plan out what exactly setupBoard does:

So, this looks to be a rather tricky method. So, I'll write it in chunks. First, I want to create all the mines. Since there is a definite number of mines, I'll do that in a for loop. Inside the for loop, I'll make two random numbers, x and y, with the RandomNumberFactory. x should be between 0 and width-1, since the arrays are 0-based. If I made it between 0 and width, it could crash if the number was equal to width. Then, I check to see if there is already a mine at that location (by checking against null). If there is not one there already, I create a mine at that location.

Once that is done, I need to put an EmptySquare at every location that does not contain a mine. This can be done with a simple double-for loop. The outer loop handles the x coordinate, and the inner loop handles the y coordinate. I check against null to see if a mine already exists there, and if it doesn't, I create an EmptySquare there.

Now, the third parameter in EmptySquare is the number of adjacent mines. How do I calculate this? Well, I'll add another subroutine to the Board to handle that. The subroutine (countMines) will count the number of mines that are adjacent to a given space. So what will this method do?

Well, what this method would need to do is to check each adjacent square. This will be a 3x3 grid of squares to check, ranging from (x-1) to (x+1), and similarly from (y-1) to (y+1). This could be accomplished by another double for loop. In the body of the loop, it will check to see if the mine at that position is a mine or not. When writing this, I tried to figure out as many special cases as possible. For example, if it is checking one of the squares on the edge of the board, I must be careful not to access a bad value in the array. Similarly, since not all the EmptySquares have not been created yet, I must take care not to call methods on null pointers. I can do this by checking the coordinates to make sure they are neither less than 0, or greater than or equal to the width or height. So, I count by creating a count variable (which starts at 0), and incrementing it once for each mine that is found. Of course, this means I must add an isMine() method to my Square. But such is life.

So, I'll finally try to create the Game class. It doesn't do a whole lot. It just creates the Board. This may change as I implement some more stuff. Following convention, I also make the Applet class, but it does very little. All it does is instantiate a Game.

So, now that I have all these classes created, I'll try compiling them together. Now that I think about it, I have probably written entirely too much without trying to compile. If I was thinking, I would have written smaller parts, and gotten them to work. So this may require a bit of debugging.

Alright. I got a bunch of compile errors, but they're all pretty silly errors. I forgot to put a semicolon in a few places, and tried to call methods that I spelled wrong. Whoops.

So, now all the compile errors are gone, and I try to run it. Unfortunately, appletviewer just hangs when I try to run it. That is not good. I'll throw a few println's here and there to see if my code is actually being run correctly. Whoops. Turns out that I just forgot an = in my .html file. I'm an idiot.

So now I'm running it, and I see pretty much nothing. Hmmm....

Well, let's make sure that the Squares are being created. I'll put a println in the Square constructor, and change the color of them. Nope, that's not it. Still nothing showing up. Ah-ha! I'll add a geometry manager to the applet. Much better. Now there is one square showing up. Hmmm. Ah, I know! I'm not specifying where the squares should be drawn. So, this will require a little design change. I will have to inform the squares of their x and y position on their creation.

Okay, so now that I've done that (by adding x & y parameters to Square, and its subclasses, and adding a line in Square's constructor to set position), things are looking good. I made Mines a different color for testing purposes.

Next, I'm going to work on figuring out how to add graphics for a Mine vs. an EmptySquare, and deal with user interaction (toggle buttons!)

But for now, I will sleep.


Last modified: Wed Mar 11 03:44:20 EST 1998