// 
//	dvadsiatka.cc, version 2.0
//	All chlast reserved, (C) 2000 Nezmar
//
	
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

// definicia koeficientov 'vykonu', integer je pouzity kvoli rychlosti vypoctov

#define	CHLAST		7
#define	male_pivo	6
#define	pivo		10
#define	stamprdlo	6
#define	poldeco	10
#define	vino		10
#define	domaca		14
#define	cola		-1

int	chlast_tab[CHLAST] = {male_pivo, pivo, stamprdlo, poldeco, vino, domaca, cola};

// vstupne data
struct my
{
	char * meno;		// identifikacny retazez
	int zaludok;		// hranica pre tycku (+20 je uz deadlock)
} 
My[] 	= 	{{"Jano", 60},
		{"Kecup", 70},
		{"Dusko", 90},
		{"Zich", 120},
		{"Pixla", 100}};

class Ochlasta
{
	int zaludok;
	int nakupene;
	char * meno;	
  public:
	Ochlasta(char *s, int z)
	{
		meno = s;
		zaludok = z;
		nakupene = 0;	// predpoklad je ze vsetci su aspon pri prichode triezvi!
	}

	int Nakup(int coze)
	{
		return nakupene += nakup;
	}

 	int UzJeTycka(void)
	{
		return min(zaludok, nakupene) == zaludok ? nakupene-zaludok : 0; 
	} 

	int Tycka(void);
} 

class Krcma 
{ 
	Ochlasta obsadka[MAX_MIEST_V_KRCME]; // ludia v krcme 
	int vodka; // zasoby chlastu 
	int pivo; 
	int vino; 
	int ejtybli; 
  public: 
	int ksichtov_v_krcme; 

	Krcma(struct my *My, int kolko, int a="10," int b="200," int c="20)" : vodka(a), pivo(b), vino(c) 
	{ 
		ejtybli=0;
		pocet_ksichtov_v_krcme=kolko; // akoze 5 
		for(int i=0; i !=pocet_ksichtov_v_krcme; i++) 
		{ // pociatocna inicializacia 
			obsadka[i]=new Ochlasta(My[i].meno, My[i].zaludok);
		}
	}

	~Krcma()
	{ 
		for(int i=0; i !=MAX_MIEST_V_KRCME; i++) 
		{ 
			if (obsadka[i].exist()) delete(obsadka[i]); 
		} 
		ejtybli=0; // ju potrebne poupratovat 
	} 

	int je_co_pit(void) // pozor na zaporne hodnoty!!! 
	{
		return vodka + pivo + vino; 
	} 

	void Kolo(int ktoze); 

	int Frtan(int ktoze, int coze) 
	{ 
		return obsadka[ktoze].Nakup(coze); 
	} 

	int PridajTycku(void) 
	{ 
		return ejtybli++; 
	} 

	int UzMamDost(int kto)
	{
		int tycka = obsadka[kto].UzJeTycka();
		if (tycka == 0) return 0;
		return obsadka[kto].Tycka();
	}

	void Hrobar(void);

	void HardReset(int kto)
	{
		printf("The man %s is death!\n", obsadka[kto].meno);
		delete obsadka[kto];
		pocet_ksichtov_v_krcme--;
	}
} 

int MamChutNa(void)
{
	return chlast_tab[random(CHLAST)];
}

int Ochlasta::Tycka(void) 
{ 
	// tak sa pozrime co sme to papinkali ...
	if (random(6) == 1) return 0;	// neuspesny pokus - sucha tycka - POZOR: HROZI DEADLOCK!!!
	nakupene = nakupene / 2;	// BULHAR: zaludok je sice prazdny ale v krvi toho je este dost
	return 1;
} 

void Krcma::Runda(int ktoze) 
{ 
	int co = MamChutNa();
	for(int i=0; i !=pocet_ksichtov_v_krcme; i++)
	{
		Vrbica.Frtan(i, co);
	}
} 

void Krcma::Hrobar(void) 
{ 
	for(int i=0; i !=pocet_ksichtov_v_krcme; i++)
	{
		if (min(obsadka.UzJeTycka(i), 19) == 19)
		{	// deadlock
			obsadka[i].HardReset(); // uz to mas za sebou ... (momentalne nastavene na 2 piva)
		}
	}
} 

int main(int argc, char *argv[]) 
{	
	// pociatocna inicializacia, 5 kusov vid zaciatok programu 
	Krcma Vrbica(My, 5); 
	int hladina;

	printf("Nazdar chlapi!\n");
	while(end_of_the_world()==0 
	&& Vrbica.je_co_pit() !=0 
	&& Vrbica.pocet_ksichtov_v_krcme !=0) 
	{ 
		// kazdy si nieco objednava ...
		for(int i=0; i !=pocet_ksichtov_v_krcme; i++)
		{
			Vrbica.Frtan(i, MamChutNa());
		}

		// niekto musi predsa nieco oslavovat...
		Vrbica.Runda(random(pocet_ksichtov_v_krcme));

		// nahodny test na prekrocenie maximalnej pripustnej hodnoty
		Vrbica.Hrobar();

		// a zeby este niekto iny ... nieco oslavoval .. jedna ku trom ze hej
		if (random(3) == 1) Vrbica.Runda(random(pocet_ksichtov_v_krcme));

		// tak sa na to pozrieme, ako sme na tom ...
		for(int i=0; i !=pocet_ksichtov_v_krcme; i++)
		{
			hladina = Vrbica.UzMamDost(i);
			if (hladina)
			{
				Vrbica.PridajTycku();
			}
		}
		// nahodny test na prekrocenie maximalnej pripustnej hodnoty
		Vrbica.Hrobar();
	} 
	printf("Sakra, uz je zase jar!\n");
}