Sudoku në C sharp

### Historiku
Në nëntor të vitit 1892,Le Siècle një francez,publikoj një enigmë me 9x9 blloqe me nga 3x3 nën-blloqe.Kjo enigmë nuk ishte një Sudok sepse përmbante vlera duplikate dhe kërkonte më shumë zgjidhje aritmetike se sa logjike,por kishte një çelës karakteristik: çdo rreshti,kolone dhe nën-blloku i shtohej i njejti numër.
Në qershor të vitit 1886,La France,e përpunoj enigmën duke e bërë atë më modern.Ai thjeshtësoj enigmën me 9x9 blloqe ashtu që çdo rresht,kolonë dhe diagonale përmbante vetëm numrat prej 1 deri 9.

Sudoku më modern ishte dizajnuar nga Howard Garns,një arkitekt 74 vjeçar nga India,dhe u publikua për herë të parë në vitin 1979 në gazetën Dell Magazine me emrin Number Place(Hapsirë numrash).Garn nuk arriti të shoh kreacionin e tij si një fenomen botërorë.
Enigma është paraqitur në Japoni nga Nikoli në gazetën Monthly Nikolist në prill të vitit 1984 me emrin ´Sūji wa dokushin ni kagiru´ e cila mund të perkthehet si `Shifrat duhet të jenë unike´.Më vonë,ky emër u reduktua në Sudoku,duke marrë kështu dy shkronja të para të secilës fjalë.

### Variantet
Enigma me 9x9 blloqe dhe 3x3 nënblloqe është variant i rëndomtë.Enigma të thjeshta mund të jenë me 4x4 blloqe me nga 3x3 nënblloqe.Enigmat mund të jenë edhe më të mëdha siç është Dodeka sudoku me 12x12 blloqe me nga 4x3 nënblloqe.Gazeta Dell publikoj një enigme me 16x16 blloqe.Nikoli ofroj një enigme me 25x25 blloqe të njohur si Sudoku monstra gjigante.Sudoku-zilla ishte një enigme me 100x100 blloqe e cila u publikua në vitin 2010.Një variant me emrin ´´Mini Sudoku´ u publikua në gazetën amerikane USA Today e cial është luajtur me 6x6 blloqe me nga 3x2 nënblloqe.
Hypersudoku është një variant shumë e njohur dhe e perhapur.Ajo u publikua në shumë gazeta botërore me emra si ´NRC Sudoku´ , ´Wondoku´,´Hyper-sudoku´ etj.
Janë përpiluar edhe enigma alfabetike,të nojura si Wordoku,ku dallimi i vetëm është se në vend të numrave janë përdorur shkronjat.

### Kodi për implementimin e enigmes në C#
Klasa Sudoku është klasa kryesore për të implementuar **lojën.GjeneroLojen(Nivelilojes  niveli)** është një metodë e cila e gjeneron **new game**.
Kodi është si vijon:

    public void GjeneroLojen(NiveliLojes niveli)
    {
    InicializoB() ;
    int minPos,maxPos,noOfSet ;
    
    switch(niveli)
    {
    case NiveliLojes.simple:
    minPos=4;
    maxPos=6;
    noOfSets=8;
    UnMask(minPos,maxPos,noOfSets);
    break;

    case NiveliLojes.medium:
    minPos=3;
    maxPos=5;
    noOfSets=7;
    UnMask(minPos,maxPos,noOfSets);
    break;

    case NiveliLojes.complex:
    minPos=3;
    maxPos=5;
    noOfSets=6;
    UnMask(minPos,maxPos,noOfSets);
    break;

    default:
    UnMask(3,6,7)
    break;
    }

Në kodin e mësipërm,**NiveliLojes** është e tipit enum.Metoda **InicializoB()** gjeneron zgjidhjen unike.Metoda **Unmask()** krijon një dataset të quajtur ProblemSet për të pastruar kutit.**GameSet** kthen DataSet-in i cili është përdorur për tu lidhur me DataGrid.DataSet-i kthen tri bashkësi të të dhenave: ProblemSet,nje kopje të ProblemSet dhe AnswerSet.Ky kthim i të gjitha bashkësive të të dhënave në një DataSet të vetëm e thjeshteson ngarkesën dhe ruan funsionalitetin:

    public DataSet ProblemSet
    {
    get{ return FormDataSet();}
     }

Funksioni më lart e thirr metodën private,**FormDataSet()**. Kjo metodë pastaj gjeneron DataSet-in nga vektori dhe e kthen tek funksioni që e thrret.

    private void CurrentSet_ColumnChanging(object sender,System.Data.DataColumnChangeEventArgs e) 
    {
      try
       {
        lblStatus.Text="";
        int rowPos = dataGrid1.CurrentCell.RowNumber;
        string currentNumber = e.ProposedValue as string;
        
        int numri=Int32.Parse(currentNumber);
        if((number 9))
        {
            string errorMessage=
                "Numri duhet te jete ndermjet 1 dhe 9";
            e.Row.SetColumnError(e.Column,errorMessage);
        }
        else
        {
            int col =e.Column.Ordinal;
            bool answerChanged = 
                _newGame.CheckForAnswerChange(rowPos,col,number);
            
            if(answerChanged)
            {
                lblStatus.Text="Nuk mund ta nderroni pergjigjen";
                e.ProposedValue = e.Row[e.Column];

            }
               else if(_newGame.CheckForDuplicate(rowPos,col,number))
               {
               e.Row.SetColumnError(e.Column,"Numri eshte duplikat");
            
                }
              else
             {
                e.Row.menjanogabimin();
                bool Pergjigjakomp= IsSolutionComplete();
                if(Pergjigjakomp)
                {
                  lblStatus.Text= "Shkelqyeshem!!! E keni kryer me sukses";
                }
            }

        }
    }
    catch(Exception ex)
    {
        e.Row.SetColumnError(e.Column,
             "Jepni numrin ndermjet 1 & 9");
    }
  }

Kodi i mësipërm së pari lexon pozicionin e kutisë e cila përdorë tipin **datagrid1.CurrentCell.RowNumber**
Përdoruesi jep vlerën për kutinë që është përdorur në tipin **e.ProposedValue**. Ky tip është konvertuar në një numër dhe pastaj të gjitha të dhënat ekzekutohen duke thirrur metodat **CheckForAnswerhangd()** dhe **checkForDuplicate()**.Labela përdoret për të shfaqur statusin dhe shfaqet një mesazh në qoftë se zgjidhja është kompletuar.Mesazhi për gabim mund  të vendoset përmes tipit **e.Row.SetcolumnError**.Gjithashtu është përdorur edhe një timer për të shfaqur kohën.

**Kufizimi i nënmatricave 3x3**
:Përderisa një DataGrid është përdorur për pamje,atëherë çdo qeli mund të merrë pamjen përkatëse apo kufizimi i DataGrid-it mund të ndryshohet.Për të shfaqur vijën kufizuese për secilin nënbllok ne duhet të shtypim metodën paint të DataGrid-it siç mund të shihet edhe në kodin në vazhdim:
   
    private void DataGrid1_Paint(object sender,System.Windows.Forms.PaintEventArgs e)
    {
    Point currentPoint = new Point(0,0);
    Size permasa = new permasa(PREFERRED_COLUMN_WIDTH*3,PREFERRED_ROW_HEIGHT*3);
    Pen lapsi = new Pen(Color.Red,3);
          
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            currentPoint.X = i*PREFERRED_ROW_HEIGHT*3;
            currentPoint.Y = j*PREFERRED_ROW_HEIGHT*3;
            Rectangle rect = new Rectangle(currentPoint,permasa);
            e.Graphics.DrawRectangle(lapsi,rect);
        }
     }
   }

Një DataGrid kolonë duhet të trashëgohet nga DataGridColumnStyle,e cila është një klasë abstrakte.Microsoft.NET Farmework jep dy tipe për të rregulluar kolonat të cilat janë trashëguar nga kjo klasë.Njëra është DataGridTextBoxColum dhe tjetra është **DataGridBoolColumn**.Është implementuar një klasë **DataGridSpinnerColumn** për **DataGridSpinnerColumn** dhe trashëgohet nga **DataGridBoolColumn**.
Pra mund të shihni  sa i lehtë është implementimi i lojës Sudoku në C# përmes Microsfot.NET

Referimet:
http://en.wikipedia.org/wiki/Sudoku*Sodoku*