// File: /workspace/github_cpp_makefile_star2_O2/giovifazi[P]knossos-bloodbath/main.cpp
// Function: main
int main()
{
   	printTitle();

   	srand(time(0));        // Random seed per partite pseudocasuali

	Map map_game(1,1);     // Creo una mappa con w=1 e h=1 ma ancora vuota
	map_game.init(1);      // Inizializza la mappa con valore 1 nella posizione (0,0)
	Node node_orig(0,0);   // Creo il nodo iniziale

	//Controllo se i giocatori vogliono giocare
  	if (!loadMenu())
		return 0;		

	int NP = setPlayers();        	//imposto il numero di giocatori

	Player *players[NP];	      	   //creo n giocatori in array dinamico

	for (int i=0; i<NP; i++)      	//inizializzo tutti i giocatori
	{
		players[i] = new Player(setName(i+1),50,10,i+1);   // setName e` nel Menu.cpp
		players[i]->pos = &node_orig;                      // imposto la posizione di tutti giocatori nel nodo iniziale
	}

   // Stampa grafica e narrazione di entrata nel labirinto
   printEntrance();

   // Metto nella mappa grafica la somma dei numeri assegnati ai players
	map_game.changeValue(0,0, ((NP*(NP+1))/2) +1, NP);

	// Inizio vera e propria partita
	char cmd_player;		         // carattere di input del giocatore
	int alive_players = NP;		   // Numero di giocatori in vita
	std::string allwd_mov = "nseox";   // stringa con i caratteri validi per giocare

   int z;                  // in base al valore di z stampo un hud differente
   int death;              // controlla se un giocatore e' morto di "morte naturale" o se in seguito ad un combattimento
   bool mov_newn;          // controlla movimento verso un nodo esistente o appena creato
   bool ignore = false;    // controlla per stabilire se usare cin.ignore o meno 

	// Loop dei turni
	while (true)
	{
		// Scorre array giocatori per far eseguire i turni
		for (int j=0; j<NP; j++)
		{
			// Fa turni finche` non c e` un solo vincitore
			if (alive_players > 1)
			{
				//Fa fare il turno solo ai giocatori ancora in vita
				if (players[j] != NULL && players[j]->is_alive())
				{
	       death=0;		//reimposto la morte naturale, durante i turni precedenti potrebbe essere stata cambiata
               map_game.set_Turn(players[j]->pos->get_x(), players[j]->pos->get_y(),true); // Imposta nella mappa dove stampare le {} per il turno corrente
					map_game.draw(NP);				
					map_game.set_Turn(players[j]->pos->get_x(), players[j]->pos->get_y(),false);// Toglie nella mappa dove avviene il turno corrente

               if (map_game.getPresAt(players[j]->pos->get_x(), players[j]->pos->get_y())!= 1)
                  z=1;     // se nel nodo c'e' un solo player indico che x e` per cercare oggetti 
               else 
                  z=0;     // ..per combattere altrimenti


					hud_print(players[j], allwd_mov, z);			// Stampa comandi player
					cmd_player = get_player_input(allwd_mov);    // filtra input giocatore e lo ritorna in cmd_player, get_player_input e` in game.cpp
	
					if (cmd_player == 'x')  // Se esamino/combatto
               {	
                  ignore = true;    // stampa ignore per comodita gameplay
						
						//Se c`e' un solo giocatore nella stanza, esamina la stanza
						if (map_game.getPresAt(players[j]->pos->get_x(), players[j]->pos->get_y())== 1)
                     hud_action(players[j]->diceRoll_or());   // Lancia il dado per esaminare stanze visitate, diceRoll_or() mi restituisce un'intero per la stampa hud_action
						//Altrimenti decide se combattere
						else
						if (battleChoice()) {
								death=players[j]->engage_battle(&players[0],  map_game, NP, j, node_orig, alive_players);
                        ignore = true;
                  }
else { ignore = false;}
               }
					//Se l'input e' un azione di movimento (n s e o)
					else
               {
						//Muove il giocatore secondo l'input
						mov_newn = players[j]->Player_move(cmd_player, map_game, node_orig);
										
						//Controllo se ci sono altri giocatori nel nodo in cui mi sto muovendo
						if (map_game.getPresAt(players[j]->pos->get_x(), players[j]->pos->get_y()) > 1)
						{
							if (battleChoice()){    // battleChoice fa scegliere se combattere
								death=players[j]->engage_battle(&players[0],  map_game, NP, j, node_orig, alive_players );					
					         ignore = true;
					      } else { ignore = false; }
                  }

               }

                                        
					//Controllo eventuale morte del giocatore[j] alla fine del suo turno
					if (!players[j]->is_alive())
					{
                  hud_death(players[j]->getName(), death);  // Grafica della morte

						players[j]->remove_from_map(map_game);    // Rimuove il simbolo dalla mappa grafica
						players[j]->pos = NULL;                   // cancella il puntatore della pos ai nodi
						players[j] = NULL;                        // cancella il puntatore a giocatore
                  
                  alive_players--;                          // Segna un giocatore vivo in meno
					}
           
               // FINE TURNO stampo mappa per rispettare le specifiche del progetto

               if (players[j]==NULL)                            //caso in cui il giocatore sia morto durante il suo turno
               {
                  map_game.draw(NP);               
                  std::cout << "\n\nPremi invio per terminare il turno";
                  std::cin.get();
               }
               else 
               {
                  std::cout << "Fine del turno di " << players[j]->getName() << "\n\n";
                  map_game.draw(NP);
          

 
	  	// Evita di dover premere due volte invio a fine turno in certi casi
	  	if (!(mov_newn /*|| map_game.getPresAt(players[j]->pos->get_x(), players[j]->pos->get_y()) > 1*/))
                     if (!ignore)
			std::cin.ignore(); 
                  
                  std::cout << "\n\nPremi invio per terminare il turno ";
                  std::cin.get();
               }
               
               // reimposto queste variabili per cin.ignore
               ignore = false;
               mov_newn = false;
            }

            // Spazi per separare grafica
            for (int r=0; r < 40; r++)
               std::cout << "\n";

         }// if alive_players > 1
	
		   if (alive_players == 1)    // In caso di vittoria di un giocatore
         {			   
            // scorre l array di giocatori per trovare quello che ha vinto
            for (int j=0; j<NP; j++)
            {
               if (players[j] != NULL)
               {  
                  // Stampa mappa con ultimo sopravvissuto
                  map_game.draw(NP);
                 
                  // Stampa grafica e narrazione di uscita dal labirinto
				  printExit();

				  std::cout
                  << players[j]->getName() << " vince!\n"
                  << "Premi invio per chiudere il gioco";
                 
                  std::cin.get();
               }
            }
           
            // Cancella la mappa di gioco con garbage collection
            map_game.delete_map(true);
            return 0;
        
         }//if alive_players ==1
	   
	   }//for j=0.. np.. etc
  	
  	}//while true
 

   return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
callq 0x5d23
xorl %r13d, %r13d
xorl %edi, %edi
callq 0x2100
movl %eax, %edi
callq 0x2110
leaq -0x60(%rbp), %rbx
pushq $0x1
popq %r14
movq %rbx, %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x31d8
movq %rbx, %rdi
movl %r14d, %esi
callq 0x3238
leaq -0xe0(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2bec
callq 0x7180
testb %al, %al
je 0x2a80
callq 0x74f3
movq %rsp, -0x78(%rbp)
movl %eax, %ecx
movq %rsp, %rdx
leaq 0xf(,%rcx,8), %rcx
andq $-0x10, %rcx
subq %rcx, %rdx
movq %rdx, -0x48(%rbp)
movq %rdx, %rsp
testl %eax, %eax
movl $0x0, %ecx
movq %rax, -0x40(%rbp)
cmovgl %eax, %ecx
movq %rcx, -0x68(%rbp)
leaq -0x160(%rbp), %r12
movq -0x48(%rbp), %rbx
cmpq %r13, -0x68(%rbp)
je 0x25b9
pushq $0x58
popq %rdi
callq 0x2130
movq %rax, %r14
leaq 0x1(%r13), %r15
movq %r12, %rdi
movl %r15d, %esi
callq 0x7678
movq %r14, %rdi
movq %r12, %rsi
pushq $0x32
popq %rdx
pushq $0xa
popq %rcx
movl %r15d, %r8d
callq 0x6100
movq %r14, (%rbx,%r13,8)
movq %r12, %rdi
callq 0x2080
movq (%rbx,%r13,8), %rax
leaq -0xe0(%rbp), %rcx
movq %rcx, 0x50(%rax)
movq %r15, %r13
jmp 0x2565
callq 0x5e24
movq -0x40(%rbp), %rbx
leal 0x1(%rbx), %eax
imull %ebx, %eax
pushq $0x2
popq %rcx
cltd
idivl %ecx
leal 0x1(%rax), %ecx
leaq -0x60(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
movl %ebx, %r8d
callq 0x383a
movl %ebx, -0x38(%rbp)
leaq 0x5a19(%rip), %rsi      # 0x8004
leaq -0xb8(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x2b10
xorl %eax, %eax
movq 0xd9c9(%rip), %r15      # 0xffd0
leaq 0xa247(%rip), %r12      # 0xc855
movq %rax, %r13
movl $0x0, %eax
cmpq -0x68(%rbp), %r13
je 0x260e
movl -0x38(%rbp), %ecx
cmpl $0x2, %ecx
jl 0x29c9
movq -0x48(%rbp), %rax
movq (%rax,%r13,8), %rdi
testq %rdi, %rdi
je 0x29b1
callq 0x61e6
testb %al, %al
je 0x29b1
movq -0x48(%rbp), %rax
leaq (%rax,%r13,8), %rax
movq %rax, -0x30(%rbp)
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c02
movl %eax, %r14d
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c0c
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
pushq $0x1
popq %rcx
callq 0x388e
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x3452
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c02
movl %eax, %r14d
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c0c
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
xorl %ecx, %ecx
callq 0x388e
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c02
movl %eax, %r14d
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c0c
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
callq 0x31e4
movl %eax, %r14d
leaq -0x140(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x21d0
xorl %edx, %edx
cmpl $0x1, %r14d
setne %dl
movq -0x30(%rbp), %rdi
leaq -0x140(%rbp), %r14
movq %r14, %rsi
callq 0x3907
movq %r14, %rdi
callq 0x2080
leaq -0x120(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x21d0
leaq -0x120(%rbp), %rbx
movq %rbx, %rdi
callq 0x7ade
movl %eax, %r14d
movq %rbx, %rdi
callq 0x2080
movq -0x30(%rbp), %rax
movq (%rax), %rdi
cmpb $0x78, %r14b
jne 0x27ba
movq 0x50(%rdi), %rdi
callq 0x2c02
movl %eax, %r14d
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c0c
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
callq 0x31e4
cmpl $0x1, %eax
jne 0x2852
movq -0x30(%rbp), %rax
movq (%rax), %rdi
callq 0x6954
movl %eax, %edi
callq 0x4e65
movb $0x1, %al
movl %eax, -0x34(%rbp)
xorl %r14d, %r14d
jmp 0x289c
movsbl %r14b, %esi
leaq -0x60(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
callq 0x61f2
movl %eax, %ebx
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c02
movl %eax, %r14d
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2c0c
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
callq 0x31e4
xorl %r14d, %r14d
cmpl $0x2, %eax
jl 0x2849
callq 0x7a0c
xorl %r14d, %r14d
testb %al, %al
je 0x2849
movq -0x48(%rbp), %rsi
movq (%rsi,%r13,8), %rdi
subq $0x8, %rsp
leaq -0x60(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl %r13d, %r8d
leaq -0xe0(%rbp), %r9
leaq -0x38(%rbp), %rax
pushq %rax
callq 0x64c0
popq %rcx
popq %rdx
movl %eax, %r14d
movb $0x1, %al
movl %eax, -0x34(%rbp)
jmp 0x289e
movl $0x0, -0x34(%rbp)
jmp 0x289e
callq 0x7a0c
xorl %r14d, %r14d
movl $0x0, %ebx
movl $0x0, -0x34(%rbp)
testb %al, %al
je 0x289e
movq -0x48(%rbp), %rsi
movq (%rsi,%r13,8), %rdi
subq $0x8, %rsp
leaq -0x60(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl %r13d, %r8d
leaq -0xe0(%rbp), %r9
leaq -0x38(%rbp), %rax
pushq %rax
callq 0x64c0
popq %rcx
popq %rdx
movl %eax, %r14d
movb $0x1, %al
movl %eax, -0x34(%rbp)
xorl %ebx, %ebx
movq -0x30(%rbp), %rax
movq (%rax), %rdi
callq 0x61e6
movq -0x30(%rbp), %rcx
movq (%rcx), %rsi
testb %al, %al
je 0x2940
testq %rsi, %rsi
je 0x2989
movq %r15, %rdi
leaq 0x5763(%rip), %rsi      # 0x802f
callq 0x2120
movq %rax, %r14
movl %ebx, -0x6c(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rsi
leaq -0x98(%rbp), %rbx
movq %rbx, %rdi
callq 0x61a6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x20f0
movq %rax, %rdi
leaq 0x9f52(%rip), %rsi      # 0xc854
callq 0x2120
movq %rbx, %rdi
callq 0x2080
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x3452
movl -0x6c(%rbp), %eax
orb -0x34(%rbp), %al
leaq 0x5719(%rip), %rsi      # 0x8042
jne 0x299d
movq 0xd6ae(%rip), %rdi      # 0xffe0
callq 0x2240
leaq 0x5704(%rip), %rsi      # 0x8042
jmp 0x299d
leaq -0x100(%rbp), %rdi
callq 0x61a6
leaq -0x100(%rbp), %rbx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x5b6c
movq %rbx, %rdi
callq 0x2080
movq -0x30(%rbp), %rax
movq (%rax), %rdi
leaq -0x60(%rbp), %rsi
callq 0x646a
movq -0x30(%rbp), %rcx
movq (%rcx), %rax
andq $0x0, 0x50(%rax)
andq $0x0, (%rcx)
decl -0x38(%rbp)
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x3452
leaq 0x566d(%rip), %rsi      # 0x800a
movq %r15, %rdi
callq 0x2120
movq 0xd634(%rip), %rdi      # 0xffe0
callq 0x2170
pushq $0x28
popq %rbx
subl $0x1, %ebx
jb 0x29c6
movq %r15, %rdi
movq %r12, %rsi
callq 0x2120
jmp 0x29b4
movl -0x38(%rbp), %ecx
incq %r13
movq %r13, %rax
cmpl $0x1, %ecx
jne 0x260e
xorl %r14d, %r14d
leaq -0x98(%rbp), %r15
leaq 0x567f(%rip), %r13      # 0x8068
leaq 0x5681(%rip), %rbx      # 0x8071
movq 0xd5e9(%rip), %r12      # 0xffe0
cmpq %r14, -0x68(%rbp)
je 0x2a64
movq -0x48(%rbp), %rax
cmpq $0x0, (%rax,%r14,8)
je 0x2a5f
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x3452
callq 0x5fca
movq -0x48(%rbp), %rax
movq (%rax,%r14,8), %rsi
movq %r15, %rdi
callq 0x61a6
movq 0xd59f(%rip), %rdi      # 0xffd0
movq %r15, %rsi
callq 0x20f0
movq %rax, %rdi
movq %r13, %rsi
callq 0x2120
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2120
movq %r15, %rdi
callq 0x2080
movq %r12, %rdi
callq 0x2170
incq %r14
jmp 0x29f7
leaq -0x60(%rbp), %rdi
pushq $0x1
popq %rsi
callq 0x3280
leaq -0xb8(%rbp), %rdi
callq 0x2080
movq -0x78(%rbp), %rsp
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2af8
movq %rax, %rbx
jmp 0x2b07
jmp 0x2af8
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x2aef
jmp 0x2ae5
movq %rax, %rbx
leaq -0x120(%rbp), %rdi
jmp 0x2aef
movq %rax, %rbx
leaq -0x140(%rbp), %rdi
jmp 0x2aef
jmp 0x2af8
movq %rax, %rbx
jmp 0x2ad6
movq %rax, %rbx
leaq -0x160(%rbp), %rdi
callq 0x2080
pushq $0x58
popq %rsi
movq %r14, %rdi
callq 0x2140
jmp 0x2b07
jmp 0x2af8
movq %rax, %rbx
leaq -0x98(%rbp), %rdi
callq 0x2080
jmp 0x2afb
jmp 0x2af8
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
callq 0x2080
movq %rbx, %rdi
callq 0x2220
nop