Add project files.

This commit is contained in:
Sandor Szenasi
2024-09-05 19:47:35 +02:00
parent 0bf4c5bd60
commit 78859a5b2b
32 changed files with 2927 additions and 0 deletions

91
Engine/AlapTipusok.cs Normal file
View File

@@ -0,0 +1,91 @@
namespace OE.ALGA.Engine
{
public class KetElemuVektor : IComparable
{
readonly int x;
readonly int y;
public int X { get { return x; } }
public int Y { get { return y; } }
public KetElemuVektor(int x, int y)
{
this.x = x;
this.y = y;
}
public override bool Equals(object? obj)
{
if (obj != null && obj is KetElemuVektor b)
{
return X == b.X && Y == b.Y;
}
return false;
}
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
public int CompareTo(object? obj)
{
if (obj != null && obj is KetElemuVektor b)
{
if (x != b.x)
return x.CompareTo(b.x);
else
return y.CompareTo(b.y);
}
throw new InvalidOperationException();
}
public static bool operator ==(KetElemuVektor a, KetElemuVektor b) => a.Equals(b);
public static bool operator !=(KetElemuVektor a, KetElemuVektor b) => !a.Equals(b);
}
public class Pozicio : KetElemuVektor
{
public Pozicio(int x, int y) : base(x, y)
{
}
public static Pozicio operator +(Pozicio p, Irany m) => new Pozicio(p.X + m.X, p.Y + m.Y);
public static double Tavolsag(Pozicio a, Pozicio b) => Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2));
}
public class Irany : KetElemuVektor
{
public static readonly Irany[] FoIranyok = new Irany[4] { new Irany(0, -1), new Irany(-1, 0), new Irany(0, 1), new Irany(1, 0) };
public static int Balra(int iranyIndex)
{
return (iranyIndex - 1 + 4) % 4;
}
public static int Jobbra(int iranyIndex)
{
return (iranyIndex + 1) % 4;
}
public Irany(int x, int y) : base(x, y)
{
}
public static Irany operator *(Irany i, int s) => new Irany(i.X * s, i.Y * s);
}
public class Meret
{
public int Szelesseg { get; set; }
public int Magassag { get; set; }
public Meret(int szelesseg, int magassag)
{
this.Szelesseg = szelesseg;
this.Magassag = magassag;
}
}
}

31
Engine/Backend.cs Normal file
View File

@@ -0,0 +1,31 @@
namespace OE.ALGA.Engine
{
public class Backend
{
public Kepernyo Megjelenites { get; } = new Kepernyo();
public BillentyuzetKezelo Bemenet { get; } = new BillentyuzetKezelo();
public OrajelGenerator Orajel { get; } = new OrajelGenerator();
public Backend()
{
Orajel.OrajelFogadoFelvetele(Bemenet);
Orajel.OrajelFogadoFelvetele(Megjelenites);
}
bool kilepes = false;
public void Start()
{
Orajel.Start();
while (!kilepes)
{
Thread.Sleep(1000);
}
}
public void Stop()
{
Orajel.Stop();
kilepes = true;
}
}
}

View File

@@ -0,0 +1,43 @@
namespace OE.ALGA.Engine
{
public interface IBillentyuLenyomasKezelo
{
void BillentyuLenyomas(ConsoleKey billentyu);
}
public class BillentyuzetKezelo : IOrajelFogado
{
private readonly List<IBillentyuLenyomasKezelo> billentyuLenyomasKezelok = new List<IBillentyuLenyomasKezelo>();
public void BillentyuLenyomasKezeloFelvetele(IBillentyuLenyomasKezelo kezelo)
{
billentyuLenyomasKezelok.Add(kezelo);
}
public void BillentyuLenyomasKezeloEltavolitasa(IBillentyuLenyomasKezelo kezelo)
{
billentyuLenyomasKezelok.Remove(kezelo);
}
private readonly Dictionary<ConsoleKey, Action> billentyuAkciok = new Dictionary<ConsoleKey, Action>();
public void BillentyuAkcioFelvetele(ConsoleKey billentyu, Action akcio)
{
billentyuAkciok.Add(billentyu, akcio);
}
public void Orajel(int ido)
{
while (Console.KeyAvailable)
{
ConsoleKey billentyu = Console.ReadKey(true).Key;
foreach (IBillentyuLenyomasKezelo kezelo in billentyuLenyomasKezelok)
{
kezelo.BillentyuLenyomas(billentyu);
}
if (billentyuAkciok.TryGetValue(billentyu, out Action? value))
value();
}
}
}
}

10
Engine/Engine.csproj Normal file
View File

@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>OE.ALGA.Engine</RootNamespace>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,12 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE0290:Use primary constructor", Justification = "<Pending>", Scope = "module")]
[assembly: SuppressMessage("Style", "IDE0300:Simplify collection initialization", Justification = "<Pending>", Scope = "module")]
[assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "<Pending>", Scope = "module")]
[assembly: SuppressMessage("Style", "IDE0028:Simplify collection initialization", Justification = "<Pending>", Scope = "module")]
[assembly: SuppressMessage("Style", "IDE0305:Simplify collection initialization", Justification = "<Pending>", Scope = "module")]

22
Engine/Kivetelek.cs Normal file
View File

@@ -0,0 +1,22 @@
namespace OE.ALGA.Engine
{
public class UtkozesKivetel : Exception
{
public TerkepElem Forras { get; set; }
public TerkepElem Utkozes { get; set; }
public UtkozesKivetel(TerkepElem forras, TerkepElem utkozes)
{
this.Forras = forras;
this.Utkozes = utkozes;
}
}
public class NemLehetIdeLepniKivetel : UtkozesKivetel
{
public NemLehetIdeLepniKivetel(TerkepElem forras, TerkepElem utkozes) : base(forras, utkozes)
{
}
}
}

209
Engine/KonzolMegjelenito.cs Normal file
View File

@@ -0,0 +1,209 @@
using System.Text;
namespace OE.ALGA.Engine
{
public interface IMegjelenitheto
{
public Pozicio Pozicio { get; }
public Jel Jel { get; }
}
public class FixJel : IMegjelenitheto
{
public Pozicio Pozicio { get; private set; }
public Jel Jel { get; private set; }
public FixJel(Pozicio pozicio, Jel jel)
{
this.Pozicio = pozicio;
this.Jel = jel;
}
public FixJel(IMegjelenitheto eredeti)
{
this.Pozicio = eredeti.Pozicio;
this.Jel = eredeti.Jel;
}
public static FixJel[] SzovegbolJelsor(string szoveg, Pozicio hely, ConsoleColor szin)
{
FixJel[] jelsor = new FixJel[szoveg.Length];
for (int i = 0; i < szoveg.Length; i++)
jelsor[i] = new FixJel(new Pozicio(hely.X + i, hely.Y), new Jel(szoveg[i], szin));
return jelsor;
}
}
public class Jel
{
readonly char karakter;
readonly ConsoleColor szin;
public char Karakter { get { return karakter; } }
public ConsoleColor Szin { get { return szin; } }
public Jel(char karakter, ConsoleColor szin)
{
this.karakter = karakter;
this.szin = szin;
}
public override bool Equals(object? obj)
{
if (obj != null && obj is Jel b)
{
return this.Karakter == b.Karakter && this.Szin == b.Szin;
}
else
return false;
}
public override int GetHashCode()
{
return karakter.GetHashCode() ^ szin.GetHashCode();
}
public static bool operator ==(Jel a, Jel b) => a is not null && a.Equals(b);
public static bool operator !=(Jel a, Jel b) => a is null || !a.Equals(b);
}
public interface INezopont
{
string Fejlec { get; }
Meret Meret { get; }
IMegjelenitheto[] MegjelenitendoElemek();
}
public class Kepernyo : IOrajelFogado
{
readonly Meret meret;
readonly Jel[,] puffer;
readonly Jel[,] utolso;
public Kepernyo(int szelesseg, int magassag)
{
meret = new Meret(szelesseg, magassag);
Console.CursorVisible = false;
Console.OutputEncoding = Encoding.Unicode;
puffer = new Jel[szelesseg, magassag];
utolso = new Jel[szelesseg, magassag];
}
public Kepernyo() : this(Console.WindowWidth, Console.WindowHeight)
{
}
readonly List<Func<string>> HUDmegjelenitok = new List<Func<string>>();
public void HUDAdatFelvetele(Func<string> hudMegjelenito)
{
HUDmegjelenitok.Add(hudMegjelenito);
}
readonly List<INezopont> nezopontok = new List<INezopont>();
public void NezopontFelvetele(INezopont nezopont)
{
nezopontok.Add(nezopont);
}
public void NezopontEltavolitasa(INezopont nezopont)
{
nezopontok.Remove(nezopont);
}
public void Kirajzolas()
{
PufferTorles();
int eltolasX = 0;
foreach (INezopont nezopont in nezopontok)
{
KeretRajzolas(eltolasX, 0, nezopont.Meret, nezopont.Fejlec);
ElemekRajzolasa(eltolasX, 0, nezopont);
eltolasX += nezopont.Meret.Szelesseg + 2;
}
eltolasX = 0;
foreach (Func<string> hudMegjelenito in HUDmegjelenitok)
{
string adat = hudMegjelenito();
for (int i = 0; i < adat.Length; i++)
puffer[eltolasX + i, meret.Magassag - 1] = new Jel(adat[i], ConsoleColor.White);
puffer[eltolasX + adat.Length, meret.Magassag - 1] = new Jel('|', ConsoleColor.Red);
eltolasX += adat.Length + 1;
}
PufferKirajzolas();
}
readonly Jel ures = new Jel(' ', ConsoleColor.Black);
private void PufferTorles()
{
for (int i = 0; i < meret.Szelesseg; i++)
for (int j = 0; j < meret.Magassag; j++)
{
puffer[i, j] = ures;
}
}
private void KeretRajzolas(int eltolasX, int eltolasY, Meret meret, string fejlec)
{
for (int i = 1; i <= meret.Szelesseg; i++)
{
puffer[eltolasX + i, eltolasY] = new Jel('\u2550', ConsoleColor.Gray);
puffer[eltolasX + i, eltolasY + meret.Magassag + 1] = new Jel('\u2550', ConsoleColor.Gray);
}
for (int i = 1; i <= meret.Magassag; i++)
{
puffer[eltolasX, eltolasY + i] = new Jel('\u2551', ConsoleColor.Gray);
puffer[eltolasX + meret.Szelesseg + 1, eltolasY + i] = new Jel('\u2551', ConsoleColor.Gray);
}
puffer[eltolasX, eltolasY] = new Jel('\u2554', ConsoleColor.Gray);
puffer[eltolasX + meret.Szelesseg + 1, eltolasY] = new Jel('\u2557', ConsoleColor.Gray);
puffer[eltolasX, eltolasY + meret.Magassag + 1] = new Jel('\u255a', ConsoleColor.Gray);
puffer[eltolasX + meret.Szelesseg + 1, eltolasY + meret.Magassag + 1] = new Jel('\u255d', ConsoleColor.Gray);
for (int i = 0; i < fejlec.Length; i++)
puffer[eltolasX + 2 + i, eltolasY] = new Jel(fejlec[i], ConsoleColor.Gray);
}
private void ElemekRajzolasa(int eltolasX, int eltolasY, INezopont nezopont)
{
foreach (IMegjelenitheto elem in nezopont.MegjelenitendoElemek())
{
puffer[eltolasX + 1 + elem.Pozicio.X, eltolasY + 1 + elem.Pozicio.Y] = elem.Jel;
}
}
private void PufferKirajzolas()
{
for (int j = 0; j < meret.Magassag; j++)
{
for (int i = 0; i < meret.Szelesseg; i++)
{
if (utolso[i, j] != puffer[i, j])
{
Console.SetCursorPosition(i, j);
Console.ForegroundColor = puffer[i, j].Szin;
Console.Write(puffer[i, j].Karakter);
utolso[i, j] = puffer[i, j];
}
}
}
}
public void Orajel(int ido)
{
Kirajzolas();
}
}
}

54
Engine/OrajelGenerator.cs Normal file
View File

@@ -0,0 +1,54 @@
namespace OE.ALGA.Engine
{
public interface IOrajelFogado
{
void Orajel(int ido);
}
public class OrajelGenerator
{
Timer? timer;
public int Ido { get; private set; } = 0;
public void Start()
{
timer = new Timer(FoCiklus, null, 0, 100);
}
public void Stop()
{
timer?.Change(Timeout.Infinite, Timeout.Infinite);
}
bool foglalt = false;
private void FoCiklus(object? state)
{
if (!foglalt) // ha nem végzett az előző ciklus, akkor kihagyja a következőt
{
foglalt = true;
Ido++;
List<IOrajelFogado> aktivOrajelFogadok = new List<IOrajelFogado>(orajelFogadok); // azért kell a másolat, mert valamelyik órajel kezelés módosíthatja az orajelFogadok listát
foreach (IOrajelFogado fogado in aktivOrajelFogadok)
{
fogado.Orajel(Ido);
}
foglalt = false;
}
}
private readonly List<IOrajelFogado> orajelFogadok = new List<IOrajelFogado>();
public void OrajelFogadoFelvetele(IOrajelFogado fogado)
{
orajelFogadok.Add(fogado);
}
public void OrajelFogadoEltavolitasa(IOrajelFogado fogado)
{
orajelFogadok.Remove(fogado);
}
}
}

43
Engine/Parameterek.cs Normal file
View File

@@ -0,0 +1,43 @@
namespace OE.ALGA.Engine
{
public static class Param
{
public const int TERKEP_SZELESSEG = 15;
public const int TERKEP_MAGASSAG = 19;
public const char NYIL_FEL = '\u02c4';
public const char NYIL_BAL = '\u02c2';
public const char NYIL_LE = '\u02c5';
public const char NYIL_JOBB = '\u02c3';
public const char HALOTT = '+';
public const char FAL = '\u2593';
public const char LOVEDEK_VIZSZINTES = '-';
public const char LOVEDEK_FUGGOLEGES = '-';
public const int JATEKVEGE_IDO = 500;
public const int HIRTELENHALAL_KEZDO_IDO = 100;
public const int HIRTELENHALAL_FOKOZAS_IDO = 10;
public const int HIRTELENHALAL_BUNTETES = 1;
public const int LOVEDEK_MAX_SEBZES = 10;
public const int JATEKOS_LATOTAVOLSAG = 2;
public const int JATEKOS_MEMORIAMERET = 30;
public const int KINCSEK_SZAMA = 5;
public const int KINCSEK_MAX_MERETE = 8;
public const int HATIZSAK_MAX_MERETE = 10;
public const double GEP_VISSZARAK_ESELY = 0.1;
// optimalizalas
public const double MIN_KINCS_TAVOLSAG = 4;
// kupac
public const int LOVEDEKEK_SZAMA = 10;
// szélességi bejárás
public const int TERKEP_BEJARAS_LEPESKORLAT = 30;
}
}

277
Engine/Terkep.cs Normal file
View File

@@ -0,0 +1,277 @@
namespace OE.ALGA.Engine
{
public class Terkep : INezopont
{
readonly Random rnd = new Random();
public string Fejlec { get { return "Térkép"; } }
readonly Meret meret;
public Meret Meret { get { return meret; } }
readonly List<TerkepElem> elemek = new List<TerkepElem>();
public void Felvesz(TerkepElem elem)
{
elemek.Add(elem);
}
public void Eltavolit(TerkepElem elem)
{
elemek.Remove(elem);
}
public bool Mozgat(TerkepElem elem, Irany irany)
{
Pozicio ujPoz = elem.Pozicio + irany;
bool odaLephet = true;
foreach (TerkepElem ottvan in AdottHelyen(ujPoz))
{
ottvan.Utkozes?.Invoke(elem);
elem.Utkozes?.Invoke(ottvan);
}
elem.Athelyez(ujPoz);
return odaLephet;
}
public List<TerkepElem> AdottHelyen(Pozicio pozicio)
{
return elemek.FindAll(x => x.Pozicio == pozicio);
}
public TerkepElem[] Kornyezet(Pozicio pozicio, int tavolsag)
{
List<TerkepElem> elemek = new List<TerkepElem>();
for (int x = -tavolsag; x <= tavolsag; x++)
for (int y = -tavolsag; y <= tavolsag; y++)
elemek.AddRange(AdottHelyen(new Pozicio(pozicio.X + x, pozicio.Y + y)));
return elemek.ToArray();
}
public IMegjelenitheto[] MegjelenitendoElemek()
{
return elemek.ToArray();
}
public Terkep(int szelesseg, int magassag)
{
this.meret = new Meret(szelesseg, magassag);
}
public void LabirintusGeneralas()
{
List<Fal> falak = new List<Fal>();
List<Pozicio> bovitheto = new List<Pozicio>();
// korbe falak letrehozasa
for (int x = 0; x < meret.Szelesseg; x++)
{
falak.Add(new Fal(this, new Pozicio(x, 0)));
falak.Add(new Fal(this, new Pozicio(x, meret.Magassag - 1)));
}
for (int y = 0; y < meret.Magassag; y++)
{
falak.Add(new Fal(this, new Pozicio(0, y)));
falak.Add(new Fal(this, new Pozicio(meret.Szelesseg - 1, y)));
}
falak.Add(new Fal(this, new Pozicio(1, 2)));
// belso szerkezet letrehozasa
Pozicio kezdoPozicio = new Pozicio(2, 2);
falak.Add(new Fal(this, kezdoPozicio));
bovitheto.Add(kezdoPozicio);
int falProba;
do
{
int falRnd = rnd.Next(bovitheto.Count); // melyik falnal probaljon eloszor tovabb boviteni
falProba = 0; // az elso fal valasztas random, de utana szisztematikusan tovabbnezi a mogotte levoket
bool ok = false;
while (falProba < bovitheto.Count && !ok) // ha nem nezte meg at az osszes falat es nem sikerult boviteni
{
Pozicio vizsgalt = bovitheto[(falRnd + falProba) % bovitheto.Count]; // ezt a falat vizsgaljuk
int iranyRnd = rnd.Next(4); // ebbe az iranyba probal eloszor boviteni
int iranyProba = 0; // az elso irany valasztas random, de utana szisztematikusan nezi a tobbi iranyt
while (iranyProba < 4 && !ok) // meg nem nezte azt az osszes iranyt es nem sikerult boviteni
{
Irany irany = Irany.FoIranyok[(iranyRnd + iranyProba) % 4];
Pozicio uj = vizsgalt + irany * 2;
if (TerkepenBelulVan(uj) && !falak.Exists(x => x.Pozicio == uj)) // ha itt nincs meg fal
{
falak.Add(new Fal(this, uj)); // uj 2. tavolsagra levo fal letrehozasa, ebbol indulhat bovites is
falak.Add(new Fal(this, vizsgalt + irany)); // uj koztes fal letrehozasa
bovitheto.Add(uj);
ok = true; // sikerult boviteni
}
iranyProba++; // uj iranyt probalunk
}
falProba++; // uj falat probalunk
}
} while (falProba < bovitheto.Count); // minden fal minden iranyt vegigneztunk es nincs bovites
}
public bool TerkepenBelulVan(Pozicio pozicio)
{
return pozicio.X > 0 && pozicio.X < meret.Szelesseg - 1 && pozicio.Y > 0 && pozicio.Y < meret.Magassag - 1;
}
public bool NincsFal(Pozicio pozicio)
{
return !AdottHelyen(pozicio).Exists(x => x is Fal);
}
}
abstract public class TerkepElem : IMegjelenitheto, IComparable
{
readonly private Terkep terkep;
public Terkep Terkep { get { return terkep; } }
protected Pozicio pozicio;
public Pozicio Pozicio { get { return pozicio; } }
abstract public Jel Jel { get; }
public Action<TerkepElem>? Utkozes { get; set; }
public virtual void Athelyez(Pozicio ujPozicio)
{
if (terkep.TerkepenBelulVan(ujPozicio))
pozicio = ujPozicio;
}
protected TerkepElem(Terkep terkep, Pozicio pozicio)
{
this.terkep = terkep;
terkep.Felvesz(this);
this.pozicio = pozicio;
}
public virtual void Megszunik()
{
terkep.Eltavolit(this);
}
static int idSzamlalo = 0;
readonly int id = idSzamlalo++;
public int CompareTo(object? obj)
{
if (obj is TerkepElem o)
return id.CompareTo(o.id);
else
throw new ArgumentException("Hibás összehasonlítás");
}
}
public class FixTerkepElem : TerkepElem
{
protected Jel jel;
public override Jel Jel
{
get { return jel; }
}
protected FixTerkepElem(Terkep terkep, Pozicio pozicio, Jel jel) : base(terkep, pozicio)
{
this.pozicio = pozicio;
this.jel = jel;
}
}
public class Fal : FixTerkepElem
{
static readonly Jel FAL_KARAKTER = new Jel(Param.FAL, ConsoleColor.DarkRed);
public Fal(Terkep terkep, Pozicio pozicio) : base(terkep, pozicio, FAL_KARAKTER)
{
Utkozes = elem => throw new NemLehetIdeLepniKivetel(this, elem);
}
}
public class Kincs : TerkepElem
{
readonly ConsoleColor[] szinek = new ConsoleColor[] { ConsoleColor.DarkRed, ConsoleColor.Red, ConsoleColor.DarkYellow, ConsoleColor.Yellow,
ConsoleColor.DarkYellow, ConsoleColor.Red };
public char Azonosito { get; private set; }
public float Ertek { get; private set; }
public int Suly { get; private set; }
int villogasSzamlalo = 0;
public override Jel Jel
{
get { return new Jel(Azonosito, szinek[villogasSzamlalo++ % szinek.Length]); }
}
public Kincs(Terkep terkep, Pozicio pozicio, char azonosito, float ertek, int suly) : base(terkep, pozicio)
{
this.Azonosito = azonosito;
this.Ertek = ertek;
this.Suly = suly;
}
}
public class KincsKezelo : INezopont
{
readonly protected Kincs[] kincsek = new Kincs[Param.KINCSEK_SZAMA];
readonly protected Terkep terkep;
public KincsKezelo(Terkep terkep)
{
this.terkep = terkep;
megjelenithetoKincsAdatok = Array.Empty<FixJel>();
}
public void KincsekGeneralasa()
{
Random rnd = new Random();
for (int i = 0; i < Param.KINCSEK_SZAMA; i++)
kincsek[i] = new Kincs(terkep, new Pozicio(0, 0), (char)(i + 97), rnd.Next(1, 100 / Param.KINCSEK_SZAMA), rnd.Next(1, Param.KINCSEK_MAX_MERETE));
KincsekElhelyezese();
MegjelenitesRendereles();
}
protected virtual void KincsekElhelyezese()
{
Random rnd = new Random();
int i = 0;
while (i < Param.KINCSEK_SZAMA)
{
Pozicio rndPozicio = new Pozicio(rnd.Next(terkep.Meret.Szelesseg), rnd.Next(terkep.Meret.Magassag));
if (terkep.AdottHelyen(rndPozicio).Count == 0)
{
kincsek[i].Athelyez(rndPozicio);
i++;
}
}
}
private IMegjelenitheto[] megjelenithetoKincsAdatok;
private void MegjelenitesRendereles()
{
List<FixJel> elemek = new List<FixJel>();
for (int i = 0; i < kincsek.Length; i++)
{
string szoveg = kincsek[i].Jel.Karakter + " " + kincsek[i].Ertek + "/" + kincsek[i].Suly;
elemek.AddRange(FixJel.SzovegbolJelsor(szoveg, new Pozicio(1, i), ConsoleColor.White));
}
megjelenithetoKincsAdatok = elemek.ToArray();
}
public string Fejlec => "Kincsek";
public Meret Meret => new Meret(9, Param.KINCSEK_SZAMA);
public IMegjelenitheto[] MegjelenitendoElemek()
{
return megjelenithetoKincsAdatok;
}
}
}