With the source code for Microsoft Sudoku released on MSDN at http://msdn.microsoft.com/library/en-us/dntablet/html/tbconSudokuSampleFinal.asp, you can take the code and modify it to your liking, adding features, putting a new UI on the game for different environments, whatever cool projects you come up with. I provided a few project suggestions at the end of the article, but I thought I'd spend a few blog posts detailing other ways the game could be extended.

One of the neat features that many apps have these days (both Web and smart client applications) is the ability to be skinned or themed, allowing users to tweak the UI to their liking. Modifying Sudoku to support basic skinning is a piece of cake, requiring only around 20 lines of code.

At present, Sudoku uses approximately 35 bitmap images for various parts of the UI. This includes some background images, images for the various buttons and icons in the UI, images that serve as suggested-cell or selected-cell highlights, etc. The easiest way to modify Sudoku to provide a skinning feature is to allow a user to easily replace these images with their own set.

Sudoku contains a file ResourceHelper.cs that provides static Bitmap properties for each of these images. The images are all stored as embedded resources in the assembly, and the static constructor for ResourceHelper loads the images from manifest resource streams through an internal method GetResourceImage:

    internal static Bitmap GetResourceImage(string resourceName)
    {
         return new Bitmap(_resourceAssembly.GetManifestResourceStream(resourceName)); 
    }

The resource names supplied to GetResourceImage are strings like "Microsoft.Sudoku.Images.Background.png", "Microsoft.Sudoku.Images.CellHintUpperLeft.png", and "Microsoft.Sudoku.Images.ButtonChecked.png". Thus, the easiest way to modify Sudoku to providing skinning capabilities is to modify GetResourceImage to pull these resources from somewhere besides the assembly's embedded resources. To begin, I'll add the following code to ResourceHelper.cs:

    private static string _skinDirectoryPath;

    private static string SkinDirectoryPath
    {
        get
        {
            if (_skinDirectoryPath == null)
            {
                _skinDirectoryPath = System.Configuration.ConfigurationSettings.AppSettings["SkinDirectoryPath"];
                if (!Directory.Exists(_skinDirectoryPath)) _skinDirectoryPath = string.Empty;
                else if (!_skinDirectoryPath.EndsWith("\\")) _skinDirectoryPath += "\\";
            }
            return _skinDirectoryPath;
        }
    }

This code adds a SkinDirectoryPath property that will return the string path to a folder containing the skin's replacement images. It pulls this path from the AppSettings section of the application's configuration file:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <appSettings>
            <add key="SkinDirectoryPath" value="C:\Sudoku\BlueSkin\" />
        </appSettings>
    </configuration>

Now, all that remains is to modify GetResourceImage to pull an image from the skin directory if that image can be found there (if it can't be found, it will fall back to the original behavior, pulling the images from the embedded resource):

    internal static Bitmap GetResourceImage(string resourceName)
    {
        string filepath = SkinDirectoryPath;
        if (filepath.Length > 0)
        {
            filepath += resourceName;
            if (File.Exists(filepath)) return new Bitmap(filepath);
        }
        return new Bitmap(_resourceAssembly.GetManifestResourceStream(resourceName)); 
    }

That's the total extent of the modifications to the application necessary to support basic skinning. I could of course add more code to support layout modifications, ink color changes, and so forth, but by allowing the images to be replaced with any of the user's choosing, some really nice skins can be created. For example, here are two skins I created simply by changing the background images and the color hues of the rest of the images:

You can download the image files for these skins from here and here. Simply extract the images into a directory, and then point the SkinDirectoryPath appSetting at this directory. When you launch Sudoku, GetResourceImage will discover the new images and use those instead of the ones embedded in the assembly.

Note that I pulled the background images from the Origami Project Gallery.  These images are meant be used with the Program Launcher application that ships on Ultra-Mobile PCs (UMPC) as part of the Microsoft Touch Pack, but they work equally well with Sudoku.