namespace PripravaNaTest_Vlakna;
 
class Program
{
    static void Main(string[] args)
    {
        AlchymLab alchymLab = new AlchymLab(100, 100, 100);
        Random rnd = new Random();
        int pocetLektvaruSily = 0;
        int pocetLektvaruNeviditelnosti = 0;
        Thread t1 = new Thread(RunDoplnSuroviny);
        Thread t2 = new Thread(RunUvarLektvarSily);
        Thread t3 = new Thread(RunUvarLektvarNeviditelnosti);
        Thread t4 = new Thread(RunUvarObaNahodne);
        t1.Start();
        t2.Start();
        t3.Start();
        t4.Start();
        t1.Join();
        t2.Join();
        t3.Join();
        t4.Join();
 
        Console.WriteLine("Byliny: " + alchymLab.AktualniByliny + ", Krystaly: " + alchymLab.AktualniKrystaly + ", Esence: " + alchymLab.AktualniEsence + "\n"+"Počet lektvarů síly: "+pocetLektvaruSily+", Počet lektvarů neviditelnosti: "+pocetLektvaruNeviditelnosti);
 
        void RunDoplnSuroviny()
        {
            for (int i = 0; i < 10; i++)
            {
                alchymLab.DoplnSuroviny(rnd.Next(10) + 1, rnd.Next(10) + 1, rnd.Next(10) + 1);
            }
        }
 
        void RunUvarLektvarSily()
        {
            for (int i = 0; i < 5; i++)
            {
                alchymLab.UvarLektvarSily();
                pocetLektvaruSily++;
            }
        }
 
        void RunUvarLektvarNeviditelnosti()
        {
            for (int i = 0; i < 4; i++)
            {
                alchymLab.UvarLektvarNeviditelnosti();
                pocetLektvaruNeviditelnosti++;
            }
        }
 
        void RunUvarObaNahodne()
        {
            for (int i = 0; i < rnd.Next(5)+1; i++)
            {
                alchymLab.UvarLektvarSily();
                alchymLab.UvarLektvarNeviditelnosti();
                pocetLektvaruSily++;
                pocetLektvaruNeviditelnosti++;
            }
        }
    }
}
namespace PripravaNaTest_Vlakna;
 
public class AlchymLab
{
    private readonly object _lock = new object();
    private readonly int _kapacitaBylin;
    private readonly int _kapacitaKrystalu;
    private readonly int _kapacitaEsenci;
 
    private int _aktualniByliny;
    private int _aktualniKrystaly;
    private int _aktualniEsence;
 
 
    public int AktualniByliny
    {
        get => _aktualniByliny;
        set => _aktualniByliny = value;
    }
 
    public int AktualniKrystaly
    {
        get => _aktualniKrystaly;
        set => _aktualniKrystaly = value;
    }
 
    public int AktualniEsence
    {
        get => _aktualniEsence;
        set => _aktualniEsence = value;
    }
 
    public AlchymLab(int kapacitaBylin, int kapacitaKrystalu, int kapacitaEsenci)
    {
        _kapacitaBylin = kapacitaBylin;
        _kapacitaKrystalu = kapacitaKrystalu;
        _kapacitaEsenci = kapacitaEsenci;
    }
 
    public void DoplnSuroviny(int byliny, int krystaly, int esence)
    {
        lock (_lock)
        {
            AktualniByliny = (AktualniByliny + byliny <= _kapacitaBylin)
                ? AktualniByliny += byliny
                : throw new Exception("Nelze naplnit sklad bylinami.");
            AktualniKrystaly = (AktualniKrystaly + krystaly <= _kapacitaKrystalu)
                ? AktualniKrystaly += krystaly
                : throw new Exception("Nelze naplnit sklad krystaly.");
            AktualniEsence = (AktualniEsence + esence <= _kapacitaEsenci)
                ? AktualniEsence += esence
                : throw new Exception("Nelze naplnit sklad esencemi.");
        }
    }
 
    public bool UvarLektvarSily()
    {
        lock (_lock)
        {
            if (_aktualniByliny >= 5 && _aktualniEsence >= 1 && _aktualniKrystaly >= 2)
            {
                _aktualniByliny -= 5;
                _aktualniEsence -= 1;
                _aktualniKrystaly -= 2;
                return true;
            }
            return false;
        }
    }
 
    public bool UvarLektvarNeviditelnosti()
    {
        lock (_lock)
        {
            if (_aktualniByliny >= 2 && _aktualniEsence >= 2 && _aktualniKrystaly >= 3)
            {
                _aktualniByliny -= 2;
                _aktualniEsence -= 2;
                _aktualniKrystaly -= 3;
                return true;
            }
            return false;
        }
    }
}