Posts tagged: Sudoku

Sudoku 2.0 – The Board

I have finally finished enough work that I can start this article series on Sudoku, again. I apologize for starting it so long ago and never finishing it. As I mentioned in my previous introductory post, I have learned a lot since the last time I approached this subject.  I am not going to repeat myself by discussing what Sudoku is and how you play it again.  I did this in my original article.

Ok, I lied.  I will repeat myself briefly because it is important.  The sudoku board is a 9 x 9 grid.  Each cell in this grid holds a value as part of the puzzle.  The cells are further grouped into what is called a Minigrid, of which there are 9.  Each mini grid is a smaller 3 x 3 grid of cells (9 total).

Covering that was important because I used that knowledge to design the board itself.  To keep things straight forward, I used UserControls as their really wasn’t a need to create a custom Control.  The parent control is the Board.  The XAML for the Board UserControl can be found below.

<UserControl
    x:Class="Sudoku.Board"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Sudoku"
    Width="400" Height="400">

    <Grid x:Name="LayoutRoot" Background="White" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Border x:Name="MainBorder" Grid.ColumnSpan="3" Grid.RowSpan="3"  Background="White" BorderBrush="Black" BorderThickness="1" Margin="-1" />

        <!-- Miini Grids -->
        <local:MiniGrid x:Name="C1R1" Grid.Column="0" Grid.Row="0" />
        <local:MiniGrid x:Name="C2R1" Grid.Column="1" Grid.Row="0" />
        <local:MiniGrid x:Name="C3R1" Grid.Column="2" Grid.Row="0" />
        <local:MiniGrid x:Name="C1R2" Grid.Column="0" Grid.Row="1" />
        <local:MiniGrid x:Name="C2R2" Grid.Column="1" Grid.Row="1" />
        <local:MiniGrid x:Name="C3R2" Grid.Column="2" Grid.Row="1" />
        <local:MiniGrid x:Name="C1R3" Grid.Column="0" Grid.Row="2" />
        <local:MiniGrid x:Name="C2R3" Grid.Column="1" Grid.Row="2" />
        <local:MiniGrid x:Name="C3R3" Grid.Column="2" Grid.Row="2" />

        <!-- Highlighters -->
        <Rectangle x:Name="MiniGridHighlighter" Grid.Column="0" Grid.Row="0" Fill="#FF848484" Opacity=".5" IsHitTestVisible="False" Visibility="Collapsed" />
    </Grid>
</UserControl>

The Board itself is pretty simple.  It mainly consists of a Grid control which has 3 columns and 3 rows.  This grid uses a Border to draw a black line around the outside of the board itself.  Each cell in the Grid contains a MiniGrid control.  A MiniGrid is a user control that I created that represents, well, a mini grid on the board.  Each MiniGrid is named after the cell that is in.  For example, the MiniGrid that occupies the first cell on the board (column 1 and row 1) is named “C1R1″.  The Rectangle, named MiniGridHighlighter, is currently a place holder.  The Board doesn’t really use this yet.  I created it because I figured I might need a way to highlight the entire minigrid when I start working on the user interaction and game play.

<UserControl>
    x:Class="Sudoku.MiniGrid"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Sudoku"
    Height="Auto" Width="Auto">

    <Grid x:Name="LayoutRoot">
            <Border Grid.ColumnSpan="3" Grid.RowSpan="3" BorderBrush="Black" BorderThickness="1">
            <!-- Cell Container -->
            <Grid x:Name="CellLayout">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>

                <!-- Cells -->
                <local:Cell x:Name="C1R1" Grid.Column="0" Grid.Row="0" />
                <local:Cell x:Name="C2R1" Grid.Column="1" Grid.Row="0" />
                <local:Cell x:Name="C3R1" Grid.Column="2" Grid.Row="0" />
                <local:Cell x:Name="C1R2" Grid.Column="0" Grid.Row="1" />
                <local:Cell x:Name="C2R2" Grid.Column="1" Grid.Row="1" />
                <local:Cell x:Name="C3R2" Grid.Column="2" Grid.Row="1" />
                <local:Cell x:Name="C1R3" Grid.Column="0" Grid.Row="2" />
                <local:Cell x:Name="C2R3" Grid.Column="1" Grid.Row="2" />
                <local:Cell x:Name="C3R3" Grid.Column="2" Grid.Row="2" />

                <!-- Highlighters -->
                <Rectangle x:Name="ColumnHighlighter" Grid.Column="0" Grid.RowSpan="3" Fill="#FF848484" Opacity=".5" IsHitTestVisible="False" Visibility="Collapsed" />
                <Rectangle x:Name="RowHighlighter" Grid.ColumnSpan="3" Grid.Row="0" Fill="#FF848484" Opacity=".5" IsHitTestVisible="False" Visibility="Collapsed" />
            </Grid>
        </Border>
    </Grid>
</UserControl>

The MinGrid is constructed similar to the Board. Everything is contained within a parent Grid control. This has a Border control and an inner Grid. The inner Grid control, as with the Board control, has 3 columns and 3 rows.  This gives us nine cells total.  Each of these cells contains a Cell control.  Each Cell is named in the same manner as the MiniGrids were (as discussed above).  The MiniGrid also has two highlighter Rectangle controls which we may use later.  One is capable of highlighting a row while the other takes care of the column.

<UserControl>
    x:Class="Sudoku.Cell"
    xmlns">http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="Auto" Width="Auto">

    <Grid x:Name="LayoutRoot">
        <Border BorderBrush="Gray" BorderThickness="1" />
        <TextBlock x:Name="ValueTextBlock" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" FontSize="24" />
    </Grid>

</UserControl>

Finally, above, we have the Cell itself.  This control is very simple and is made up of a Grid that contains a Border and a TextBlock.  The TextBlock is where the actually value for the cell will be displayed.

Sudoku Board

The three user controls, mentioned previously, make up the Sudoku puzzle board, which looks like the image shown above.  At this point there is no interaction but we are ready to fill the board with the actual puzzle (which I will cover in the next article).

Sudoku 2.0 – Introduction

First, let me apologize for taking forever to follow up on the Sudoku article I wrote a while back.  I always intended to actually complete the game and I never got back to it.  Finding the time to keep up with a blog is much more difficult than I initially imagined.  I have made a New Years resolution to attempt to do much better this time around.  I figured I would start with the Sudoku articles, which appear to get the most hits.

I am still using Silverlight but the biggest initially change is that I am not going to bother dynamically creating the Grid this time around.  The first artile, which I should have up in a couple days, will cover the board itself.  I am almost finished designing it in Expression Blend 3.  I have the main board and the minigrid control designed.  I just need to finish up the inidivudal cells.  Once this is all done I will move the XAML over to Visual Studio to wire-up with code.

Thanks for your patience, I promise I will have it up and running soon.

Silverlight Sudoku – The Grid

I long time has past since I initially started this article series which I never got around to finishing. I have since restarted this project and have posted a new article in the new series (which I will actually complete).

I am sure many of you have heard of Sudoku (pronounced soe-DOE-koo). Sudoku is a very popular puzzle game.  The name itself is a Japanese word that roughly means number place.  Playing Sudoku is fairly easy, but, since it IS a puzzle game, not always so easy to complete.

The Basic Rules
I use the term basic because there are many different variations of Sudoku.  This article series will focus on the standard game which, as seen in the image below, is played on a 9×9 grid.  This grid is further divided into 9 3×3 sub-grids.

Standard Sudoku Grid

Standard Sudoku Grid

The figure above also shows the valid values for each cell.  To win Sudoku, every cell must be filled with a number ranging from 1 to 9.  Each sub-grid will contain the numbers from 1-9 with no repeats.  Each row and column in the overall 9×9 grid will also contain the numbers 1 – 9 (also, not repeating).  Since it is the key to playing the game, I am going to repeat that each column, row and sub-grid must contain the numbers 1-9 with no repeats.

When you are first given a Sudoku puzzle, the grid will be partially filled out.  As mentioned above, your task is to use logic to determine what numbers should be in each remaining cell.  I am not going to use this space to step you through all aspects of Sudoku.  There are many sites on the Internet dedicated to providing you with this information and I don’t feel the need to repeat it.  From this point on I am going to assume you know how to play the game so we can move on to the task at hand.

Drawing The Grid
The first thing we are going to work on is drawing the grid that Sudoku will be played on.  For the record, I am using Visual Studios 2008 SP1, Silverlight 2 and Microsoft Expression Blend 2 SP1.  I am also assuming that you have some basic understanding of Silverlight.  If you don’t, you can find everything you need here.

Initially I started drawing the playing grid in Expression Blend.  I started using the Grid control to separate each cell since it already understands the concept of columns and rows.  The idea was to place a TextBlock in a Border control in each cell.  As I was doing this I was a little put off by how long and cluttered the XAML was appearing.  Since our grid is 9 x 9 we are dealing with at least 81 controls, which is a lot.  I was going to use styles to make configuring the TextBlock controls a little easier but even a simple change to the grid or any of the sub controls could be very time consuming.  What I decided was that the creation of the playing board (or grid) needed to be dynamic.

Since this is just the starting point of our project I didn’t do anything fancy.  I created a simple Silverlight project in Visual Studio and added a Canvas (named LayoutRoot) and Rectangle (named BoardBackground) to the Page.xaml file, shown below.

It is important to note that the standard Sudoku board is square so the Height and Width of our page (where the board is being drawn) should be the same.

 

public partial class Page : UserControl
{
    int gridSize = 9;

    public Page()
    {
        InitializeComponent();
        DrawBoard();
    }

    ///
    /// Dynamically draw the Sudoku board
    ///
    public void DrawBoard()
    {

        // Create the lines on the board
        for (int i = 0; i < gridSize; i++)
        {
            // Every third line should be highlighted
            bool highlight = (0 == ((i + 1) % 3));

            // Create new lines
            Line verticalLine = new Line();
            Line horizontalLine = new Line();

            // Configure the vertical line.  If it is a highlight line, it will
            // be darker then the other lines.
            verticalLine.Stroke = new SolidColorBrush { Color = (highlight ? Colors.Black : Colors.Gray) };
            verticalLine.StrokeThickness = 2;
            verticalLine.SetValue(Canvas.ZIndexProperty, (highlight ? 1 : 0));
            verticalLine.X1 = Width * ((double)(i + 1) / gridSize);
            verticalLine.Y1 = 0;
            verticalLine.X2 = verticalLine.X1;
            verticalLine.Y2 = Height;

            // Configure the horizontal line.  If it is a highlight line, it will
            // be darker then the other lines.
            horizontalLine.Stroke = new SolidColorBrush { Color = (highlight ? Colors.Black : Colors.Gray) };
            horizontalLine.StrokeThickness = 2;
            horizontalLine.SetValue(Canvas.ZIndexProperty, (highlight ? 1 : 0));
            horizontalLine.X1 = 0;
            horizontalLine.Y1 = Height * ((double)(i + 1) / gridSize);
            horizontalLine.X2 = Width;
            horizontalLine.Y2 = horizontalLine.Y1;

            // Add the lines to the Canvas
            LayoutRoot.Children.Add(verticalLine);
            LayoutRoot.Children.Add(horizontalLine);
        }

        BoardBackground.Width = Width;
        BoardBackground.Height = Height;
    }
}

The code behind file (Page.xaml.cs), shown above, contains all of the code necessary to draw the board dynamically.

The gridSize variable is used to hold the size of the grid. This defaults to 9 but makes it easy for us to change in the future. All of the drawing is handled by the DrawBoard method. Since I am taking the dynamic approach I realized that I don’t have to use border controls or grids. After all, a Sudoku board is simply made up of a series of lines that cross, forming a grid. Therefore I just use Line controls.

I just wanted to add a quick note to apologize that the previous code example does not have all of the appropriate objects highlighted. It seems that the plugin I am using has not been updated to support Silverlight at this time.

All of the drawing takes place within a loop and we loop the number of times equal to the size of our grid, which is 9. The highlight variable is used to determine if the current line being drawn should be a darker line. This is calculated by checking if the current line is divisible by 3 (since every third line should be highlighted) evenly.

The vertical and horizontal lines are evenly spaced based on the overall size of the control and are configured in a similar manner, differing only in what axis (X for horizontal or Y for vertical) is the primary axis. First, the color of the line is set. As I mentioned above, if this is a highlight line, it will be colored Black; otherwise Gray. Next, the ZIndex property of the Canvas is set. This ensures that the highlight lines (the darker ones) are drawn over the regular lines. Finally, we set the X1, Y1, X2 and Y2 properties which determine the starting and ending points for our line.

For a vertical line, X1 is calculated by multiplying the Width of the page by the current loop index divided by the overall size of the grid. Y1 is 0, X2 will be the same as X1 (since our line needs to be straight) and Y2 will be the same as the Height of the page.

For a horizontal line, X1 is 0 and Y1 is calculated by multiplying the Height of the page by the current loop index divided by the overall size of the grid. X2 is the same as the page Height and Y2 is the same as Y1.

Finally, we add the new line controls to the canvas. The only thing left to do, once the loop is done, is to ensure that the background of our grid (the BoardBackground rectangle) is the same size as our page.

When the application executes, you will see our Sudoku board (as shown in the image below).

Sudoku Board

Sudoku Board

That is the end of this article. I know you didn’t get to do too much. In the next article, which I will try to get to shortly, we will add in the logic to generate a Sudoku game (populate the board).

WordPress Themes