Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop

Sudoku Generator using DataGridView

5.00/5 (3 votes)
21 Feb 2014CPOL1 min read 17.8K   97  
Sudoku Generator

Introduction

In this article, I will show you my first WinForm Sudoku Generator in C# using DataGridViev.

Background

I love playing Sudoku. The first thought was create Sudoku Solver, but I do not have enough experience to do it. So, I decided to create Sudoku Generator at first.

Using the Code

First of all, we need to create a game place and design them. For that, we create a DataGridView and then format it. I use for this Build() function.

C#
public void Build()
     {
         DGV1.ColumnCount = 9;
         DGV1.Rows.Add(9);

         for (int i = 0; i < 9; i++)
         {
             DataGridViewColumn column = DGV1.Columns[i];
             column.Width = (int)(DGV1.Width / 9f);
             DataGridViewRow row = DGV1.Rows[i];
             row.Height = (int)(DGV1.Height / 9f);
         }
         DGV1.Width = DGV1.Columns[1].Width * 9;

         for (int i = 0; i < 9; i++)
         {
             for (int j = 0; j < 9; j++)
             {
                 DGV1.Rows[i].Cells[j].Style.BackColor = Color.LightCyan;
             }
         }

         for (int i = 0; i < 9; i++)
         {
             for (int j = 3; j < 6; j++)
             {
                 DGV1.Rows[i].Cells[j].Style.BackColor = Color.LightBlue;
                 DGV1.Rows[j].Cells[i].Style.BackColor = Color.LightBlue;
             }
         }

         for (int i = 3; i < 6; i++)
         {
             for (int j = 3; j < 6; j++)
             {
                 DGV1.Rows[i].Cells[j].Style.BackColor = Color.LightCyan;
                 //DGV1.Rows[j].Cells[i].Style.BackColor = Color.LightBlue;
             }
         }
     }

In this code, I add 9 rows and 9 columns in a table and then set some color for them.

The game consists of:

  • Game class that represent the game structure
  • static PermFunc class that consists of functions used by array permutation

The game concept is realized in the Game class. I use array for saving data from DGV.

In constructor, there is array initializing according to the rules. And array permutation. This Permutation() function mixes values in the array.

C#
public void Permutation()
       {
           PermFunc.Mix(array);
           solve =Copy(array, solve);   // used to solve sudoku
           DeleteCell();                // randomly remove a certain number of cells
           ShowIt(array);               // display generated array on the screen
       }

PermFunc.Mix(array) - It is the function from static class PermFunc that is used for data permutation.

C#
public static int[,] Mix(int[,] array)
   {
       int b = random.Next(40, 50); // кількість операцій перемішування 

       for (int i = 0; i < 40; i++)
       {

           int s = random.Next(1, 7);
           switch (s) // permutation function switching
           {
               case 1:
                   {
                       SwapColumns(array);
                       break;
                   }
               case 2:
                   {
                       SwapRows(array);
                       break;
                   }
               case 3:
                   {
                       Transpose(array);
                       break;
                   }
               case 4:
                   {
                       SwapBigColumns(array);
                       break;
                   }
               case 5:
                   {
                       SwapBigRows(array);
                       break;
                   }
               default:
                   {
                       SwapRows(array);
                       break;
                   }
           }
       }
       return array;
   }

Mixing algorithm is in swapping rows or columns within a group.

Here is the code for SwapRows() function:

C#
public static void SwapRows(int[,] array)
     {
         int a = random.Next(0, 8);
         int b = random.Next(0, 8);
         while (!Allowed(a, b))  // the cell is free
         {
             b = random.Next(0, 8);
         }
         int temp;
         for (int i = 0; i < array.GetLength(0); i++)
         {
             temp = array[i, a];
             array[i, a] = array[i, b];
             array[i, b] = temp;
         }
     }

where Allowed() determines according to Sudoku game the possibility of swapping random rows.

C#
public static bool Allowed(int a, int b)
      {
          if ((a == 0) || (a == 3) || (a == 6))  // swapping only between certain columns
          {
              if ((b == a + 1) || (b == a + 2))
              {
                  return true;
              }
          }

          if ((a == 1) || (a == 4) || (a == 7))
          {
              if ((b == a - 1) || (b == a + 1))
              {
                  return true;
              }
          }
          if ((a == 2) || (a == 5) || (a == 8))
          {
              if ((b == a - 1) || (b == a - 2))
              {
                  return true;
              }
          }
          return false;
      }

For verifying data, I used a function that separately checks rows, columns and squares for the error.

C#
public bool NewValidate()
       {
           int[,] mass = new int[9, 9];

           int one = 0;

           for (int i = 0; i < 9; i++)
           {
               for (int j = 0; j < 9; j++)
               {
                   one = SetValue(mass, i, j); // sets value from DGV
                   mass[i, j] = one;
               }
           }
           if (!VerifyRows(mass))
               return false;
           if (!VeryfyColumns(mass))
               return false;
           if (!VeryfySquares(mass))
               return false;
           return true;
       }

The squares verifying function looks like:

C#
private bool VeryfySquares(int[,] mass)
 {
     int val = 0;
     for (int n = 0; n < 3; n++)
     {
         for (int m = 0; m < 3; m++)
         {
             List<int> list = new List<int>(9);
             for (int i = 0 + n * 3; i < 3 + n * 3; i++)
             {
                 for (int j = 0 + 3 * m; j < 3 + 3 * m; j++)
                 {
                     val = mass[i, j];
                     if (val == 0)   // if val=0 value not displayed
                     {
                         continue;
                     }
                     if (list.Contains(val))
                     {
                         MessageBox.Show(val.ToString());
                         return false;
                     }

                     else
                         list.Add(val);
                 }
             }
         }
     }
     return true;
 }

The game window is as shown below:

Image 1

I'm sorry for my English. Waiting for constructive comments...

History

  • 20th February, 2014 - Original version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)