3.5 Statistikas sistēma un struct
Stundas uzdevums: Izmantot struct datu grupēšanai un kompozīciju (composition) klašu organizēšanai.
80 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~20 min) - izveido struct statistikai · 2. uzdevums (~25 min) - ieliec struct klasē un pievieno metodes · 3. uzdevums (~20 min) - pievieno pagaidu bonusus sarakstā · Iesniegšana (~5 min).
Pirms sāc: atver savu dalībnieku klasi. Šodien sakārtosi tās laukus: tā vietā, lai klasē būtu desmit atsevišķi skaitļi, tie visi dzīvos vienā struct.
Teorija: struct un kompozīcija
struct ir vienkāršāka klase - visi lauki ir public pēc noklusējuma. Lietojama datu grupēšanai.
using System;
public struct Stats
{
public int Energy;
public int MaxEnergy;
public int Focus;
public int Calm;
public int Speed;
public Stats(int energy = 100, int focus = 10, int calm = 5, int speed = 5)
{
Energy = energy;
MaxEnergy = energy;
Focus = focus;
Calm = calm;
Speed = speed;
}
public void Heal(int amount)
{
Energy = Math.Min(MaxEnergy, Energy + amount);
}
}
public class Participant
{
private Stats stats = new Stats(); // kompozīcija!
private string name;
public Participant(string name)
{
this.name = name;
}
public ref Stats GetStats() => ref stats; // atgriež references
}
Kompozīcija (klase satur citu klasi) bieži ir labāka par mantošanu - fleksiblāka un mazāk saistīta.
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: katrai būtiskai turnīra lomai ir C# klase vienā .cs failā, ar konstruktoriem, metodēm, signāliem vai mantošanu.
public class OopCheckpoint
{
public string Lesson = "3.5 Statistikas sistēma un struct";
public bool UsesCSharp = true;
public bool HasScriptFile = true;
public bool HasSingleResponsibility = true;
public bool UsesGodotInspector = true;
}
Praktiskie uzdevumi
1. uzdevums -
Izveido struct statistikai
Beigās visi dalībnieka skaitļi būs vienuviet.
- Uzraksti failā
Stats.cspublic struct Stats {. - Pievieno laukus
public int Energy;unpublic int MaxEnergy;. - Pievieno arī
public int Focus;,public int Calm;unpublic int Speed;. - Ievēro, ka C#
structlaukiem jārakstapublic, ja tos vajag lietot ārpus struktūras. - Izveido objektu
Stats s = new Stats();un izdrukā visus laukus. - Nomaini vienu lauku un izdrukā vēlreiz.
- Pieraksti, ar ko
structatšķiras noclass.
Gatavs, kad: izdrukā redzamas visas noklusējuma vērtības, un tu vari nosaukt atšķirību no class.
2. uzdevums -
Ieliec struct klasē un pievieno metodes
Beigās klase glabās statistiku vienā laukā, nevis piecos.
- Pievieno
Participantklasei privātu laukuprivate Stats stats = new Stats();. - Izdzēs vecos atsevišķos skaitļu laukus.
- Pievieno
Statsstruktūrai metodipublic void Heal(int amount). - Ieraksti tajā
Energy = Math.Min(MaxEnergy, Energy + amount);. - Pievieno klasei publisku metodi
public ref Stats GetStats() => ref stats;. - Izsauc
p.GetStats().Heal(30);un izdrukā enerģiju. - Pārbaudi, ka enerģija nepārsniedz maksimumu.
Gatavs, kad: pēc lielas dziedināšanas enerģija apstājas tieši uz max_energy, nevis to pārsniedz.
3. uzdevums -
Pievieno pagaidu bonusus sarakstā
Beigās dalībniekam varēs uzlikt bonusus, kas summējas.
- Izveido
public struct Buff { public string Name; public int FocusBonus; }. - Pievieno
Statsklasei laukupublic List<Buff> Buffs = new();. - Uzraksti metodi
public int GetTotalFocus(). - Saskaiti tajā ciklā pamata
Focusplus visu bonusu summu. - Pievieno divus bonusus un izdrukā kopējo fokusu.
- Izdzēs vienu bonusu un izdrukā vēlreiz.
- Pieraksti, kāpēc kopējo vērtību labāk rēķināt, nevis glabāt atsevišķā laukā.
Gatavs, kad: kopējais fokuss mainās, pievienojot un noņemot bonusus, un vienmēr sakrīt ar summu.
Papildu uzdevums - Pievieno bonusiem ilgumu
Ja pamatdarbs ir gatavs, liec bonusiem beigties pēc dažām kārtām.
- Pievieno
Buffstruktūrai laukupublic int TurnsLeft;. - Uzraksti metodi, kas samazina visiem bonusiem
TurnsLeftpar vienu. - Izdzēs no saraksta tos, kuriem tas sasniedzis nulli.
- Izsauc šo metodi trīs reizes pēc kārtas.
- Izdrukā pēc katras reizes kopējo fokusu.
Gatavs, kad: bonusi pazūd paši pēc norādītā kārtu skaita, un fokuss atgriežas sākuma vērtībā.
Ko sagatavo
Stundas mērķis: Tu proti izveidot struct datu grupēšanai, ielikt to klasē kā lauku (kompozīcija) un rēķināt kopējo vērtību no saraksta, nevis glabāt to atsevišķi.
GitHub krātuvē jābūt:
- Faili
Stats.csun atjauninātaisParticipant.cs. - Ekrānuzņēmums ar Output paneli, kurā redzams kopējais fokuss pirms un pēc bonusa noņemšanas.
- README.md: ar ko
structatšķiras noclassun kāpēc kopējo fokusu labāk rēķināt.
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
- Stats noklusējuma vērtības neuzstādās: C# struct bez konstruktora dod 0 vērtības. Inicializē ar konstruktoru.
- List iteration kļūda: nemaini
List<Buff>tajā pašāforeach; lietoforvaiRemoveAll. - Slow buff lookup: lielam bonusu skaitam lieto
Dictionary<string, Buff>vai atsevišķu indeksu.
Godot ekrānuzņēmumi
Koda piemērs (paplašināts)
using System;
using System.Collections.Generic;
public struct Buff
{
public string Target;
public int Amount;
public float Duration;
}
public class Stats
{
public int Energy = 100;
public int MaxEnergy = 100;
public int Focus = 10;
public int Calm = 5;
public int Speed = 5;
public List<Buff> Buffs = new();
public int GetTotalFocus()
{
int total = Focus;
foreach (Buff buff in Buffs)
{
if (buff.Target == "focus") total += buff.Amount;
}
return total;
}
public void ApplyPenalty(int amount)
{
int actual = Math.Max(1, amount - Calm);
Energy = Math.Max(0, Energy - actual);
}
public void Update(float delta)
{
for (int i = 0; i < Buffs.Count; i++)
{
Buff buff = Buffs[i];
buff.Duration -= delta;
Buffs[i] = buff;
}
Buffs.RemoveAll(buff => buff.Duration <= 0);
}
}