IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Míny - Kontrola počtu min, víťazstvo, zobrazenie pole

Tento článok je súčasťou nákupný programovacích jazykov C #, Java a game maker pri tvorbe klasických Min (Minesweeper) pozri: -> Miny aneb nákupný programovacích jazykov C #, Java, GM

Teraz napíšeme fce pre kontrolu počtu min v okolí tlačidlá, kontrola víťazstvo, zobrazenie voľných polí a zobrazenie celého mínového poľa.

C # zápis

Farba podľa počtu min

Iba vracia farbu podľa zadaného počtu min.

// barva podle počtu min
public static Color getColor(int count_of_mines)
{
    switch (count_of_mines)
    {
        case 0: return Color.White;
        case 1: return Color.SkyBlue;
        case 2: return Color.GreenYellow;
        default: return Color.Orange;
    }
}

Počet min v okolí

Prejde okolia tlačidlá a spočíta vráti počet mín v ňom.

// projede okolí stisknutého tlačítka a vrátí počet min kolem něj
private int checkMinesAround(int x, int y)
{
    int count = 0;


    for (int i = -1; i <= 1; i++)
    {
        for (int j = -1; j <= 1; j++)
        {
            // ošetření přetečení
            if (((x + i < 0) || (x + i >= _xLength)) || ((y + j < 0) || (y + j >= _yLength)) || ((x + i == x) && (y + j == y)))
                continue;

            if (_minesArray[x + i, y + j])
                count++;
        }
    }
    return count;
}

Zobrazenie voľných polí

Rekurzívne prejde okolia stlačeného tlačidla a ak je hodnota v min v jeho okolí rovná nule, skontroluje okolie jeho okolitých tlačidiel a postupuje rovnakým spôsobom.

// projede všechny tlačítka od stisknutého, které mají v okolí nulový počet min a zobrazí je
public void showFree(int x, int y)
{
    for (int i = -1; i <= 1; i++)
    {
        for (int j = -1; j <= 1; j++)
        {
            // ošetření přetečení
            if (((x + i < 0) || (x + i >= _xLength)) || ((y + j < 0) || (y + j >= _yLength)))
                continue;

            if ((this.checkMinesAround(x + i, y + j) == 0) && (_buttons[x + i, y + j].Enabled == true) && (_buttons[x + i, y + j].Text != "?"))
            {
                _buttons[x, y].Text = "0";
                _buttons[x, y].BackColor = Mines.getColor(0);
                _buttons[x, y].Enabled = false;
                this.showFree(x + i, y + j);
            }
        }
    }
}

Zobrazenie celého poľa

Jednoducho prejdeme celé pole. Všimnite si odstránenie udalosti myši.

// zobrazí celé minové pole (při prohře či výhře)
public void showField()
{
    for (int y = 0; y < _yLength; y++)
    {
        for (int x = 0; x < _xLength; x++)
        {
            if (_minesArray[x, y])
            {
                _buttons[x, y].Text = "M";
                _buttons[x, y].BackColor = Color.Red;
            }
            else
            {
                _buttons[x, y].Text = checkMinesAround(x, y).ToString();
                _buttons[x, y].BackColor = Mines.getColor(checkMinesAround(x, y));
            }
            _buttons[x, y].Enabled = false;
            _buttons[x, y].MouseDown -= new MouseEventHandler(Mines_MouseDown);
        }
    }
}

Víťazstvo

Skontroluje počet aktívnych tlačidiel a porovná tento počet z celkovým počtom min. Ak sa zhoduje - zostávajú iba míny.

// pokud je počet aktivních tlačítek roven počtu min (zbývají pouze miny) -> vítězství
public bool checkVictory()
{
    int enabled_buttons = 0;
    foreach (Button but in _buttons)
    {
        if (but.Enabled == true)
            enabled_buttons++;
    }

    if (enabled_buttons == _countOfMines)
        return true;
    else
        return false;
}

Java zápis

Farba podľa počtu min

Iba vracia farbu podľa zadaného počtu min.

// vrací barvu v závislosti na počtu min
public Color getColor(int count_of_mines)
{
    switch (count_of_mines)
    {
        case 0: return Color.white;
        case 1: return Color.blue;
        case 2: return Color.green;
        default: return Color.orange;// větší než 2
    }
}

Nastavenie tlačidla

Nastaví tlačidlo podľa zadaných parametrov.

public void setButton(String text, Color color, int x, int y)
{
    buttons[x][y].setText(text);
    buttons[x][y].setBackground(color);
    buttons[x][y].setEnabled(false);
}

Počet min v okolí

Prejde okolia tlačidlá a spočíta vráti počet mín v ňom.

// vrátí počet min kolem daného tlačítka
public int checkMinesAround(int x, int y)
{
    int count = 0;
    for (int i = -1; i <= 1; i++)
    {
        for (int j = -1; j <= 1; j++)
        {
            // ošetření přetečení
            if (((x+i < 0) || (x+i >= x_length)) || ((y+j < 0) || (y+j >= y_length)) || ((x+i == x) && (y+j == y)))
                continue;

            if (mines_array[x+i][y+j])
                count++;
        }
    }
    return count;
}

Zobrazenie voľných polí

Rekurzívne prejde okolia stlačeného tlačidla a ak je hodnota v min v jeho okolí rovná nule, skontroluje okolie jeho okolitých tlačidiel a postupuje rovnakým spôsobom.

// pokud je počet min daného tlačítka roven 0 projede jeho okolí a odkryje pole s ním spajaté, které také mají počet min v jejich okolí roven 0
public void showFree(int x, int y)
{
    for (int i = -1; i <= 1; i++)
    {
        for (int j = -1; j <= 1; j++)
        {
            // ošetření přetečení
            if (((x+i < 0) || (x+i >= x_length)) || ((y+j < 0) || (y+j >= y_length)) || ((x+i == x) && (y+j == y)))
                continue;

            if ((this.checkMinesAround(x+i, y+j) == 0) && (buttons[x+i][y+j].isEnabled() == true) && (buttons[x+i][y+j].getText() != "?"))
            {
                this.setButton("0", this.getColor(0), x+i, y+j);
                this.showFree(x+i, y+j);
            }
        }
    }
}

Zobrazenie celého poľa

Jednoducho prejdeme celé pole. Všimnite si odstránenie udalosti myši.

// zbrazí pole min (prohra/výhra)
public void showField()
{
    for (int y = 0; y < y_length; y++)
    {
        for (int x = 0; x < x_length; x++)
        {
            if (mines_array[x][y])
                this.setButton("M", Color.red, x, y);
            else
                this.setButton(String.valueOf(this.checkMinesAround(x, y)), this.getColor(this.checkMinesAround(x, y)), x, y);
        }
    }
}

Víťazstvo

Skontroluje počet aktívnych tlačidiel a porovná tento počet z celkovým počtom min. Ak sa zhoduje - zostávajú iba míny.

// po stisku tlačítka se zkontroluje kolik zbývá aktivních polí, pokud je číslo rovno počtu min vrátí true
public boolean checkVictory()
{
    int enabled_buttons = 0;

    for (int y = 0; y < y_length; y++)
    {
        for (int x = 0; x < x_length; x++)
        {
            if (buttons[x][y].isEnabled())
                enabled_buttons++;
        }
    }

    if (enabled_buttons == count_of_mines)
        return true;
    else
        return false;
}

Game maker - zápis

Farba a zobrazenie počtu min

Tieto náležitosti sa vykonávajú v draw eventu.

draw_sprite(sprite_index, -1, x, y);

draw_set_font(font0);

switch (mines_around)
{
    case 0: draw_set_color(c_white); break;
    case 1: draw_set_color(c_blue); break;
    case 2: draw_set_color(c_green); break;
    default: draw_set_color(c_red); break;
}

// vykreslí počet min okolo stisknutého tlačítka
if (sprite_index == spr_clicked)
    draw_text(x - 3, y - 8, mines_around);

Počet min v okolí

Na toto si napíšeme script, ktorý potom budeme volať pomocou script_execute (názov, parametre ...)

Kontrola je mína

Pristúpi k objektu, podľa súradníc a zistí z premennej minie, ktorá sa nastavuje pri vytváraní polí, či je na zadanom mína či nie.

//is mine

if (instance_exists(instance_position(argument0, argument1, obj_button)))
{
    if (instance_position(argument0, argument1, obj_button).mine == true)
    {
        return true;
    }
}

return false;

Počet min v okolí

//check_mines_around

count = 0;

if (script_execute(is_mine, argument0 - sprite_width, argument1)) { count += 1 }
if (script_execute(is_mine, argument0 + sprite_width, argument1)) { count += 1 }

if (script_execute(is_mine, argument0 - sprite_width, argument1 - sprite_height)) { count += 1 }
if (script_execute(is_mine, argument0, argument1 - sprite_height)) { count += 1 }
if (script_execute(is_mine, argument0 + sprite_width, argument1 - sprite_height)) { count += 1 }

if (script_execute(is_mine, argument0 - sprite_width, argument1 + sprite_height)) { count += 1 }
if (script_execute(is_mine, argument0, argument1 + sprite_height)) { count += 1 }
if (script_execute(is_mine, argument0 + sprite_width, argument1 + sprite_height)) { count += 1 }

return count;

V udalosti Room štart v obj_button tento script zavoláme a priradíme tlačidlám koľko majú min v okolí, potom je len zobrazíme v udalosti draw.

// po vytvoření všech tlačítek se nastaví počet min okolo
mines_around = script_execute(check_mines_around, x, y);

Zobrazenie voľných polí

Týmto spôsobom sa prejde okolí tlačidlá - vpravo, vľavo, hore a dole. Rekurzia potom skontroluje zvyšok. V kódu je len kontrola pravého suseda.

// show_free
if (script_execute(check_mines_around, argument0 + sprite_get_width(spr_button), argument1) == 0)
{
    with (instance_position(argument0 + sprite_get_width(spr_button), argument1, obj_button))
    {
        if (sprite_index != spr_clicked)
        {
            sprite_index = spr_clicked;
            script_execute(show_free, argument0 + sprite_get_width(spr_button), argument1);
        }
    }
}

Zobrazenie celého poľa

Jednoducho prejdeme celé pole. Všimnite si fce screen_redraw, pokiaľ ju nepoužijete, potom sa pri show_message nepřekreslí obrazovka a vy neuvidíte ono poľa.

// show_all
for (i = 1; i < instance_count; i += 1)
{
    with (instance_id[i])
    {
        if (mine == true)
            sprite_index = spr_mine;
        else
            sprite_index = spr_clicked;
    }
}

// překreslí se
screen_redraw();

Víťazstvo

Skontroluje počet inštancií, ktoré nemajú sprite rovný spr_clicked -> teda aktívny a porovná tento počet z celkovým počtom min. Ak sa zhoduje - zostávajú iba míny.

// check_victory
clicked = 0;

for (i = 1; i < instance_count - 1; i += 1)
{
    if (instance_id[i].sprite_index != spr_clicked) { clicked += 1 }
}

if (clicked == obj_controler.mines_count)
    return true;

return false;

Pokračovanie> Zaujímavosti a poznámky


 

Článok pre vás napísal David Jančík
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor je vášnivý programátor. Nezná slovo "nelze", nebojí se zkoušet nepoznané a pronikat do nových technologií.
Aktivity