ebSkola

4.2 Dictionary un Godot Dictionary

Stundas uzdevums: Apgūt asociatīvās datu struktūras inventāram un konfigurācijai.

SR 2.4.16. Saliktas datu struktūras SR 2.4.4. Iegūst un apstrādā datus

80 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~20 min) - izveido inventāru ar Dictionary · 2. uzdevums (~25 min) - pievieno drošu meklēšanu · 3. uzdevums (~20 min) - salīdzini C# un Godot vārdnīcas · Iesniegšana (~5 min).

Pirms sāc: atceries no Programmēšanas I vārdnīcas: inventars["zobens"] = 1. C# tam lieto Dictionary<TKey, TValue>, bet Godot pusē - Godot.Collections.Dictionary.

Teorija: Dictionary un Godot Dictionary

Asociatīvā datu struktūra glabā atslēga → vērtība pārus.

using Godot;
using Godot.Collections;
using System.Collections.Generic;

// Dictionary<TKey, TValue> - ātra meklēšana pēc atslēgas
Dictionary<string, int> inventory = new();
inventory["Health Potion"] = 5;
inventory["Mana Potion"] = 3;

if (inventory.TryGetValue("Health Potion", out int amount))
{
    GD.Print(amount);
}

// Dictionary ar objektiem pēc ID
Dictionary<int, Enemy> enemyById = new();

// Godot Dictionary - der saziņai ar editoru un JSON saglabāšanai
Godot.Collections.Dictionary inv = new();
inv["coins"] = 100;
inv["arrows"] = 25;
if (inv.ContainsKey("coins")) GD.Print(inv["coins"]);

Kā šo izmantot projektā

Atceries: ar redzamu efektu editorā nepietiek. Paskaidro, kura C# klase glabā stāvokli, kura metode to maina un kā Godot node struktūra izmanto šo kodu.

Pārbaudi: C# kodā pamatoti izvēlēti List, Dictionary vai HashSet, AI stāvokļi ir skaidri, un sarežģītākas sistēmas var profilēt vai atkļūdot.

public class AiDataCheckpoint
{
    public string Lesson = "4.2 Dictionary un Godot Dictionary";
    public bool UsesCSharp = true;
    public bool ChoosesContainer = true;
    public bool SeparatesAiState = true;
    public bool HandlesRemovalSafely = true;
}

Praktiskie uzdevumi

1. uzdevums -

Izveido inventāru ar Dictionary

Beigās priekšmetus varēs atrast pēc nosaukuma, nevis pēc numura.

  1. Pievieno faila sākumā using System.Collections.Generic;.
  2. Izveido Dictionary<string, int> inventory = new();.
  3. Pievieno inventory["Health Potion"] = 5;.
  4. Pievieno vēl divus priekšmetus ar dažādiem daudzumiem.
  5. Izdrukā viena priekšmeta daudzumu pēc nosaukuma.
  6. Uzraksti ciklu foreach (var pair in inventory) { ... }, kas izdrukā visu.
  7. Pieraksti, kāpēc uz izdrukas secību nevajag paļauties.

Gatavs, kad: izdrukā redzami visi trīs priekšmeti, un tu vari paskaidrot, ka Dictionary ir paredzēts ātrai meklēšanai pēc atslēgas.

2. uzdevums -

Pievieno drošu meklēšanu

Beigās neesoša priekšmeta pieprasījums vairs neradīs pārsteigumus.

  1. Izdrukā inventory["Nav taada"] un pieraksti kļūdas ziņojumu.
  2. Izdrukā pēc tam inventory.Count un pieraksti, vai tas mainījās.
  3. Pieraksti, kāpēc tieša kvadrātiekavu lietošana bez pārbaudes ir bīstama.
  4. Nomaini pārbaudi uz if (inventory.TryGetValue("Health Potion", out int amount)) { ... }.
  5. Uzraksti metodi int GetAmount(string name), kas atgriež 0, ja priekšmeta nav.
  6. Izsauc to ar esošu un neesošu nosaukumu.
  7. Pārbaudi, ka vārdnīcas izmērs vairs nemainās.

Gatavs, kad: neesoša atslēga vairs neaptur programmu, bet tava metode korekti atgriež 0.

3. uzdevums -

Salīdzini Dictionary ar Godot Dictionary

Beigās tu zināsi, kuru struktūru lietot saziņai ar Godot.

  1. Izveido Godot.Collections.Dictionary saveData = new();.
  2. Pievieno tam saveData["player_name"] = "Anna"; un saveData["level"] = 5;.
  3. Izdrukā abas vērtības.
  4. Pieraksti, vai Godot.Collections.Dictionary pieļauj dažādu tipu vērtības vienā struktūrā.
  5. Mēģini līdzīgus datus ielikt Dictionary<string, int> un izlasi kļūdu.
  6. Pieraksti, kura struktūra derēs saglabāšanai failā.
  7. Izvēlies savam inventāram pareizo variantu un pamato.

Gatavs, kad: Godot.Collections.Dictionary pieņem dažādus tipus vienā struktūrā, bet Dictionary<string, int> prasa vienu vērtības tipu.

Papildu uzdevums - Izmēģini SortedDictionary

Ja pamatdarbs ir gatavs, salīdzini ātru meklēšanu ar sakārtotu izdruku.

  1. Izveido to pašu inventāru ar SortedDictionary<string, int>.
  2. Izdrukā to ciklā un salīdzini secību ar Dictionary<string, int>.
  3. Pieraksti, kura struktūra izdrukā atslēgas sakārtoti.
  4. Pieraksti, kura struktūra parasti ir piemērotāka vienkāršai ātrai meklēšanai.

Gatavs, kad: SortedDictionary izdrukā atslēgas alfabētiski, bet parastais Dictionary tiek lietots ikdienas ātrai piekļuvei.

Ko sagatavo

Stundas mērķis: Tu proti C# izveidot Dictionary inventāru, droši meklēt tajā priekšmetus un izskaidrot, kad jālieto Godot Dictionary.

GitHub krātuvē jābūt:

  1. C# fails ar inventāru un GetAmount metodi.
  2. Ekrānuzņēmums, kurā redzams, ka pēc neesoša priekšmeta pieprasījuma vārdnīcas izmērs nemainās.
  3. README.md: kāpēc kvadrātiekavas ar neesošu atslēgu ir bīstamas un kad lieto Godot.Collections.Dictionary.

Kā iesniedz: Veic commit un push. Skolotāja norādītajā vietā ievieto tikai GitHub krātuves saiti; visiem prasītajiem failiem, README.md pierakstiem un pierādījumiem jābūt pašā krātuvē.

Biežākās kļūdas

  • KeyNotFoundException: Kvadrātiekavas lasa tikai esošas atslēgas. Lieto TryGetValue vai ContainsKey.
  • Sajauktas vārdnīcas: Dictionary<string, int> ir tipa-droša C# struktūra, bet Godot.Collections.Dictionary glabā Variant datus.
  • Negaidīta secība: parasts Dictionary nav paredzēts sakārtotai izdrukai. Ja vajag sakārtotas atslēgas, lieto SortedDictionary.

Godot ekrānuzņēmumi

Spēles inventāra UI: 4×4 grid ar ikonām, blakus skaitļi (5x Health Potion, 3x Mana Potion, 1x Sword).
Spēles inventāra UI: 4×4 grid ar ikonām, blakus skaitļi (5x Health Potion, 3x Mana Potion, 1x Sword).

Koda piemērs (paplašināts)

using Godot;
using System.Collections.Generic;

public class PlayerInventory
{
    private readonly Dictionary<string, int> inventory = new();

    public void AddItem(string name, int amount = 1)
    {
        inventory.TryGetValue(name, out int current);
        inventory[name] = current + amount;
        GD.Print("+", amount, " ", name);
    }

    public bool UseItem(string name)
    {
        if (!inventory.TryGetValue(name, out int count) || count <= 0)
        {
            GD.Print("Nav ", name);
            return false;
        }

        inventory[name] = count - 1;
        return true;
    }

    public void PrintInventory()
    {
        foreach ((string name, int count) in inventory)
        {
            GD.Print(name, ": ", count);
        }
    }
}
Inventārs rāda: Health Potion: 5, Mana Potion: 3, Sword: 1; pēc lietošanas Health Potion: 4.