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
}
}