Sunday, February 26, 2006

Flipping tile colors

Over the last few days I have spent a great deal of time creating/polishing the Polarium clone. As I kept adding more features, my design had to undergo some changes. With refactoring I was able to maintain the sanity during development. The whole exercise was to learn more about WPF and some of the APIs.

An interesting feature I added yesterday was the ability to flip the tile colors (White->Black, Black->White). Although this is not technically difficult, it is useful while solving puzzles. Consider the puzzle shown below:

As you start to solve this puzzle you will have to take a few moments to think about making your first move. It appears like there are more black tiles than white and in some ways this contrast makes it difficult to decide where to start. Now have a look at the same puzzle with the tile colors reversed (White -> Black, Black -> White).

The puzzle has suddenly become much more manageable. Now the contrast is much better and we can clearly see the pattern. For some puzzles, flipping the tile colors can greatly change our perception of difficulty of the puzzle. The idea is to solve the puzzle and this is one feature that can help you do that!

Implementation problems

An interesting bug I found while implementing this feature was when I would switch the ControlTemplate for the tiles from WhiteTileTemplate to BlackTileTemplate and vice versa. For doing that I would simply assign the template as:

However only assigning the template does not always set the template! It works for the first time but any subsequent template changes does not update the VisualTree. This came as a surprise to me since that is what I would expect with the previous code. After digging some time into the documentation, I found the FrameworkElement.ApplyTemplate() API. The docs say the following:

Builds the current template's visual tree if necessary, and returns a value indicating whether the visual tree was rebuilt by this call.

So my solution was to just call ApplyTemplate() following the template setting.

Saturday, February 25, 2006

Polarium cleanups + a cool new feature

Yesterday night I spent a lot of time playing some of the puzzles from Polarium Puzzle archive. The way I was going about playing them was to copy the puzzle code, paste it into a file, save it, and then load it up in the app. After playing about 5 puzzles I realized the inconvenience in doing that again and again. I had to come up with a better way of doing that and reduce the number of steps required to play a puzzle.

After a few minutes of thinking about this, I came up with the idea of using the Clipboard directly. I would right-click two times on the Polarium title text:

to invoke the level-load operation. At this point, I would check if the Clipboard has any text, and if it did I would call the PolariParser to load the level. Note that this works only for the NintendoDS format. I think I am going to totally remove the support for the B/W/G format, since nobody seems to be using that.

This required me to make some changes to the Parser. Previously all the input used to come from a file. This had to be changed so that I could load directly from text. With all that in place, things are much more comfortable:

Copy the puzzle code from the archive

Right-click 2 times on the Polarium title

Get the grey-cells working on the puzzle!

Besides this I have also cleaned up the code with some refactorings. This should make it more readable.

Friday, February 24, 2006

Support for the NintendoDS custom puzzle format

Today has been pretty busy for me. Once I released the Polarium clone, a co-worker at my workplace pointed out that the custom puzzles are being specified in a separate format and not the B/W/G format that I had come up with. Here is an example of that format:

If you look at the numbers you will have no clue how those numbers map to the Black/White/Gray tiles! I was stumped too. After a prolonged search over the Internet I came across this link that described this encoding format. The description was fairly straightforward and I coded up the decoding logic quickly. The only hitch I faced here was for converting the integer to its binary representation. I used the string Convert.ToString(long value, int toBase)API for this purpose but I found out that the binary representation does not end on a word-boundary. For example for the integer 2862745346, the binary representation turns out to be 10101010101000100000011100000010, whose length is 29 instead of the intuitive 32. This required me to add the padding manually. Frankly I feel the BCL should have given me a binary string of size 8/16/32/64 as it sees fit. Too bad.

Hooking up this format into the program was simple. I added a new file extension (.pol) for this kind of encoding and also created the corresponding parser using GOLD.

With the support for this new format, you can now play more than 1000 puzzles freely available over the internet. That should keep you busy for a loooooooooooooooooong time!

Thursday, February 23, 2006

Animations ready for Polarium clone

Today was the day to have fun with animations. There are couple of animations that are there in the game:

Hilighting the current tile

Translating the current tile to the new position

Showing the level clear messages

All of these were created inside Expression Interactive Designer (EID) using the Timelines. Well not entirely. Since EID doesn't allow creating timelines for anonymous controls, I had to go back to XAML to make some modifications. The reason I needed this was because I wanted to make generic animations rather than tying to a particular control. I made a posting on EID forums on this issue/feature-request. Although these animations are far from creating the *WOW* effect, its an intial draft for getting the feature in place :)

Beside animations, I also added some graphics for the Level Cleared, Try-Again messages. These show up when the user double clicks the current tile to flip all the tiles. At that point if all the tiles in a row are of the same color (not the gray tiles), then the "Clear!" message comes up. Otherwise the "Try Again" message is shown. You can click to get back to the game.

5. Level not cleared6. Level clearedNow I should take care of error handling and try to polish the UI. There is still one major glitch with resizing the window; the right hand side of the tile gets clipped. Got to be pixel-perfect :)

Wednesday, February 22, 2006

Level loader for Polarium clone

I decided to complete the core functionality of the game before polishing the graphics. Today was the day to take care of levels. In my clone you can create your custom levels in a simple text file and load it by clicking on the "Level" button.

If you look at the Polarium grid, it is essentially a rectangular grid of Black/White/Gray tiles. So an example of a level file could look like:

G B W B W GG B W B W GG B W B W GG B W B W GG B W B W GG B W B W G

The letters B/W/G represent the colors and each row is demarcated by the newline character. Instead of creating my own parser by using a bunch of dirty String.Split()s, I decided to use my trusted tool GOLD Builder. GOLD creates LALR parsers and all the rules are written using EBNF syntax. The reason I chose GOLD was because I intend to add support for headers like Author, Date, etc. Extensibility is the key.

Tuesday, February 21, 2006

Polarium clone in WPF

I had wanted to build a clone of the game Polarium for a long time now. I first saw this on my friend's NintendoDS and I got hooked onto it. There are couple of clones floating around already on the internet mostly in Flash, Qt, etc. WPF presents a great platform to build this game. Although I can't own the game, I can surely create (umm...recreate) one.

Since the last 2 days I have been working on the game logic, interactions and the data structures. After thrashing a few designs I have finally been able to solve all the core problems. Now I have a basic version which has the interactions and game logic in place. Here are some screenshots of the game:

The next steps involve adding some animations to show the movements, change the graphics of the tiles and finally work on the levels. Anybody interested?

Thursday, February 16, 2006

How to waste Time?

Today I didn't have anything to do at work, which is pretty much how it has been since last few days. I decided to play more with the Expression Graphic Designer (EGD) and made this clock. A tutorial which was posted here helped me learn some more facets of the EGD. All of this learning will soon be used to create a poster (which I'll be posting soon) for my Master's Thesis. My advisor wants to showcase the work I have done for my Thesis. If you are curious, check out DotSpect. For the not so curious have a look at the clock and waste your time! :)Update: Here are the Expression files.

QuickSort demo mentioned on Expression Blog

Ya you read it right. I had made a small demo a few days back to animate the QuickSort algorithm. The demo was built using the Expression Interactive designer and VS2005. You can either find this on my Blog or you can make a round-trip from the Expression Blog. I suggest you take the second option (Well, thats the whole idea of this blog post, right :))

Monday, February 13, 2006

QuickSort animation in WPF

This is my first complete application written in Windows Presentation Foundation (WPF). I had written many test projects and samples to test various pieces of WPF but nothing that puts things together as a whole.

The idea of creating a QuickSort animation struck me when I was explaining this algorithm to someone at UH. I thought it would be cool to animate this using WPF.

WorkflowThe workflow I adopted was opening up Expression Interactive Designer (EID) and Visual Studio 2005 (VS) side by side. I created the project in EID and then opened it up in VS as well. I would hack in EID to come up with the visuals and then go back to VS to write out the logic. The only nagging thing was the "Do you want to reload?" dialog which pops up in both places as you switch between EID and VS. It would be very cool if these apps understood that we are hacking the same project and reload things automatically. I don't know if this could be configured. If yes, I would like to know HOW?

Insights on the internals

1. The solution is divided into 3 projects. There is a class library that contains the QuickSort implementation. A Test project that has unit tests for QuickSort. Finally there is the UI written using WPF.2. The UI generates some random numbers (clicking on Generate! button) and sets up the list for QuickSort.3. As QuickSort executes, it fires events whenever a Swap operation happens4. The UI intercepts these events and makes a list of all the swaps5. Clicking the Play button plays the swaps as they happened.

Pretty simple isn't it. On the surface yes. I had some issues with animating the elements. Some off-by-one issues in the QuickSort implementation and a few issues with enabling-disabling the (Generate, Play) buttons.

It was fun and a great learning experience. Discussion on the EID forum helped a lot in shaping this app.