Uss/Madu Mäng

🐍 Käesoleva projekti eesmärgiks oli luua klassikaline arkaadmäng “Ussimäng” (inglise keeles Snake), kasutades C# programmeerimiskeelt ja objekti-orienteeritud programmeerimise (OOP) printsiipe. Projekt on teostatud käsurearakendusena Console Application ning selle fookuses on puhas koodiarhitektuur, dünaamiliste andmestruktuuride haldamine ja andmete püsiv salvestamine.

🛠️ Mängu peamised funktsioonid

Interaktiivne menüü: Liigu valikute vahel mugavalt klaviatuuri nooleklahvidega. Ei mingit üleliigset hiirega klikkimist – puhas nooleklahvide funktsionaalsus.

  • Kolm raskusastet (Kiirust): * Kerge – Ideaalne harjutamiseks ja soojenduseks.
    • Keskmine – Tasakaalustatud tempo kogenud mängijatele.
    • Raske – Tõeline väljakutse neile, kellel on välkkiired refleksid!
  • Nutikas liikumisloogika: Ussile on programmeeritud 180-kraadise pöörde keeld. See tähendab, et sa ei saa kogemata otse tagasi liikuda ja end silmapilkselt vigastad
    • Keskmine – Tasakaalustatud tempo kogenud mängijtele.
      Raske – Tõeline väljakutse neile, kellel on välkkiired refleksid!

Kohalik edetabel (TOP 5): Sinu parimad tulemused ei kao kuhugi! Mäng salvestab automaatselt mängija nime, skoori ja valitud raskusastme eraldi faili (leaders.txt) ning kuvab peamenüüs viis kõige kõvemat rekordit.

💻 Tehniline tagatugi (Koodi arhitektuur)

See projekt pole lihtsalt mäng, vaid suurepärane näide puhtast ja organiseeritud objektorienteeritud programmeerimisest (OOP). Kood on jaotatud loogilisteks klassideks:

  • Program – Mängu käivitaja ja sisenemispunkt.
  • Mäng – Kogu mängumootor, mis juhib menüüd, raskusastmeid, skoorisüsteemi ja failide salvestamist.
  • Uss – Haldab ussi keha dünaamilist nimekirja ($List$), liikumise algoritme (“loo uus pea, kustuta vana saba”) ja enese hammustamise kontrolli.
  • Toit – Genereerib juhuslikesse koordinaatidesse uut toitu, jälgides mänguvälja piire.
  • Punkt – Alusstruktuur $X$- ja $Y$-koordinaatide ning sümbolite joonistamiseks ja kustutamiseks.

🕹️ Kuidas mängida?

  1. Käivita programm.
  2. Vali peamenüüst “Alusta mängu”.
  3. Vali endale sobiv raskusaste.
  4. Kasuta ussi juhtimiseks klaviatuuri nooleklahve (Üles, Alla, Vasakule, Paremale).
  5. Söö võimalikult palju toitu, kasvata skoori ja pane oma nimi edetabelisse!

Uuenduslikkust:

1. Arhitektuur ja interaktiivne menüü (Klass Mäng)

  • Baasülesandes: Kogu loogika asus otse failis Program.cs meetodis Main(). Mäng käivitus konsooli avamisel kohe ja sulgus seina tabamisel.
  • Mis lisati: Kogu mängu loogika tõsteti eraldi klassi Mäng. Lisati ilus nooleklahvidega juhitav algmenüü (“Alusta mängu”, “Edetabel”, “Välju”), kus aktiivne valik on visuaalselt esile tõstetud.

Program.cs praegu:

using System;

class Program
{
    static void Main()
    {
        Console.CursorVisible = false;
        Console.Title = "Madu / Ussimäng Pro";

        Mäng mänguhaldur = new Mäng();

        while (true)
        {
            int valik = mänguhaldur.NäitaInteraktiivneMenüü();

            if (valik == 0)
            {
                mänguhaldur.Mängi();
            }
            else if (valik == 1)
            {
                mänguhaldur.Edetabel();
            }
            else if (valik == 2)
            {
                break;
            }
        }
    }
}

2. Raskusastmed ja kiiruse muutmine

  • Baasülesandes: Mängu kiirus oli koodis jäigalt paika pandud ühe numbriga — Thread.Sleep(150).
  • Mis lisati: Realiseeriti raskusastme valiku alammenüü (Kerge, Keskmine, Raske). Sõltuvalt valikust muutub mängutsükli viivitus (näiteks 180 ms, 110 ms või 60 ms), muutes ussi liikumise kas aeglasemaks või kiiremaks.
   public void ValiRaskusaste()
    {
        int valitudIndeks = 0;
        string[] raskusastmed = { "Lihtne", "Keskmine", "Raske" };
        int[] kiirused = { 180, 110, 60 };

3. Punktisüsteem ja andmete salvestamine faili (Edetabel)

  • Baasülesandes: Kaotuse korral kuvati lihtsalt tekst “MÄNG LÄBI!” ja programm lõpetas töö. Mingit punktide arvestust ei olnud.
  • Mis lisati: * Loodi muutuja skoor, mis kasvab iga söödud toiduga 10 punkti võrra ja kuvatakse ekraanil reaalajas.
    • Mängu lõppedes küsib programm mängija nime ning salvestab tulemuse (nimi, skoor ja raskusaste) tekstifaili (leaders.txt).
    • Lisati TOP 5 edetabeli ekraan, mis loeb failist andmeid, sorteerib need LINQ käsu (OrderByDescending) abil kahanevasse järjekorda ja näitab parimaid mängijaid.
var ridad = File.ReadAllLines(FailiNimi);
            var edetabel = new List<KeyValuePair<string, int>>();

            foreach (var rida in ridad)
            {
                var osad = rida.Split(';');
                if (osad.Length == 2 && int.TryParse(osad[1], out int ojad))
                {
                    edetabel.Add(new KeyValuePair<string, int>(osad[0], ojad));
                }
            }

            var top5 = edetabel.OrderByDescending(x => x.Value).Take(5).ToList();

            for (int i = 0; i < top5.Count; i++)
            {
                Console.WriteLine($"{i + 1}. {top5[i].Key} — {top5[i].Value} punkti");
            }
        }

4. Nähtavad seinad ja raam (Kaart / JoonistaRaam)

  • Baasülesandes: Seina tabamist kontrolliti puhtalt matemaatiliselt — vaadati, kas pea koordinaadid läksid aknast välja (pea.X <= 0). Ekraanil endal mingeid seinu näha ei olnud.
  • Mis lisati: Lisati füüsilise raami joonistamise funktsioon. Mänguvälja piirid joonistatakse tumehallide # sümbolitega, et mängija näeks visuaalselt ala, millest välja ei tohi roomata.
   public void JoonistaRaam()
    {
        Console.ForegroundColor = ConsoleColor.DarkGray;
        for (int x = 0; x < laius; x++)
        {
            new Punkt(x, 0, '#').Joonista();
            new Punkt(x, kõrgus - 1, '#').Joonista();
        }
        for (int y = 0; y < kõrgus; y++)
        {
            new Punkt(0, y, '#').Joonista();
            new Punkt(laius - 1, y, '#').Joonista();
        }
        Console.ResetColor();
    }