Hru Hledání min, jejíž zpracování pro WPF, jsem popsal nedávno, jsem z jinou skupinou vytvořil znovu, tentokrát jako konzolovou aplikaci.
Oproti WPF nelze používat myš a souřadnice pro odkrytí pole se musí zadávat z klávesnice. Grafika také není zrovna ohromující, ale hrát se to dá...
Základní algoritmy zůstávají stejné. Většina jich byla popsána již v předchozím článku o WPF verzi, takže zde již pouze uvedu celý kód aplikace. Rozdíly budou popsány v komentářích.
class Program { static Random random = new Random(); static void Main(string[] args) { int n = 10, m = 10; // Rozměry minového pole (N = řádky, M = sloupce) int pocetMin = 10; // Počet min // 0 - nic, 1-8 číslo, 9 - mina, záporná verze čísla (pro 0 je -10) = odkryté pole int[,] miny = new int[n, m]; // Deklarace pole // Rozmístění min a očíslování okolních polí for (int k = 0; k < pocetMin; k++) { int i = random.Next(n); // Náhodný řádek int j = random.Next(m); // Náhodný sloupec while (miny[i, j] == 9) // Je-li tam již jiná mina, vybrat jiné souřadnice { i = random.Next(n); j = random.Next(m); } miny[i, j] = 9; // Umístění miny (9) // Zvýšit číslo v sousedících polích o +1 for (int y = -1; y <= 1; y++) // projít od pole o 1 vlevo do o 1 vpravo for (int x = -1; x <= 1; x++) // a také pro o 1 řádek nad až po 1 řádek pod if (i + y >= 0 && x + j >= 0 && // nepřekročili-li se levé hranice plochy i + y < n && j + x < m && // ani pravé hranice plochy miny[i + y, j + x] != 9) // a ani miny včetně té právě položené neměnit miny[i + y, j + x]++; // zvýšit číslo v této buňce o +1 } VypisMinovePole(miny); short konec = 0; // -1 = prohra, +1 = výhra, 0 = hra pokračuje while (konec == 0) // Herní smyčka { int x = -1, y = -1; bool platneSouradnice = false; // Přáznak, byly-li zadány platné souřadnice while (!platneSouradnice) // Opakování dokud nejsou zadány platné souřadnice try { Console.Write("X: "); x = Convert.ToInt32(Console.ReadLine()); // X (index sloupce) Console.Write("Y: "); y = Convert.ToInt32(Console.ReadLine()); // Y (index řádku) Console.WriteLine(); if (x >= 0 && x < m && y >= 0 && y < n) // Ověření, jsou-li souřadnice v rozsahu pole if (miny[y, x] >= 0) // Ověření, není-li na souřadnicích již odkryté pole platneSouradnice = true; else Console.WriteLine("Pole na zadaných souřadnicích je již odkryto..."); else Console.WriteLine("Byly zadány souřadnice mimo rozsah pole..."); } catch { Console.WriteLine("Souřadnice musí být platné celé číslo..."); // Zadáno neplatné číslo } // Odkrývání pole podle typu if (miny[y, x] == 9) // Mina = konec hry (prohra) a odkrytí všech polí { for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (miny[i, j] >= 1 && miny[i, j] <= 9) miny[i, j] *= -1; // Odkrytí neprázdného pole else if (miny[i, j] == 0) miny[i, j] = -10; // Odkrytí prázdného pole konec = -1; // Konec hry prohrou } else if (miny[y, x] >= 0) // Prázdné pole či pole s číslem odkryje metoda Odkryj Odkryj(y, x, miny); VypisMinovePole(miny); // Vypsání nové podoby herní plochy // Ověření konce výhrou (jsou-li odkryta všechna pole kromě min) if (konec == 0) if (JeVseOdkryto(miny)) konec = 1; } // Konec herní smyčky // Oznámení výhry či prohry if (konec < 0) Console.WriteLine("Prohrál jsi!"); else Console.WriteLine("Vyhrál jsi!"); Console.ReadLine(); } // Kontrola, jsou-li již všechna pole (kromě min) odkryta nebo ne static bool JeVseOdkryto(int[,] miny) { for (int i = 0; i < miny.GetLength(0); i++) for (int j = 0; j < miny.GetLength(1); j++) if (miny[i, j] >= 0 && miny[i, j] != 9) return false; return true; } // Odkryje pole na zadaných souřadnicích a všechny jeho sousedy static void Odkryj(int i, int j, int[,] miny) { if (j >= 0 && i >= 0 && j < miny.GetLength(1) && i < miny.GetLength(0)) // Jsou-li zadané souřadnice v ploše minového pole if (miny[i, j] == 0) // a je-li v daném poli prázdno a není dosud odkryto { miny[i, j] = -10; // Odkrytí pole // Odkrytí i všech sousedních polí rekurzivním voláním, jež odkryje i jejich sousední pole for (int x = -1; x <= 1; x++) // Projít od pole o 1 vlevo do o 1 vpravo for (int y = -1; y <= 1; y++) // a také pro o 1 řádek nad až po 1 řádek pod Odkryj(i + y, j + x, miny); // toto pole odkrýt } else if (miny[i, j] > 0 && miny[i, j] < 9) // Není-li pole prázdné, odkrýt jej ale jeho sousedy již ne miny[i, j] *= -1; // Odkrytí pole - nastavit mu jeho zápornou hodnotu } // Vypíše aktuální stav minového pole do konzolového výstupu static void VypisMinovePole(int[,] miny) { // Vypsání záhlaví sloupců int sirkaZnaku = miny.GetLength(1) > 10 ? 2 : 1; // Je-li počet sloupců dvojciferné číslo, přidá mezeru před ta jednociferná Console.Write(" | "); for (int j = 0; j < miny.GetLength(1); j++) Console.Write("{0} ", j.ToString().PadLeft(sirkaZnaku)); Console.WriteLine(); Console.WriteLine("---+-".PadRight(miny.GetLength(1) * (sirkaZnaku + 1)+4, '-')); // Vypsání řádků for (int i = 0; i < miny.GetLength(0); i++) { // Vypsání sloupce s číslem řádku Console.Write("{0} |", i.ToString().PadLeft(2)); if (sirkaZnaku > 1) Console.Write(" "); // Vypsání minového pole for (int j = 0; j < miny.GetLength(1); j++) { Console.Write(" "); if (miny[i, j] >= 0) // Neodkryté pole VypisZnakSBarvou('#', ConsoleColor.Black); else if (miny[i, j] == -10) // Prázdné odkryté pole VypisZnakSBarvou('0', ConsoleColor.DarkGray); else if (miny[i, j] == -9) // Odkrytá mina VypisZnakSBarvou('X', ConsoleColor.Red); else // Odkryté pole s číslem VypisZnakSBarvou((-miny[i, j]).ToString()[0], ConsoleColor.DarkCyan); if (sirkaZnaku > 1) Console.Write(" "); } Console.WriteLine(); } Console.WriteLine(); } // Vypíše do konzole jeden znak podbarvený zadanou barvou static void VypisZnakSBarvou(char znak, ConsoleColor barva) { Console.BackgroundColor = barva; // Nastavení barvy pozadí Console.Write(znak); // Vypsání znaku Console.BackgroundColor = ConsoleColor.Black; // Vrácení barvy pozadí na černou } }