#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <termios.h>

#define DEBUG 1

char getch() {
	char buf = 0;
	struct termios old = {0};
	if (tcgetattr(0, &old) < 0)
		perror("tcsetattr()");
	old.c_lflag &= ~ICANON;
	old.c_lflag &= ~ECHO;
	old.c_cc[VMIN] = 1;
	old.c_cc[VTIME] = 0;
	if (tcsetattr(0, TCSANOW, &old) < 0)
		perror("tcsetattr ICANON");
	if (read(0, &buf, 1) < 0)
		perror ("read()");
	old.c_lflag |= ICANON;
	old.c_lflag |= ECHO;
	if (tcsetattr(0, TCSADRAIN, &old) < 0)
		perror ("tcsetattr ~ICANON");
	return (buf);
}


typedef enum {
	MEDIK, SLINA, MAG, MAFIAN, UCHYL, ZABIJAK, PONOZKY, SAMAN,
	ZRCADLO, ATEISTA, ANARCHISTA, PROVAZOCHODEC, HVEZDAR,
	MASOVY_VRAH, GANDALF, KUSKONA, MRAKOPLAS, MECIAR, DZURINDA,
	KOVAC, ZAVAZADLO, ATOMOVKA, OPPENHEIMER, SCHIZOFRENIK, OBCM, DRZABA, NULLFUNKCE
	} typ_funkce;

typedef struct {
	typ_funkce typ;
	int num;	// dodatečná data: mafián č. num, schizofrenik skup. num…
			// implicitní u ostatních je 0
			// mág č. num,
			// anarchista, hvězdář, oppenheimer, šaman,
			// provazochodec: počet využití funkce
			// medik:	0 … ještě nevyužil
			//		>0 … využil minulou noc, počet životů, které získá
			//		<0 … využil dříve než minulou noc, už nesmí
			// atomovka:	0 … ještě nebyla odpálena,
			//		1 … odpálena, ještě nebouchla
			//		2 … odpálena, vybouchla
} st_funkce;

typedef enum {
	STRILI, SMRDI, PRESOUVA, UCHYLI, PRESMERUJE, SLINI
	} typ_udalosti;

typedef enum {
	ZABIT, OBESEN, PRESUNUT, ZUCHYLEN
	} typ_efektu;

typedef struct{
	char jmeno[256];
	int predchozi;
	int nasledujici;
	int zivotu;
	int nfunkci;
	st_funkce *funkce;
} st_hrac;

typedef struct {
	typ_udalosti typ;
	int nzdroj;
	int *zdroj;
	int ncil;
	int *cil;
} st_udalost;

typedef struct {
	typ_efektu typ;
	int nzdroj;
	int *zdroj;
	int ncil;
	int *cil;
} st_efekt;


int nhracu;
st_hrac *hraci;
int kolo;

int medik=-1, fnmedik=0;
int hvezdar=-1, fnhvezdar=0;
int atomovka=-1, fnatomovka=0;
int anarchista=-1, fnanarchista=0;
int ateista=-1, fnateista=0;
int oppenheimer=-1, fnoppenheimer=0;
int zrcadlo=-1, fnzrcadlo=0;
int gandalf=-1, fngandalf=0;
int kuskona=-1, fnkuskona=0;


char uchylarny[2][512];

st_udalost *udalosti;
int nudalosti;		// počet nezpracovaných událostí
int maxudalosti;	// maximální počet událostí, pro které je alokovaná paměť

st_efekt *efekty;
int nefektu;		// počet nezpracovaných efektů
int maxefektu;		// maximální počet efektů, pro které je alokovaná paměť

int *teple_mrtvoly;
int nteplych_mrtvol;
int *studene_mrtvoly;
int nstudenych_mrtvol;

#define dprint(vyraz) printf(#vyraz " = %g\n", vyraz)

void flush_stdin(){
//	int ch;
//	while ((ch=getchar()) != EOF && ch != '\n');
}

void print_line(){
	printf("===========================\n");
}

int ask_bool(char *question){
	char answer;
	while (1) {
		printf("%s [a/n] ", question);
		fflush(stdout);
		answer=getch();
		if (answer=='a'){
			printf("ano.\n");
			return 1;
		}
		else if (answer=='n'){
			printf("ne.\n");
			return 0;
		}
	}
}

int ask_int(char *question){
	int answer;
	printf("%s ", question);
	scanf("%i", &answer);
	return answer;
}

void ask_string(char *question, char *answer){
	printf("%s ", question);
	scanf("%s", answer);
}

int cislo_funkce (st_hrac *hrac, typ_funkce funkce){
	int i;
	for (i=0;i<hrac->nfunkci;i++){
		if (hrac->funkce[i].typ == funkce)
			return i;
	}
	return -1;
}

int hrac_ma_funkci (st_hrac *hrac, typ_funkce funkce){
	int i;
	for (i=0;i<hrac->nfunkci;i++){
		if (hrac->funkce[i].typ == funkce)
			return 1;
	}
	return 0;
}

void add_effect(typ_efektu typ, int nzdroj, int *zdroj, int ncil, int *cil){
	// přidání efektů do fronty
	int i;
	#ifdef DEBUG
	printf("Přidávám efekt typu ");
	switch(typ){
		case ZABIT:
			printf("ZABIT");
			break;
		case OBESEN:
			printf("OBESEN");
			break;
		case PRESUNUT:
			printf("PRESUN");
			break;
		case ZUCHYLEN:
			printf("ZUCHYLEN");
			break;
		default:
			printf("neznámý typ efektu. Zavolejte kouzelníka. ");
	}
	printf(". Zdrojoví hráči jsou:");
	for (i=0;i<nzdroj;i++){
		printf(" %i", zdroj[i]);
	}
	printf(". Cílovi hráči jsou:");
	for (i=0;i<ncil;i++){
		printf(" %i", cil[i]);
	}
	printf("\n");
	#endif

	if (nefektu >= maxefektu){	// zdvojnásobit frontu na události
		st_efekt *tmp;
		maxefektu = 2*maxefektu;
		tmp = malloc(sizeof(st_efekt)*maxefektu);
		for (i=0;i<nefektu;i++){
			tmp[i].typ = efekty[i].typ;
			tmp[i].nzdroj = efekty[i].nzdroj;
			tmp[i].zdroj = efekty[i].zdroj;
			tmp[i].ncil = efekty[i].ncil;
			tmp[i].cil = efekty[i].cil;
		}
		free(efekty);
		efekty = tmp;
	}
	efekty[nefektu].typ = typ;
	efekty[nefektu].nzdroj = nzdroj;
	efekty[nefektu].zdroj = zdroj;
	efekty[nefektu].ncil = ncil;
	efekty[nefektu].cil = cil;
	nefektu++;
}

void solve_effects(){
	// aplikace efektů na hráče
	int i, j, k, l;

	print_line();
	#ifdef DEBUG
	for (i=0;i<nefektu;i++){
		printf("Ve frontě je efekt číslo %i typu ", i);
		switch(efekty[i].typ){
			case ZABIT:
				printf("ZABIT");
				break;
			case OBESEN:
				printf("OBESEN");
				break;
			case PRESUNUT:
				printf("PRESUNUT");
				break;
			case ZUCHYLEN:
				printf("ZUCHYLEN");
				break;
			default:
				printf("neznámý typ efektu. Zavolejte kouzelníka. ");
		}
		printf(". Zdrojoví hráči jsou:");
		for (j=0;j<efekty[i].nzdroj;j++){
			printf(" %i", efekty[i].zdroj[j]);
		}
		printf(". Cílovi hráči jsou:");
		for (j=0;j<efekty[i].ncil;j++){
			printf(" %i", efekty[i].cil[j]);
		}
		printf("\n");
	}
	#endif
	int tmp, tmp2;
	typ_funkce hledam;
	for (i=0;i<nefektu;i++){
		switch(efekty[i].typ){
			case ZABIT:
				for (j=0;j<efekty[i].ncil;j++){
					hledam = NULLFUNKCE;
					if (efekty[i].cil[j]<0 || efekty[i].cil[j] >= nhracu) continue;
					if (hrac_ma_funkci(&hraci[efekty[i].cil[j]], GANDALF)){
					// řešit:
					//	gandalf zabil kus koňa a naopak,
						hledam = KUSKONA;
					}
					if (hrac_ma_funkci(&hraci[efekty[i].cil[j]], KUSKONA)){
						hledam = GANDALF;
					}
					//	atomovka zabila oppenheimera
					if (hrac_ma_funkci(&hraci[efekty[i].cil[j]], OPPENHEIMER)){
						hledam = ATOMOVKA;
					}
					//	schizofrenik umřel
					if (hrac_ma_funkci(&hraci[efekty[i].cil[j]], SCHIZOFRENIK)){
						for (l=0;l<hraci[efekty[i].cil[j]].nfunkci;l++){
							if (hraci[efekty[i].cil[j]].funkce[l].typ == SCHIZOFRENIK) break;
						}
						tmp = l;
						for (k=0;k<nhracu;k++){
							if (hrac_ma_funkci(&hraci[k], SCHIZOFRENIK)){
								for (l=0;l<hraci[k].nfunkci;l++){
									if (hraci[k].funkce[l].typ == SCHIZOFRENIK && k != efekty[i].cil[0] &&
										hraci[efekty[i].cil[j]].funkce[tmp].num == hraci[k].funkce[l].num){
										hraci[k].zivotu--;
										break;
									}
								}
							}
						}
					}
					hraci[efekty[i].cil[j]].zivotu--;
				}
				break;
			case OBESEN:
				// řešit provazochodce a masového vraha
				if (efekty[i].cil[0] < 0 && efekty[i].cil[0] >= nhracu) break;
				if (hrac_ma_funkci(&hraci[efekty[i].cil[0]], PROVAZOCHODEC)){
					break;
				}
				else {
					if (hrac_ma_funkci(&hraci[efekty[i].cil[0]], SCHIZOFRENIK)){
						for (l=0;l<hraci[efekty[i].cil[0]].nfunkci;l++){
							if (hraci[efekty[i].cil[0]].funkce[l].typ == SCHIZOFRENIK) break;
						}
						tmp = l;
						tmp2 = -1;
						for (k=0;k<nhracu;k++){
							if (hrac_ma_funkci(&hraci[k], SCHIZOFRENIK)){
								for (l=0;l<hraci[k].nfunkci;l++){
									if (hraci[k].funkce[l].typ == SCHIZOFRENIK && k != efekty[i].cil[0] &&
										hraci[efekty[i].cil[0]].funkce[tmp].num == hraci[k].funkce[l].num){
										hraci[k].zivotu--;
										break;
									}
								}
							}
						}
					}
					if (hrac_ma_funkci(&hraci[efekty[i].cil[0]], MASOVY_VRAH)){
						for (j=0;j<efekty[i].nzdroj;j++){
							if (efekty[i].zdroj[j]<0 || efekty[i].zdroj[j] >= nhracu) continue;
							hraci[efekty[i].zdroj[j]].zivotu--;
						}
					}
					hraci[efekty[i].cil[0]].zivotu--;
				}
				break;
			case PRESUNUT:
				// řešit schizofreniky
				if (efekty[i].zdroj[0] <0 || efekty[i].zdroj[0] > nhracu) break;
				if (efekty[i].ncil == 2 && efekty[i].cil[0] >= 0 && efekty[i].cil[0] < nhracu && efekty[i].cil[1] >= 0 && efekty[i].cil[1] < nhracu){
					tmp2 = -1;
					if (hrac_ma_funkci(&hraci[i], SCHIZOFRENIK)){
						for (l=0;l<hraci[efekty[i].cil[0]].nfunkci;l++){
							if (hraci[efekty[i].cil[0]].funkce[l].typ == SCHIZOFRENIK) break;
						}
						tmp = l;
						for (k=0;k<nhracu;k++){
							if (hrac_ma_funkci(&hraci[k], SCHIZOFRENIK)){
								for (l=0;l<hraci[k].nfunkci;l++){
									if (hraci[k].funkce[l].typ == SCHIZOFRENIK && k != efekty[i].cil[0] &&
										hraci[efekty[i].cil[0]].funkce[tmp].num == hraci[k].funkce[l].num){
										tmp2 = k;
										break;
									}
								}
							}
						}
					}
					if (tmp2 == -1) {
						if (efekty[i].cil[0]>efekty[i].cil[1]){
							hraci[efekty[i].zdroj[0]].predchozi = efekty[i].cil[1];
							hraci[efekty[i].cil[1]].nasledujici = efekty[i].zdroj[0];
							hraci[efekty[i].zdroj[0]].nasledujici = efekty[i].cil[0];
							hraci[efekty[i].cil[1]].predchozi = efekty[i].zdroj[0];
						}
						else {
							hraci[efekty[i].zdroj[0]].predchozi = efekty[i].cil[0];
							hraci[efekty[i].cil[0]].nasledujici = efekty[i].zdroj[0];
							hraci[efekty[i].zdroj[0]].nasledujici = efekty[i].cil[1];
							hraci[efekty[1].cil[1]].predchozi = efekty[i].zdroj[0];
						}
						printf("Pozor! Přesun hráče!\n");

					}
					else {	// máme tu schizofrenika … hráč číslo tmp2
						if (efekty[i].cil[0]>efekty[i].cil[1]){
							hraci[efekty[i].cil[1]].nasledujici = efekty[i].zdroj[0];
							hraci[efekty[i].zdroj[0]].predchozi = efekty[i].cil[1];
							hraci[efekty[i].zdroj[0]].nasledujici = tmp2;
							hraci[tmp2].predchozi = efekty[i].zdroj[0];
							hraci[tmp2].nasledujici = efekty[i].cil[1];
							hraci[efekty[i].cil[1]].predchozi = tmp2;
						}
						else {
							hraci[efekty[i].cil[0]].nasledujici = efekty[i].zdroj[0];
							hraci[efekty[i].zdroj[0]].predchozi = efekty[i].cil[0];
							hraci[efekty[i].zdroj[0]].nasledujici = tmp2;
							hraci[tmp2].predchozi = efekty[i].zdroj[0];
							hraci[tmp2].nasledujici = efekty[i].cil[1];
							hraci[efekty[1].cil[1]].predchozi = tmp2;
						}
						printf("Pozor! Přesun schizofreniků!\n");
					}
				}
				break;
			case ZUCHYLEN:
				// řešit schizofreniky
				if (efekty[i].cil[0] < 0 || efekty[i].cil[0] >= nhracu) break;
				tmp = -1;
				for (k=0;k<hraci[efekty[i].zdroj[0]].nfunkci;k++){
					if (hraci[efekty[i].zdroj[0]].funkce[k].typ == UCHYL) tmp = k;
				}
				if (tmp>=0) {
					printf("Hráč č. %i – %s byl zůchylen:%s\n", efekty[i].cil[0], hraci[efekty[i].cil[0]].jmeno, uchylarny[tmp]);
				}
				if (hrac_ma_funkci(&hraci[efekty[i].cil[0]], SCHIZOFRENIK)){
					for (k=0;k<hraci[efekty[i].cil[0]].nfunkci;k++){
						if (hraci[efekty[i].cil[0]].funkce[k].typ == SCHIZOFRENIK) tmp2 = k;
					}
					for (k=0;k<nhracu;k++){
						if (hrac_ma_funkci(&hraci[k], SCHIZOFRENIK)){
							for (l=0;l<hraci[k].nfunkci;l++){
								if (hraci[k].funkce[l].typ == SCHIZOFRENIK && k != efekty[i].cil[0]
									&& hraci[efekty[i].cil[0]].funkce[tmp2].num == hraci[k].funkce[l].num){
									printf("Hráč č. %i – %s byl zůchylen:%s\n", k, hraci[k].jmeno, uchylarny[tmp]);
								}
							}
						}
					}
				}
				break;
			default:
				printf("neznámý typ efektu. Zavolejte kouzelníka. ");
		}
		if (switch(efekty[i].typ == ZABIT || efekty[i].typ == obesen){	// zvýšíme počet životů, pokud jde o gandalf–kus koňa apod.
			for (j=0;j<efekty[i].nzdroj;j++){
				if (efekty[i].zdroj[j]<0 || efekty[i].zdroj[j] >= nhracu) continue;
				if (hrac_ma_funkci(&hraci[efekty[i].zdroj[j]], hledam)){
					hraci[efekty[i].zdroj[j]].zivotu++;
					// schizofrenici
					if (hrac_ma_funkci(&hraci[efekty[i].zdroj[j]], SCHIZOFRENIK)){
						tmp2 = -1;
						for (k=0;k<hraci[efekty[i].zdroj[j]].nfunkci;k++){
							if (hraci[efekty[i].zdroj[j]].funkce[k].typ == SCHIZOFRENIK) tmp2 = k;
						}
						for (k=0;k<nhracu;k++){
							if (hrac_ma_funkci(&hraci[k], SCHIZOFRENIK)){
								for (l=0;l<hraci[k].nfunkci;l++){
									if (hraci[k].funkce[l].typ == SCHIZOFRENIK && k != efekty[i].zdroj[j]
										&& hraci[efekty[i].zdroj[j]].funkce[tmp2].num == hraci[k].funkce[l].num){
										hraci[k].zivotu++l
									}
								}
							}
						}
					}
				}
			}
		}
	}
}


void add_event(typ_udalosti udalost, int nzdroj, int *zdroj, int ncil, int *cil){
	// události z noci … zatím nemají žádný efekt na hráče
	int i;
	#ifdef DEBUG
	printf("Přidávám událost typu ");
	switch(udalost){
		case STRILI:
			printf("STRILI");
			break;
		case SMRDI:
			printf("SMRDI");
			break;
		case PRESOUVA:
			printf("PRESOUVA");
			break;
		case UCHYLI:
			printf("UCHYLI");
			break;
		case PRESMERUJE:
			printf("PRESMERUJE");
			break;
		case SLINI:
			printf("SLINI");
			break;
		default:
			printf("neznámý typ události. Zavolejte kouzelníka. ");
	}
	printf(". Zdrojoví hráči jsou:");
	for (i=0;i<nzdroj;i++){
		printf(" %i", zdroj[i]);
	}
	printf(". Cílovi hráči jsou:");
	for (i=0;i<ncil;i++){
		printf(" %i", cil[i]);
	}
	printf("\n");
	#endif

	if (nudalosti >= maxudalosti){	// zdvojnásobit frontu na události
		st_udalost *tmp;
		maxudalosti = 2*maxudalosti;
		tmp = malloc(sizeof(st_udalost)*maxudalosti);
		for (i=0;i<nudalosti;i++){
			tmp[i].typ = udalosti[i].typ;
			tmp[i].nzdroj = udalosti[i].nzdroj;
			tmp[i].zdroj = udalosti[i].zdroj;
			tmp[i].ncil = udalosti[i].ncil;
			tmp[i].cil = udalosti[i].cil;
		}
		free(udalosti);
		udalosti = tmp;
	}
	udalosti[nudalosti].typ = udalost;
	udalosti[nudalosti].nzdroj = nzdroj;
	udalosti[nudalosti].zdroj = zdroj;
	udalosti[nudalosti].ncil = ncil;
	udalosti[nudalosti].cil = cil;
	nudalosti++;
}

void solve_events(){
	// přeloží události na konečné efekty na hráče
	int i, j;

	print_line();
	#ifdef DEBUG
	for (i=0;i<nudalosti;i++){
		printf("Ve frontě je událost číslo %i typu ", i);
		switch(udalosti[i].typ){
			case STRILI:
				printf("STRILI");
				break;
			case SMRDI:
				printf("SMRDI");
				break;
			case PRESOUVA:
				printf("PRESOUVA");
				break;
			case UCHYLI:
				printf("UCHYLI");
				break;
			case PRESMERUJE:
				printf("PRESMERUJE");
				break;
			case SLINI:
				printf("SLINI");
				break;
			default:
				printf("neznámý typ události. Zavolejte kouzelníka. ");
		}
		printf(". Zdrojoví hráči jsou:");
		for (j=0;j<udalosti[i].nzdroj;j++){
			printf(" %i", udalosti[i].zdroj[j]);
		}
		printf(". Cílovi hráči jsou:");
		for (j=0;j<udalosti[i].ncil;j++){
			printf(" %i", udalosti[i].cil[j]);
		}
		printf("\n");
	}
	#endif

	int slineny = -1;
	int npresunu = 0;
	int presuny[2][2];	// máme maximálně dva mágy, [x][0] … odkud, [x][1] … kam
	presuny[0][0] = -1;
	presuny[0][1] = -1;
	presuny[1][0] = -1;
	presuny[1][1] = -1;

	for (i=0;i<nudalosti;i++){	// nejprve magické přesuny
		if (udalosti[i].typ == PRESMERUJE && udalosti[i].zdroj[0] != ateista && udalosti[i].cil[0] != ateista){
				presuny[npresunu][0] = udalosti[i].zdroj[0];
				presuny[npresunu][1] = udalosti[i].cil[0];
				npresunu++;
		}
	}

	if (npresunu > 1 && presuny[0][1] == presuny[1][0])	{	// detekce cyklů u mágů
		npresunu = 0;	// zrušíme přesuny	TODO: špatně, má dojít ke zničení efektů!
	}
	// přesuny detekovány, teď je aplikujeme na události ve frontě

	for (i=0;i<nudalosti;i++){
		if (udalosti[i].typ != PRESOUVA){ // u události PRESOUVA je cílový hráč uložen v poli zdroj
			for (j=0;j<npresunu;j++){
				if (udalosti[i].cil[0] == presuny[j][0]){
					udalosti[i].cil[0] = presuny[j][1];
				}
			}
		}
		else {
			for (j=0;j<npresunu;j++){
				if (udalosti[i].zdroj[0] == presuny[j][0]){
					udalosti[i].zdroj[0] = presuny[j][1];
				}
			}
		}
	}

	for (i=0;i<nudalosti;i++){	// najdeme slinu
		if (udalosti[i].typ == SLINI && hrac_ma_funkci(&hraci[udalosti[i].cil[0]], ATEISTA)==0){
			slineny = udalosti[i].cil[0];
		}
	}

	// a na závěr přeložíme události na efekty
	for (i=0;i<nudalosti;i++){
		if (udalosti[i].typ == SLINI || udalosti[i].typ == PRESMERUJE) continue;
		switch(udalosti[i].typ){
			case STRILI:
				if (udalosti[i].cil[0] != slineny){
					j = cislo_funkce(&hraci[udalosti[i].cil[0]], ZRCADLO);
					if (j>-1 && hraci[udalosti[i].cil[0]].funkce[j].num < 1){	// kulka se odrazí
						hraci[udalosti[i].cil[0]].funkce[j].num++;
						add_effect(ZABIT, udalosti[i].ncil, udalosti[i].cil, udalosti[i].nzdroj, udalosti[i].zdroj);
						printf("Prasklo zrcadlo.\n");
					}
					else {
						add_effect(ZABIT, udalosti[i].nzdroj, udalosti[i].zdroj, udalosti[i].ncil, udalosti[i].cil);	
					}
				}
				break;
			case SMRDI:
				if (udalosti[i].cil[0] != slineny){
					add_effect(ZABIT, udalosti[i].nzdroj, udalosti[i].zdroj, udalosti[i].ncil, udalosti[i].cil);
				}
				break;
			case PRESOUVA:
				add_effect(PRESUNUT, udalosti[i].nzdroj, udalosti[i].zdroj, udalosti[i].ncil, udalosti[i].cil);
				break;
			case UCHYLI:
				add_effect(ZUCHYLEN, udalosti[i].nzdroj, udalosti[i].zdroj, udalosti[i].ncil, udalosti[i].cil);
				break;
		}
	}

	// a vymažeme události
	nudalosti = 0;
}


int najdi_postavu(typ_funkce funkce, int num){
	// najde prvního hráče majícího danou funkci nebo -1, pokud neexistuje
	// neřeší, jestli je hráč živý
	int i;
	for (i=0;i<nhracu;i++){
		if (hrac_ma_funkci(&hraci[i], funkce) == 1){
			if ((funkce == MAG || funkce == MAFIAN ||
				funkce == SCHIZOFRENIK || funkce == UCHYL)
				&& num != hraci[i].funkce->num)
				continue;
			else
				return i;
		}
	}
	return -1;
}


void vypis_funkci(typ_funkce funkce){
	switch (funkce){
	case MEDIK:
		printf("medik");
		break;
	case SLINA:
		printf("slina");
		break;
	case MAG:
		printf("mág");
		break;
	case MAFIAN:
		printf("mafián");
		break;
	case UCHYL:
		printf("úchyl");
		break;
	case ZABIJAK:
		printf("zabiják");
		break;
	case PONOZKY:
		printf("ponožky");
		break;
	case SAMAN:
		printf("šaman");
		break;
	case ZRCADLO:
		printf("zrcadlo");
		break;
	case ATEISTA:
		printf("ateista");
		break;
	case ANARCHISTA:
		printf("anarchista");
		break;
	case PROVAZOCHODEC:
		printf("provazochodec");
		break;
	case HVEZDAR:
		printf("hvězdář");
		break;
	case MASOVY_VRAH:
		printf("masový vrah");
		break;
	case GANDALF:
		printf("Gandalf");
		break;
	case KUSKONA:
		printf("kus koňa");
		break;
	case MRAKOPLAS:
		printf("Mrakoplaš");
		break;
	case MECIAR:
		printf("Mečiar");
		break;
	case DZURINDA:
		printf("Dzurinda");
		break;
	case KOVAC:
		printf("Kováč");
		break;
	case ZAVAZADLO:
		printf("zavazadlo");
		break;
	case ATOMOVKA:
		printf("atomovka");
		break;
	case OPPENHEIMER:
		printf("Oppenheimer");
		break;
	case SCHIZOFRENIK:
		printf("schizofrenik");
		break;
	case OBCM:
		printf("otec Bratr Cyril Metoděj");
		break;
	case DRZABA:
		printf("Dr. Emil Žába");
		break;
	default:
		printf("Neznámá funkce. Pokud vidíte tuto hlášku, zavolejte kouzelníka.\n");
	}
}

typ_funkce ask_function(st_hrac *hrac, int nfun){
	typ_funkce funkce;
	char c;
	int ok = 0;
	int num;
	do {
		num = 0;
		printf("Zadejte funkci číslo %i hráče %s:\n", nfun, hrac->jmeno);
		printf("\t[a] medik\n");
		printf("\t[b] slina\n");
		printf("\t[c] mág\n");
		printf("\t[d] mafián\n");
		printf("\t[e] úchyl\n");
		printf("\t[f] zabiják\n");
		printf("\t[g] ponožky\n");
		printf("\t[h] šaman\n");
		printf("\t[i] zrcadlo\n");
		printf("\t[j] ateista\n");
		printf("\t[k] anarchista\n");
		printf("\t[l] provazochodec\n");
		printf("\t[m] hvězdář\n");
		printf("\t[n] masový vrah\n");
		printf("\t[o] Gandalf\n");
		printf("\t[p] kus koňa\n");
		printf("\t[q] Mrakoplaš\n");
		printf("\t[r] Mečiar\n");
		printf("\t[s] Dzurinda\n");
		printf("\t[t] Kováč\n");
		printf("\t[u] zavazadlo\n");
		printf("\t[v] atomovka\n");
		printf("\t[w] Oppenheimer\n");
		printf("\t[x] schizofrenik\n");
		printf("\t[y] otec Bratr Cyril Metoděj\n");
		printf("\t[z] Dr. Emil Žába\n");
		c=getch();
		switch (c) {
			case 'a':
				funkce = MEDIK;
				break;
			case 'b':
				funkce = SLINA;
				break;
			case 'c':
				funkce = MAG;
				num = ask_int("Číslo mága?");
				break;
			case 'd':
				funkce = MAFIAN;
				num = ask_int("Číslo mafiána?");
				break;
			case 'e':
				funkce = UCHYL;
				num = ask_int("Číslo úchyla?");
				break;
			case 'f':
				funkce = ZABIJAK;
				break;
			case 'g':
				funkce = PONOZKY;
				break;
			case 'h':
				funkce = SAMAN;
				break;
			case 'i':
				funkce = ZRCADLO;
				break;
			case 'j':
				funkce = ATEISTA;
				break;
			case 'k':
				funkce = ANARCHISTA;
				break;
			case 'l':
				funkce = PROVAZOCHODEC;
				break;
			case 'm':
				funkce = HVEZDAR;
				break;
			case 'n':
				funkce = MASOVY_VRAH;
				break;
			case 'o':
				funkce = GANDALF;
				break;
			case 'p':
				funkce = KUSKONA;
				break;
			case 'q':
				funkce = MRAKOPLAS;
				break;
			case 'r':
				funkce = MECIAR;
				break;
			case 's':
				funkce = DZURINDA;
				break;
			case 't':
				funkce = KOVAC;
				break;
			case 'u':
				funkce = ZAVAZADLO;
				break;
			case 'v':
				funkce = ATOMOVKA;
				break;
			case 'w':
				funkce = OPPENHEIMER;
				break;
			case 'x':
				funkce = SCHIZOFRENIK;
				num = ask_int("Skupina schizofreniků?");
				break;
			case 'y':
				funkce = OBCM;
				break;
			case 'z':
				funkce = DRZABA;
				break;
			default:
				printf("Neznámá funkce. ");
		}
		printf("Hráči %s přiřadím funkci ", hrac->jmeno);
		vypis_funkci(funkce);
		if (num != 0){
			printf(" číslo %i", num);
		}
		printf(". ");
	} while(ask_bool("Je to ok?")==0);
	hrac->funkce[nfun].typ = funkce;
	hrac->funkce[nfun].num = num;
	// dodatečné init efetky:
	//	zvýšit život mrakoplaši
	num = najdi_postavu(MRAKOPLAS, 0);
	if (num >= 0 && num < nhracu){
		hraci[num].zivotu++;
	}
}

// TODO: zařídit, aby ateista nemohl používat funkci mága a sliny
// TODO: Gandalf a Kuskoňa je jedna osoba – získá dva životy navíc, tj. má celkem tři
// TODO: hlasování
// TODO: přesměrování výbuchu atomovky mágem, slina apod.

void init_faze(){
	int i, j, nfunkci;
	char tmp[256];
	kolo=0;
	nfunkci=ask_int("Počet funkcí?");
	nhracu=ask_int("Počet hráčů?");
	hraci = malloc(sizeof(st_hrac)*nhracu);
	teple_mrtvoly = malloc(sizeof(int)*nhracu);
	nteplych_mrtvol = 0;
	studene_mrtvoly = malloc(sizeof(int)*nhracu);
	nstudenych_mrtvol = 0;

	efekty = malloc(sizeof(st_efekt)*4*nhracu);		// implicitně čtyřnásobek počtu hráčů
	udalosti = malloc(sizeof(st_udalost)*4*nhracu);
	nefektu = 0;
	nudalosti = 0;
	maxefektu = 4*nhracu;
	maxudalosti = 4*nhracu;

	for (i=0;i<nhracu;i++){
		sprintf(tmp, "Jméno hráče číslo %i?", i);
		ask_string(tmp, hraci[i].jmeno);
		hraci[i].zivotu = 1;
		hraci[i].nfunkci = nfunkci;
		hraci[i].funkce = malloc(sizeof(st_funkce)*nfunkci);
		for (j=0;j<nfunkci;j++){
			ask_function(&hraci[i], j);
		}
		hraci[i].predchozi = (i==0 ? nhracu-1 : i-1);
		hraci[i].nasledujici = (i==nhracu-1 ? 0 : i+1);

		for (j=0;j<nfunkci;j++){
			switch (hraci[i].funkce[j].typ){
				case MEDIK:
					medik = i;
					fnmedik = j;
					break;
				case HVEZDAR:
					hvezdar = i;
					fnhvezdar = j;
					break;
				case ATOMOVKA:
					atomovka = i;
					fnatomovka = j;
					break;
				case ANARCHISTA:
					anarchista = i;
					fnanarchista = j;
					break;
				case ATEISTA:
					ateista = i;
					fnateista = j;
					break;
				case OPPENHEIMER:
					oppenheimer = i;
					fnoppenheimer = j;
					break;
			}
		}
	}
}

void vypis_info_o_hraci(int id){	// podrobné info o hráčích
	int i;
	printf("Hráč č. %i – %s: ", id, hraci[id].jmeno);
	printf("předchozí hráč: %i – %s, ", hraci[id].predchozi, hraci[hraci[id].predchozi].jmeno);
	printf("následující hráč: %i – %s, ", hraci[id].nasledujici, hraci[hraci[id].nasledujici].jmeno);
	printf("životů: %i, ", hraci[id].zivotu);
	printf("funkce:");
	for (i=0;i<hraci[id].nfunkci;i++){
		printf(" ");
		vypis_funkci(hraci[id].funkce[i].typ);
		printf(".num=%i ", hraci[id].funkce[i].num);
	}
	printf("\n");
}

void vypis_info(){	// podrobné info o hráčích
	int i;
	for (i=0;i<nhracu;i++){
		vypis_info_o_hraci(i);
	}
}


void vypis_hrace(){	// jména a čísla hráčů
	int i;
	for (i=0;i<nhracu;i++){
		printf("\t[%i] %s\n", i, hraci[i].jmeno);
	}
}

void konec_hry(){

}

void hlasovani(){	// TODO
	int i, j;
	int obesenec;
	int hlasy_pro[nhracu], nhlasu_pro;
	int hlasy_proti[nhracu], nhlasu_proti;
	int pro, proti;		// skutečné skóre
	int meciar;	// 0 … nehlasoval, 1 … hlasoval pro, -1 … hlasoval proti
	int zivych;
	char *tmp, *tmp2;
	tmp = malloc(sizeof(char)*256);

	do {
		printf("Pro koho hlasujeme? Zadejte číslo hráče:\n");
		vypis_hrace();
		printf("\t[%i] rozmysleli jsme si to a hlasovat nechceme\n", nhracu);
		scanf("%i", &obesenec);
		if (obesenec<nhracu){
			printf("Budeme hlasovat o oběšení hráče %i – %s. ", obesenec, hraci[obesenec].jmeno);
		}
		else {
			printf("Zrušíme hlasování. ");
		}
	} while(ask_bool("Je to ok?")==0);
	if (obesenec<nhracu){
		fgets(tmp, 256, stdin);
		do {
			nhlasu_pro=-1;
			printf("Kdo je pro popravu?");
			vypis_hrace();
			fflush(stdout);
			__fpurge(stdin);
			printf("Zadejte čísla hráčů hlasujících pro popravu oddělená mezerou:\n");
			fgets(tmp, 256, stdin);
			tmp2 = tmp;
			while(*tmp2){
				if (*tmp2 == '\n'){
					*tmp2 = ' ';
				}
				tmp2++;
			}
			tmp2 = tmp;
			strcat(tmp, " ");
			while (nhlasu_pro < nhracu && *tmp){
				hlasy_pro[++nhlasu_pro] = strtol(tmp, &tmp, 10);
				if (*tmp != ' ')
					break;
				tmp++;
			}
			printf("Pro hlasovali:");
			for (i=0;i<nhlasu_pro;i++){
				printf("\thráč č. %i – %s\n", hlasy_pro[i], hraci[hlasy_pro[i]].jmeno);
			}
		} while(ask_bool("Je to ok?")==0);

		do {
			nhlasu_proti=-1;
			printf("Kdo je proti popravě?");
			vypis_hrace();
			printf("Zadejte čísla hráčů hlasujících proti popravu oddělená mezerou:\n");
			fflush(stdout);
			fgets(tmp, 256, stdin);
			tmp2 = tmp;
			while(*tmp2){
				if (*tmp2 == '\n'){
					*tmp2 = ' ';
				}
				tmp2++;
			}
			tmp2 = tmp;
			strcat(tmp, " ");
			printf("tmp='%s'\n",tmp);
			while (nhlasu_proti < nhracu && *tmp){
				hlasy_proti[++nhlasu_proti] = strtol(tmp, &tmp, 10);
				if (*tmp != ' ')
					break;
				tmp++;
			}
			printf("Pro hlasovali:");
			for (i=0;i<nhlasu_proti;i++){
				printf("\thráč č. %i – %s\n", hlasy_proti[i], hraci[hlasy_proti[i]].jmeno);
			}
		} while(ask_bool("Je to ok?")==0);
	}

	// hlasy máme, jdeme na vyhodnocení.
	pro = nhlasu_pro;
	proti = nhlasu_proti;
	// nejprve se podíváme, jestli mezi hlasujícími není Mečiar
	meciar = 0;
	for (i=0;i<nhlasu_pro;i++){
		if (hrac_ma_funkci(&hraci[hlasy_pro[i]], MECIAR)){
			meciar = 1;
		}
	}
	for (i=0;i<nhlasu_proti;i++){
		if (hrac_ma_funkci(&hraci[hlasy_proti[i]], MECIAR)){
			meciar = -1;
		}
	}
	if (meciar == 1){	// pokud ano, tak zjistíme, jestli hlasuje Dzurinda proti
		for (i=0;i<nhlasu_proti;i++){
			if (hrac_ma_funkci(&hraci[hlasy_proti[i]], DZURINDA)){
				proti++;
			}
		}
		// a zvýšíme počet hlasů pro
		pro++;
	} else if (meciar == -1){
		for (i=0;i<nhlasu_pro;i++){
			if (hrac_ma_funkci(&hraci[hlasy_pro[i]], DZURINDA)){
				pro++;
			}
		}
		proti++;
	}
	// a na závěr se podíváme, jestli hlasoval Kováč
	for (i=0;i<nhlasu_pro;i++){
		if (hrac_ma_funkci(&hraci[hlasy_pro[i]], KOVAC)){
			pro-=2;
		}
	}
	for (i=0;i<nhlasu_proti;i++){
		if (hrac_ma_funkci(&hraci[hlasy_proti[i]], KOVAC)){
			proti-=2;
		}
	}
	// a spočítáme aktuálně žijící hráče
	zivych = 0;
	for (i=0;i<nhracu;i++){
		if (hraci[i].zivotu>0)
			zivych++;
	}
	printf("Výsledek hlasování: pro %i/%i proti z %i živých hráčů.\n", pro, proti, zivych);

	if (pro>zivych/2){	// nadpoloviční většina hlasuje pro oběšení
		int *hlasujici;
		int *obesen;
		hlasujici = malloc(sizeof(int)*nhlasu_pro);
		obesen = malloc(sizeof(int));
		obesen[0] = obesenec;
		for (i=0;i<nhlasu_pro;i++){
			hlasujici[i] = hlasy_pro[i];
		}
		printf("Hráč č. %i – %s je oběšen.\n", obesenec, hraci[obesenec]);
		add_effect(OBESEN, nhlasu_pro, hlasujici, 1, obesen);
	}
}

void rano(){	// oživit medika, nechat vybouchnout atomovku
	int i, j, ok;
	if (medik >= 0 && medik<nhracu) {
		hraci[medik].funkce[fnmedik].num *= -1;		// TODO: rozmyslet, jestli jsem tady nevytvořil cyklus
		if (hraci[medik].funkce[fnmedik].num>0) {
			hraci[medik].zivotu = hraci[medik].funkce[fnmedik].num;
			medik = -1;
		}
	}
	if (atomovka >=0 && atomovka < nhracu){
		if (hraci[atomovka].zivotu >= 0 && hraci[atomovka].zivotu < nhracu && hraci[atomovka].funkce[fnatomovka].num==1){
			int *zdroj, *cil;
			zdroj = malloc(sizeof(int));
			zdroj[0] = atomovka;
			cil = malloc(sizeof(int)*2);
			cil[0] = -1;
			cil[1] = -1;
			i = atomovka;
			while(1){
				i = hraci[i].predchozi;
				if (i==atomovka){
					i = -1;
					break;
				}
				if (hraci[i].zivotu <= 0) continue;
				if (hraci[i].zivotu >= 0){
					cil[0] = i;
					break;
				}
			}
			if (i>=0){
				i = atomovka;
				while(1){
					i = hraci[i].nasledujici;
					if (hraci[i].zivotu <= 0) continue;
					if (i==cil[0]){
						i = -1;
						break;
					}
					if (hraci[i].zivotu >= 0){
						cil[1] = i;
						break;
					}
				}
				add_effect(ZABIT, 1, zdroj, 2, cil);
			}
			cil = malloc(sizeof(int));
			cil[0] = atomovka;
			add_effect(ZABIT, 1, zdroj, 1, cil);
			hraci[atomovka].funkce[fnatomovka].num = 2;
			solve_effects();
		}
	}

	// změnit studené mrtvoly na teplé mrtvoly
	for (i=0;i<nteplych_mrtvol){
		if (hraci[teple_mrtvoly[i]].zivotu > 0) continue;		// došlo k oživení
		studene_mrtvoly[nstudenych_mrtvol++] = teple_mrtvoly[i];
		printf("Hráč %i – %s se stává studenou mrtvolou.", i, hraci[i].jmeno);
	}
	nteplych_mrtvol = 0;
	// změnit hráče s nekladným počtem životů na teplé mrtvoly
	for (i=0;i<nhracu;i++){
		if (hraci[i].zivotu < 1){
			ok = 1;
			for (j=0;j<nstudenych_mrtvol;j++){
				if (studene_mrtvoly[j]==i){
					ok = 0;
					break;
				}
			}
			if (ok==1){
				teple_mrtvoly[nteplych_mrtvol++] = i;
				printf("Hráč %i – %s umírá a stává se teplou mrtvolou.", i, hraci[i].jmeno);
			}
		}
	}
}

void den(){
	char c;
	int tmp;
	int konec_kola = 0;

	rano();		// sem patří efekty typu výbuch atomovky, ožívá medik

	printf("Začíná den číslo %i.\n", kolo);
	vypis_info();
	do{
		printf("Co se děje?\n");
		printf("\t[a] hlasujeme\n");
		printf("\t[b] jdeme spát\n");
		printf("\t[c] hvězdář vyhlásil noc\n");
		printf("\t[d] odpal atomovky\n");
		printf("\t[e] anarchista háže kostkou\n");
		printf("\t[f] potřebuji vypsat info o hráčích\n");
		printf("\t[g] neexistuje možnost, jak by mohl někdo někoho zabít\n");
		fflush(stdout);
		c=getch();
		printf("zadáno %c\n", c);
		switch(c){
			case 'a':
				hlasovani();
				solve_effects();
				break;
			case 'b':
				konec_kola = 1;
				break;
			case 'c':
				if (hvezdar >= 0 && hvezdar < nhracu){
					if (hraci[hvezdar].funkce[fnhvezdar].num == 0){
						hraci[hvezdar].funkce[fnhvezdar].num++;
						konec_kola = 1;
					}
				}
				break;
			case 'd':
				if (oppenheimer >= 0 && oppenheimer < nhracu && atomovka >=0 && atomovka < nhracu){
					if (hraci[oppenheimer].funkce[fnoppenheimer].num == 0){
						hraci[atomovka].funkce[fnatomovka].num++;
						hraci[oppenheimer].funkce[fnoppenheimer].num++;
					}
			}
			break;
			case 'e':
				if (anarchista >= 0 && anarchista < nhracu){
					if (hraci[anarchista].funkce[fnanarchista].num == 0){
						tmp = ask_int("Na koho hodil kostku?");
						add_effect(ZABIT, 1, &anarchista, 1, &tmp);
						solve_effects();
						hraci[anarchista].funkce[fnanarchista].num++;
					}
				}
				break;
			case 'f':
				vypis_info();
				break;
			case 'g':
				konec_hry();
				konec_kola=1;
				break;
		}
	}while(konec_kola==0);
	kolo++;
}

void noc(){
	st_hrac *hrac;
	int i, j, k, l;
	int ncile, *cil, nzdroj, *zdroj; 
	int spatne;
	st_udalost presun;		// úchyl může generovat dvě události
	int presouva;
	char *tmp, *tmp2;

	// probudit postavy a zjisit, jestli využijí svou funkci

	// medik
	printf("Probouzí se medik. ");
	j = najdi_postavu(MEDIK, 0);
	if (j>=0 && j<nhracu){
		hrac = &hraci[j];

		if (hrac->funkce->num == 0){
			if (ask_bool("Chce se zasebevraždit?")){
				hrac->funkce->num = hrac->zivotu;
				hrac->zivotu = 0;
			}
		}
		else {
			printf("Chce se zasebevraždit? (Nechce, už nemůže.)\n");
		}
	}
	else {
		printf("(Medik není.)\n");
	}

	// slina
	j = najdi_postavu(SLINA, 0);
	printf("Slina sliní. ");
	if (j>=0 && j<nhracu){
		hrac = &hraci[j];
		if (hrac->zivotu > 0) {
			cil = malloc(sizeof(int));
			zdroj = malloc(sizeof(int));
			zdroj[0] = j;
			do {
				spatne = 1;
				printf("Na koho sliní?");
				printf(" Zadejte číslo hráče:\n");
				for (i=0;i<nhracu;i++){
					if (i==j || hraci[i].zivotu <= 0) continue;
					printf("\t[%i] %s\n", i, hraci[i].jmeno);
				}
				scanf("%i", cil);
				if (cil[0]!=j && cil[0] >= 0 && cil[0] < nhracu && hraci[cil[0]].zivotu > 0){
					printf("Sliní na hráče číslo %i – %s. ", cil[0], hraci[cil[0]].jmeno);
					spatne = 0;
				}
				else {
					printf("Špatná volba. ");
				}
			} while(spatne || ask_bool("Je to ok?")==0);
			if (spatne == 0){
				add_event(SLINI, 1, zdroj, 1, cil);
			}
		}
		else {
			printf("(Slina nesliní.)\n");
		}
	}
	else {
		printf("(Slina není.)\n");
	}

	// mágové
	for (k=1;k<3;k++){
		j = najdi_postavu(MAG, k);
		printf("Mág %i máguje. ", k);
		if (j>=0 && j<nhracu){
			hrac = &hraci[j];
			if (hrac->zivotu > 0) {
				cil = malloc(sizeof(int));
				zdroj = malloc(sizeof(int));
				do {
					spatne = 1;
					printf("Z koho přesměrovává?");
					printf(" Zadejte číslo hráče:\n");
					for (i=0;i<nhracu;i++){
						if (i==j || hraci[i].zivotu <= 0) continue;
						printf("\t[%i] %s\n", i, hraci[i].jmeno);
					}
					scanf("%i", zdroj);
					printf("Na koho přesměrovává?");
					printf(" Zadejte číslo hráče:\n");
					for (i=0;i<nhracu;i++){
						if (hraci[i].zivotu <= 0) continue;
						printf("\t[%i] %s\n", i, hraci[i].jmeno);
					}
					scanf("%i", cil);
					if (zdroj[0]!=j && zdroj[0] >= 0 && zdroj[0] < nhracu
						&& cil[0] >=0 && cil[0]<nhracu &&
						hraci[zdroj[0]].zivotu > 0 &&
						hraci[cil[0]].zivotu > 0){
						printf("Přesměruje z hráče číslo %i – %s na hráče č. %i – %s. ", zdroj[0], hraci[zdroj[0]].jmeno, cil[0], hraci[cil[0]].jmeno);
						spatne = 0;
					}
					else {
						printf("Špatná volba. ");
					}
				} while(spatne || ask_bool("Je to ok?")==0);
				if (spatne == 0){
					add_event(PRESMERUJE, 1, zdroj, 1, cil);
				}
			}
			else {
				printf("(Mág nemáguje.)\n");
			}
		}
		else {
			printf("(Mág %i není.)\n", k);
		}
	}

	// mafiáni
	printf("Mafiáni střílí.\n");
	zdroj = malloc(sizeof(int)*3);
	zdroj[0] = najdi_postavu(MAFIAN, 1);
	zdroj[1] = najdi_postavu(MAFIAN, 2);
	zdroj[2] = najdi_postavu(MAFIAN, 3);
	if ((zdroj[0] >= 0 && zdroj[0] < nhracu && hraci[zdroj[0]].zivotu > 0) ||
		(zdroj[1] >= 0 && zdroj[1] < nhracu && hraci[zdroj[1]].zivotu > 0) ||
		(zdroj[2] >= 0 && zdroj[2] < nhracu && hraci[zdroj[2]].zivotu > 0) ) {
		printf("Postupně se probouzí mafiáni a ukáží, na koho střílí.\n");
		cil = malloc(sizeof(int));
		do {
			spatne = 1;
			printf("Shodli se mafiáni?");
			printf(" Zadejte číslo hráče:\n");
			for (i=0;i<nhracu;i++){
				if (hraci[i].zivotu <= 0) continue;
				printf("\t[%i] %s\n", i, hraci[i].jmeno);
			}
			printf("\t[%i] mafiáni se neshodli.\n", nhracu);
			scanf("%i", cil);
			if (cil[0] >= 0 && cil[0] < nhracu+1 && hraci[cil[0]].zivotu > 0){
				printf("Střílí na hráče číslo %i – %s. ", cil[0], hraci[cil[0]].jmeno);
				spatne = 0;
			}
			else if (cil[0] == nhracu){
				printf("Mafiáni se neshodli. ");
			}
			else {
				printf("Špatná volba. ");
			}
		} while(spatne || ask_bool("Je to ok?")==0);
		if (spatne == 0){
			add_event(STRILI, 3, zdroj, 1, cil);
		}
	}
	else {
		printf("(Mafiáni nestřílí.)\n");
	}


	// úchylové
	for (k=1;k<3;k++){
		j = najdi_postavu(UCHYL, k);
		printf("Úchyl %i úchylí. ", k);
		if (j>=0 && j<nhracu){
			hrac = &hraci[j];
			if (hrac->zivotu > 0) {
				cil = malloc(sizeof(int));
				zdroj = malloc(sizeof(int));
				zdroj[0] = j;
				do {
					spatne = 1;
					presouva = 0;
					printf("Koho úchylí? ");
					printf(" Zadejte číslo hráče:\n");
					for (i=0;i<nhracu;i++){
						if (hraci[i].zivotu <= 0) continue;
						printf("\t[%i] %s\n", i, hraci[i].jmeno);
					}
					scanf("%i", cil);
					ask_string("Co provede? (Max. 512 znaků.)\n", uchylarny[k-1]);
					if(ask_bool("Má úchylárna efekt přesunu hráče? (Tj. dojde ke změně sousedů daného hráče?)\n")){
						presouva = 1;
						presun.zdroj = malloc(sizeof(int));
						presun.zdroj = cil;
						presun.nzdroj = 1;
						presun.cil = malloc(sizeof(int)*2);
						presun.typ = PRESOUVA;
						tmp = malloc(sizeof(char)*256);
						do {
							l=-1;
							printf("Kam se přesune?");
							vypis_hrace();
							fflush(stdout);
							__fpurge(stdin);
							printf("Zadejte čísla nových sousedů oddělená mezerou:\n");
							fgets(tmp, 256, stdin);
							tmp2 = tmp;
							while(*tmp2){
								if (*tmp2 == '\n'){
									*tmp2 = ' ';
								}
								tmp2++;
							}
							tmp2 = tmp;
							strcat(tmp, " ");
							while (l < 2 && *tmp){
								presun.cil[++l] = strtol(tmp, &tmp, 10);
								if (*tmp != ' ')
									break;
								tmp++;
							}
							printf("Noví sousedé:");
							for (i=0;i<2;i++){
								printf("\thráč č. %i – %s\n", presun.cil[i], hraci[presun.cil[i]].jmeno);
							}
						} while(ask_bool("Je to ok?")==0);
					}
					if (cil[0] >=0 && cil[0]<nhracu &&
						hraci[cil[0]].zivotu > 0){
						printf("Úchylí hráče číslo %i – %s a provede mu: %s. ", zdroj[0], hraci[zdroj[0]].jmeno, uchylarny[k]);
						spatne = 0;
					}
					else {
						printf("Špatná volba. ");
					}
				} while(spatne || ask_bool("Je to ok?")==0);
				if (spatne == 0){
					add_event(UCHYLI, 1, zdroj, 1, cil);
					if (presouva){
						if (presun.cil[0] < nhracu && presun.cil[0] >= 0
							&& presun.cil[1] < nhracu && presun.cil[1] >= 0){
							add_event(PRESOUVA, 1, presun.zdroj, 2, presun.cil);
						}
					}
				}
			}
			else {
				printf("(Úchyl neúchylí.)\n");
			}
		}
		else {
			printf("(Úchyl %i není.)\n", k);
		}
	}

	// zabiják/ponožky
	if (kolo % 2 == 1){	// zabiják
		j = najdi_postavu(ZABIJAK, 0);
		printf("Zabiják střílí. ");
		if (j>=0 && j<nhracu){
			hrac = &hraci[j];
			if (hrac->zivotu > 0) {
				cil = malloc(sizeof(int));
				zdroj = malloc(sizeof(int));
				zdroj[0] = j;
				do {
					spatne = 1;
					printf("Na koho střílí?");
					printf(" Zadejte číslo hráče:\n");
					for (i=0;i<nhracu;i++){
						printf("\t[%i] %s\n", i, hraci[i].jmeno);
					}
					scanf("%i", cil);
					if (cil[0] >= 0 && cil[0] < nhracu && hraci[cil[0]].zivotu > 0){
						printf("Střílí na hráče číslo %i – %s. ", cil[0], hraci[cil[0]].jmeno);
						spatne = 0;
					}
					else {
						printf("Špatná volba. ");
					}
				} while(spatne || ask_bool("Je to ok?")==0);
				if (spatne == 0){
					add_event(STRILI, 1, zdroj, 1, cil);
				}
			}
			else {
				printf("(Zabiják nestřílí.)\n");
			}
		}
		else {
			printf("(Zabiják není.)\n");
		}
	}
	else{		// ponožky
		j = najdi_postavu(PONOZKY, 0);
		printf("Ponožky smrdí. ");
		if (j>=0 && j<nhracu){
			hrac = &hraci[j];
			if (hrac->zivotu > 0) {
				cil = malloc(sizeof(int));
				zdroj = malloc(sizeof(int));
				zdroj[0] = j;
				do {
					spatne = 1;
					printf("Na koho smrdí?");
					printf(" Zadejte číslo hráče:\n");
					i = j;
					while(1){
						i = hraci[i].predchozi;
						if (i==j){
							i = -1;
							break;
						}
						if (hraci[i].zivotu <= 0) continue;
						printf("\t[%i] %s\n", i, hraci[i].jmeno);
						if (hraci[i].zivotu >= 0) break;
					}
					if (i<0) {
						printf("Ponožky už nemají na koho smrdět.\n");
						break;
					} else{
						i = j;
						while(1){
							i = hraci[i].nasledujici;
							if (hraci[i].zivotu <= 0) continue;
							if (i==j){
								i = -1;
								break;
							}
							printf("\t[%i] %s\n", i, hraci[i].jmeno);
							if (hraci[i].zivotu >= 0) break;
						}
						scanf("%i", cil);
						if (cil[0]!=j && cil[0] >= 0 && cil[0] < nhracu && hraci[cil[0]].zivotu > 0){
							printf("Smrdí na hráče číslo %i – %s. ", cil[0], hraci[cil[0]].jmeno);
							spatne = 0;
						}
						else {
							printf("Špatná volba. ");
						}
					}
				} while(spatne || ask_bool("Je to ok?")==0);
				if (spatne == 0){
					add_event(SMRDI, 1, zdroj, 1, cil);
				}
			}
			else {
				printf("(Ponožky nesmrdí.)\n");
			}
		}
		else {
			printf("(Ponožky nejsou.)\n");
		}
	}

	// šaman
	j = najdi_postavu(SAMAN, 0);
	printf("Šaman šamaní.\n");
	if (j>=0 && j<nhracu){
		hrac = &hraci[j];
		if (hrac->zivotu > 0 && nteplych_mrtvol > 0 && hrac->funkce->num==0) {
			cil = malloc(sizeof(int));
			zdroj = malloc(sizeof(int));
			zdroj[0] = j;
			do {
				spatne = 1;
				printf("Koho oživí?");
				printf(" Zadejte číslo hráče:\n");
				for (i=0;i<nteplych_mrtvol;i++){
					if (hraci[teple_mrtvoly[i]].zivotu > 0) continue;
					printf("\t[%i] %s\n", teple_mrtvoly[i], hraci[teple_mrtvoly[i]].jmeno);
				}
				scanf("%i", cil);
				if (cil[0]!=j && cil[0] >= 0 && cil[0] < nhracu && hraci[cil[0]].zivotu > 0){
					printf("Oživuje hráče číslo %i – %s. ", cil[0], hraci[cil[0]].jmeno);
					spatne = 0;
				}
				else {
					printf("Špatná volba. ");
				}
			} while(spatne || ask_bool("Je to ok?")==0);
			if (spatne == 0){
				hraci[cil[0]].zivotu = 1;
				hrac->funkce->num++;
				free(zdroj);
				free(cil);
			}
		}
		else {
			printf("(Šaman nešamaní.)\n");
		}
	}
	else {
		printf("(Šaman není.)\n");
	}
	// v tuto chvíli se teplé mrtvoly stávají studenými
	nteplych_mrtvol = 0;

	solve_events();		// a na závěr přeložíme události na efekty
}

void vypis_vysledky(){
	vypis_info();
}

int main(){
	int hra_pokracuje = 1;
	init_faze();
	do {
		den();
		noc();
	} while (hra_pokracuje);
	vypis_vysledky();
}
