IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Tvorba sudoku v Xamarin - Kontrolní mechanismy

V minulé lekci, Tvorba sudoku v Xamarin - Nahrání aplikace do mobilu, jsme nahráli aplikaci na iPhone a Android a nastavili mobil pro vývoj, abychom mohli aplikaci debugovat.

V dnešním Xamarin tutoriálu implementujeme kontrolní mechanismy pro zadání a řešení Sudoku. Základem bude kontrola dvou buněk, kterou zavoláme při kontrole stejných čísel ve sloupcích, řádcích, mřížce a nakonec v celém Sudoku.

Budeme rozšiřovat naši aplikaci z lekce Nahrání aplikace do mobilu. Všechen kód budeme psát do souboru MainPage.xaml.cs.

Třída EntrySudoku

Jelikož máme 81 Entry, které umí reagovat na uživatelský vstup, ale nevědí, kde v mřížce se nacházejí, musíme určit souřadnice. Tyto souřadnice budeme definovat při vytvoření nového objektu třídy EntrySudoku, kterou si teď vložíme na začátek souboru MainPage.xaml.cs:

public class EntrySudoku : Entry
{
    int row;
    int column;
    public int getRow() => row;
    public int getColumn() => column;

    public EntrySudoku(int r, int c) : base()
    {
        row = r;
        column = c;
    }
}

Třídu využijeme pro testování implementovaných funkcionalit z uživatelského rozhraní.

V proměnných row a column budeme ukládat umístění mřížky. Umístění pak definujeme v konstruktoru.

Změny stávajícího kódu

Na základě vytvoření třídy EntrySudoku změníme:

  • všechny výskyty typu Entry za typ EntrySudoku,
  • vytvoření nového objektu typu Entry za nový objekt typu EntrySudoku.

Struktura Bunka

Pod třídu EntrySudoku si vložíme novou strukturu Bunka, do které umístíme proměnné hodnota a konstanta:

public struct Bunka
{
    public int hodnota;
    public bool konstanta;
};

Proměnná hodnota bude moci nabývat hodnot:

  • 0 pro neutrální hodnotu,
  • 1 - 9 pro povolené hodnoty,
  • ostatní pro nepovolené hodnoty.

Pomocí proměnné konstanta budeme zjišťovat, zda daná hodnota nabývá hodnoty true a jedná se tedy o zadání sudoku, nebo hodnoty false a jedná se o buňku kterou musí vyplnit řešitel úlohy.

Následující metody si napíšeme například na konec souboru MainPage.xaml.cs.

Kontrola buněk

Jako první si napíšeme metodu pro kontrolu, zda hodnoty obou přijatých buněk jsou stejné:

static public bool SuRovnake(Bunka bunka1, Bunka bunka2)
{
    if ((bunka1.hodnota < 1) || (bunka1.hodnota > 9))
        return false;
    if ((bunka2.hodnota < 1) || (bunka2.hodnota > 9))
        return false;
    return bunka1.hodnota == bunka2.hodnota;
}

V metodě porovnáváme buňky bunka1 a bunka2, které jsme přijali v parametrech metody. Pokud se hodnoty buněk v intervalu 19 shodují, vrátíme hodnotu true. Pokud se hodnoty buněk v tomto intervalu neshodují, nebo máme v buňce neutrální hodnotu 0, vrátíme hodnotu false.

Kontrola sloupce

Nyní v nové metodě zkontrolujeme, zda ve sloupci se vyskytují stejné hodnoty:

static public bool SkontrolujStlpec(int row)
{
    for (int column = 0; column < 8; column++)
    {
        for (int i = column + 1; i < 9; i++)
        {
            if (SuRovnake(sudoku_grid[row, column], sudoku_grid[row, i]))
                return false;
        }
    }
    return true;
}

V prvním cyklu načítáme číslo. V druhém cyklu načteme další číslo. Načtená dvě čísla porovnáme pomocí metody SuRovnake() a vrátíme hodnotu false nebo true. Takto následně porovnáme číslo z prvního cyklu se zbývajícími čísly z druhého cyklu. Nakonec načteme další číslo v prvním cyklu a pokračujeme v porovnávání.

Kontrola řádku

Obdobně v další metodě zkontrolujeme, zda se v řádku vyskytují stejné hodnoty:

static public bool SkontrolujRiadok(int column)
    {
        for (int row = 0; row < 8; row++)
        {
            for (int i = row + 1; i < 9; i++)
            {
                if (SuRovnake(sudoku_grid[row, column], sudoku_grid[i, column]))
                    return false;
            }
        }
        return true;
    }

Stejně tak zkontrolujeme čísla v řádku. Tedy opět načteme číslo v prvním cyklu. V druhém cyklu načteme další číslo. Načtená dvě čísla porovnáme pomocí metody SuRovnake() a vrátíme hodnotu false nebo true. Takto následně porovnáme číslo z prvního cyklu se zbývajícími čísly z druhého cyklu. Nakonec načteme další číslo v prvním cyklu a pokračujeme v porovnávání.

Kontrola mřížky

Nyní implementujeme metodu pro kontrolu čísel v mřížce 3x3:

static public bool SkontrolujMriezku(int row_in, int column_in)
{
    int zaciatok_mriezky_row = 0;
    int zaciatok_mriezky_column = 0;
    int row, column, i, j;
    Bunka[] pole = new Bunka[9];
    zaciatok_mriezky_row = row_in / 3 * 3;
    // bude to 0 nebo 3 nebo 6
    zaciatok_mriezky_column = column_in / 3 * 3;
    // bude to 0 nebo 3 nebo 6
    i = 0;
    for (row = zaciatok_mriezky_row; row < zaciatok_mriezky_row + 3; row++)
    {
        for (column = zaciatok_mriezky_column; column < zaciatok_mriezky_column + 3; column++)
        {
            pole[i++] = sudoku_grid[row, column];
        }
    }
    for (i = 0; i < 8; i++)
    {
        for (j = i + 1; j < 9; j++)
        {
            if (SuRovnake(pole[i], pole[j]))
                return false;
        }
    }
    return true;
}

V metodě jsme převedli mřížku na řádek a použili stejný algoritmus. U výpočtu počátečního řádku a sloupce mřížky používáme celočíselnou aritmetiku. Takže například u kontroly pátého řádku, počáteční řádek mřížky je 5/3=1 a 1*3=3, tedy třetí řádek. Pokud je vše v pořádku, vrátíme hodnotu true. V případě dvou stejných čísel v mřížce vrátíme hodnotu false.

Kontrola Sudoku

Poslední metodou zkontrolujeme celé Sudoku:

static public bool SkontrolujSudoku()
{
    int riadok, stlpec;

    // kontrola řádků
    for (riadok = 0; riadok < 9; riadok++)
    {
        if (!SkontrolujRiadok(riadok))
            return false;
    }

    // kontrola sloupců
    for (stlpec = 0; stlpec < 9; stlpec++)
    {
        if (!SkontrolujStlpec(stlpec))
            return false;
    }

    // kontrola mřížky
    for (riadok = 0; riadok < 9; riadok += 3)
    {
        for (stlpec = 0; stlpec < 9; stlpec += 3)
        {
            if (!SkontrolujMriezku(riadok, stlpec))
                return false;
        }
    }
    return true;
}

Zkontrolujeme postupně všechny řádky, sloupce a mřížku. Pokud nalezneme chybu, z metody vyskočíme a vrátíme hodnotu false. Pokud dojdeme až na konec bez chyby, vrátíme hodnotu true.

V příští lekci, Tvorba sudoku v Xamarin - Test kontrolních mechanismů, si ukážeme, jak můžeme graficky otestovat naše kontrolní mechanismy a zobrazit počet zadaných čísel a číslic.


 

Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.

Předchozí článek
Tvorba sudoku v Xamarin - Nahrání aplikace do mobilu
Všechny články v sekci
Xamarin aplikace Sudoku v C# .NET
Přeskočit článek
(nedoporučujeme)
Tvorba sudoku v Xamarin - Test kontrolních mechanismů
Článek pro vás napsal Daniel Martinko
Avatar
Uživatelské hodnocení:
1 hlasů
Aktivity