Polarium clone in WPF - compendium
A clone of the popular game
Polarium is available for Windows Presentation Foundation (WPF). This currently runs on the
WinFX Jan CTP May CTP of WinFX Beta 2 runtime.
It is currently in version 2.2 and includes the following features:
- Supports all standard interactions available in NintendoDS
- Single click: Move to selected tile
- Double click (on current tile): Flip tiles
- Ability to load levels in the custom NDS puzzle format. You can simply copy the puzzle code from the Polarium Puzzle Archive and right-click twice on the Polarium title. This will load that puzzle.
- Flipping tile colors (White <-> Black)
- Cool animations
There are certainly many areas that can be improved/added. If there is enough interest I would be glad to create a GotDotNet workspace.
-------------------------------------------Download Source and Binaries.-------------------------------------------Here are all the blog posts detailing the development of this game:
- http://pavanpodila.blogspot.com/2006/02/polarium-clone-in-wpf.html
- http://pavanpodila.blogspot.com/2006/02/level-loader-for-polarium-clone.html
- http://pavanpodila.blogspot.com/2006/02/animations-ready-for-polarium-clone.html
- http://pavanpodila.blogspot.com/2006/02/polarium-clone-v10.html
- http://pavanpodila.blogspot.com/2006/02/support-for-nintendods-custom-puzzle.html
- http://pavanpodila.blogspot.com/2006/02/polarium-cleanups-cool-new-feature.html
- http://pavanpodila.blogspot.com/2006/02/flipping-tile-colors.html
[Update] The Polarium clone now works on
May CTP of WinFX Beta 2. Enjoy!
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 problemsAn 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:
string template = "GrayTileTemplate";
if (tile.Color == TileColor.Black) { template = "BlackTileTemplate"; }
else if (tile.Color == TileColor.White) { template = "WhiteTileTemplate"; }
b.Template = FindResource(template) as ControlTemplate;
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.
b.Template = FindResource(template) as ControlTemplate; b.ApplyTemplate();
I think this is bad design. The setter of the Template property should have done this. I am not sure what is the rationale behind this approach.
Download Source and Binaries (v2.2)
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.
Download
Source and Binaries (v2.1)
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!
Download
Source and Binaries. I christine this
v2.0. Visit the
Puzzle Archive to play some cool puzzles. Enjoy!
Polarium Clone v1.0
I think I finally have a functional Polarium clone. The changes since the last build include:
- Error handling for invalid level-files
- Enabling/Disabling of buttons (Clear, Level)
- Polished UI - removed the title bar and replaced with a custom one, changed some graphics
- Added a help button on the titlebar, clicking on which takes you to the Polarium Wiki page. This is useful for people who haven't played Polarium before. It will help them learn the rules.
- Created 5 stock levels. They are all .pl files in the /Levels folder.
Screenshots:
1. Main window
2. Loading an invalid file
I guess it is now time to sanitize the code!
Update: You can now play this game by downloading the Source and Binaries!
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.
Now, time for some screenshots:
1. Main App when you open up
2. Loading the level file
3. Level file loaded (How am I getting that weird violet color? Should be yellow!)
4. Current tile animation (translation) [Weird colors again!]
5. Level not cleared
6. Level cleared
Now 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 :)
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 G
G B W B W G
G B W B W G
G B W B W G
G B W B W G
G 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.
The grammar is pretty straightforward. Have a look
here.
I still need to take care of Error handling and do some code cleanups. Another Day of work!
Update: Since the grammar contained text that got interpreted by Blogger as tags, I've linked to the file instead.
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?
PDC talks on WPF: Better Late than Never
Couple of PDC '05 talks given on various aspects of the Windows Presentation Foundation, all streamed to the cozy comfort of your laptop! http://microsoft.sitestream.com/PDC05/
Thesis Poster in Expression Graphics Designer
My advisor Dr. Venkat Subramaniam had asked me to create a poster to showcase my Thesis on DotSpect and it had to be as big as an A4 size paper. This was a good reason to fire up Expression Graphics Designer (EGD) and have some fun! The result is shown below:
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 :))
Removing locks on files
Have you ever ran into the problem of locked files? Dialogs like are pretty annoying. You would have to restart explorer.exe or even restart your computer sometimes. Avoid all these problems with the Unlocker tool.
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 happens 4. The UI intercepts these events and makes a list of all the swaps 5. 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. Download the source.
|