Sunday, March 27, 2011

posted DDTe1 Hours 20 to 22 - Final Touches

This week we finish the series of posts on the creation of Dozen Days of Tiles Episode 1: Sudoku Player.


At this point, the Sudoku Player is in a pretty nice state with only three buttons left to implement and some additional cosmetic touches to add.

The Clear Notes button is the easiest to tackle. It simply sets all the notes in the notes section to the unchecked state. I probably don’t need to explain how this is implemented as all the method consists of is a loop through all the check boxes setting them all to false.

The Hint button is a handy feature in that it automatically sets up the notes for you. As this requires heavy use of the SudokuView classes valid tile methods the setTileHints method has been placed inside the SudokuView class. This is a bit more complex as it calls the checkRowForValue, checkColForValue, and checkGroupForValue methods for each of the 9 possible values for the tile. If all three of these methods return a 0 then we know it is possible for that number to be placed inside of the tile and therefore set the appropriate check box.

The final button to implement is the check button. It checks the value in the row using the checkRowForValue, checkColForValue, and checkGroupForValue methods to see that the value only appears one in the row, column and group. If it does, it is valid otherwise the tile gets set to blank and the hint function gets called.

Once all this was implemented, a backdrop piece of art was created and some fine tuning to the layout was completed. While I would have liked to add some keyboard support to the game, there simply was not enough time within the 24 hour limit this series imposes on episodes so the game was deemed finished. Depending on what happens on April 1st, I may re-visit this game and add additional features but I think the original version of the player will be retained to keep the spirit of the project.

Sunday, March 20, 2011

DDTe1 Hours 17 to 19 - The Mistake System

Again, we continue my series of posts on the creation of my Sudoku Player. Speaking of which, new puzzles have been added. While the Sudoku Player is technically in a functional state at this point in its development, none of the sidebar buttons work. As most of the functionality that I want is tied to these buttons, it is important to start implementing the features. To me, the most important feature is the mistake system. When on, it color codes the tiles based on if the numbers in the tiles are valid for the current state of the puzzle.

For some reason, most likely being rushed due to the time constraints placed on this project, I refer to the mistakes as hints. the enableHintsMode method in the View class will set the state of the hint system. If mistakes are to be shown, the updateHints method gets called to set the colors otherwise we simply loop through the View’s tiles and set them to the normal color if they are not locked.

Before the updateHints method can be created, some support methods need to be created. These methods are checkRowForValue, checkColForValue, and checkGroupForValue. This is a poor name for these functions as they return a count of how many times the indicated value is found, but I couldn’t think of a more appropriate names at the time. The row and column methods are fairly obvious to write but the group method required a bit of thought. My solution was to use the group number to determine offsets and have a simple pair of loops to check a 3x3 section using the offsets. Here is that function:

Sudoku.SudokuView.prototype.checkGroupForValue = function(g, n)
{
    var cntrRow, cntrCol;
    var foundCount = 0;
    var rowOffset = Math.floor((g-1) / 3) * 3;
    var colOffset = Math.floor((g-1) % 3) * 3;
    for (cntrRow = 1; cntrRow < 4; ++cntrRow)
        for (cntrCol = 1; cntrCol < 4; ++cntrCol)
            if (this.tileGrid[rowOffset+cntrRow][colOffset+cntrCol].getValue() == n)
                ++foundCount;

    return foundCount;
}

With the above three methods finished, the updateHints method is very simple to write. It is just a simple loop over all the tiles. For each tile, we add the results of the above three methods when called for the tiles row, column and group using the current value in the tile. If this number is greater than 3 then the number appears more than once in one of the three categories and therefore is not a valid tile.

With this code out of the way, the only thing left to do is to implement the toggle button. Originally I was going to use two buttons (one visible, the other invisible) to switch between the two states, but I quickly realized that the ImageCheckBox class can have button images instead of box images so I combined the two images to create the check box. With that done, the mistakes toggle shows which numbers are valid if the player desires this information. With only a few hours left in the project, it is time to finish things off.

Sunday, March 13, 2011

DDTe1 Hours 12 to 16 Laying Out the Game

This week we will continue the series of articles about the creation of the Sudoku Player project (episode 1 of my Dozen Days of Tiles series on Blazing Games). The next step in the creation of the Sudoku Player is to build the user interface. When you look at the original planned layout, it is easy to break the interface down to two separate parts. The view of the puzzle and the note taking area on the right side. We will call the puzzle viewing area the view and the note-taking area the side bar.  As a tile already exists for use with testing the side bar note-taking ability, I started with the side bar class which I called SideBar.

Laying out the buttons for the sidebar was very quick as it was just cutting and pasting from my user interface tester with the coordinates changed to be relative to the position of the sideBar. This allows the sidebar to be moved around easier and may make porting the game to another platform easier. The Numbers used to set the value of the tile and the check boxes for the notes can be placed algorithmically using a for loop. This leads to the rather large question of how to set the notes.

My thoughts are that when a tile is selected on the view, the selected tile gets sent to the SideBar which then updates it’s notes. Locked tiles, which are the numbers given to the player at the start of the game, should not be changable and should not have any notes. The setTile method calls updateUI which will hide the tiles and note check boxes if the tile is null or locked. To deal with locked tiles, a scaled-up tile is drawn in the note area with the value of the tile being the locked value. If a tile does exist and it is not locked, the check boxes are set to the note flags contained within the tile.

The sideBar class has implemented buttonClicked for dealing with buttons, which at this point of time does nothing but will be used later to actually make the sidebar buttons do something. The checkboxClicked method simply determines which check box was clicked (by looking at the unique id assigned to the check box) and updates the tile notes. This leads to the question of how to deal with clicking on a tile? Obviously a mouseUp method has to be added to the tile class which calls the registered listener’s tileClicked method. In sideBar, this method simply sets the value of the tile.

Testing on a single test tile works great so the next step is to create a grid of tiles. This is the view portion of the interface and is controlled by the SudokuView class. This is simply a grid of tiles represented by a two dimensional array. In JavaScript, such arrays have to be created by creating an array of arrays. The spacing of the tiles is calculated using the following code:

tempY = cntrRow * 43 + Math.floor((cntrRow - 1) / 3) * 10 - 27;
tempX = cntrCol * 43 + Math.floor((cntrCol - 1) / 3) * 10 - 27;

I should probably point out that constant numbers should not be used in production code, constant or property variables are far better as it makes changes much easier to implement. That said, when under pressure and when developing such a small project such shortcuts are common. Another shortcut that was taken was using the view for the tile grid as the model. The model and view should be separate with the model containing the data and the view just displaying the data. In fact, the Generator that I am creating will need a model class so I just deferred the development time. In hindsight, this was actually the correct decision as I barely finished the project in time as it was.

The tile message gets captured and passed to the parent SudokuPlayer class which calls the SideBar class with the selected tile. The rectangle showing which tile is selected was not implemented until later. At this point we have a fully functional game but many features are missing.

Sunday, March 6, 2011

DDTe1 Hours 8 to 11 - Check Boxes

With the image button created, the next step is to create a check box component. As with the ImageButton class, I opted to go with an ImageCheckBox. Before starting work on this, the artwork for the buttons and check boxes used in the game were created. I used FireWorks to do this, but any graphics program would have worked. Ideally, you want a graphics program that supports layers as they make the creation of template artwork easier. This way only a single fancy button needed to be created, with the text changed in the template to create the different buttons used in the game. For checkboxes, the image strip becomes a 2x4 image grid.

When you think about it, the ImageButton is very similar to the check box so most of the functionality that is needed to implement the check box can be inherited from the ImageButton. To this we add four additional bounding boxes to represent the image clips to use when showing the checked state of the button. We also need to know if the check box is checked so a checked flag is added.

As the ImageButton class already has a setClips method, which sets the image clips to use for the unchecked states, we only need to add a setCheckedClips method to add the ability to manually set up all the clips. This is probably an unnecessary feature, but if in the future all buttons get merged into a single image atlas, this is a handy feature to have. In addition to this new method, setChecked and isChecked methods are added to manage the state of the check.

While most of the methods inherited from ImageButton are unchanged, the mouseUp method and the drawSelf method do need to be altered. The mouseUp method needs to be able to toggle the state of the checkbox while the drawSelf method needs to distinguish between the checked and unchecked states when drawing.

To test this class as well as the new images created for the buttons, a mock-up of the sudoku sidebar was created. This is when a problem came to light. The problem is that the clicks go to a specified function for handling them. As this is a function call, the this reverence is the global this reverence not the this from the object setting the callback. While not a bug, often it is desirable to have functions be handled on an object scope and not a global scope. One solution to this would just be to attach a “parent” variable to the buttons but this is messy. A better approach would be to use interfaces. As JavaScript uses duck typing for calling methods, all that needs to be done is to set the onClick variable to an object instead of a function and have the buttons call the buttonClicked or checkboxClicked function of the passed object.

For those not familiar with the term duck typing, it essentially means that JavaScript doesn’t care what type of object is being sent as long as that object supports the method being called. The name comes from the expression, “If it looks like a duck, walks like a duck and quacks like a duck it probably is a duck.”