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