// File: /workspace/github_cpp_makefile_star2_O3/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 0x6fc0
xorl %edi, %edi
callq 0x20e0
movl %eax, %edi
callq 0x20f0
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
movl $0x1, %esi
movl $0x1, %edx
callq 0x3406
movq %rbx, %rdi
movl $0x1, %esi
callq 0x3466
leaq -0x158(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2dac
callq 0x8b5b
testb %al, %al
je 0x2b5e
callq 0x9118
movq %rsp, -0xf0(%rbp)
movl %eax, %ecx
movq %rsp, %rdx
movq %rcx, -0x88(%rbp)
leaq 0xf(,%rcx,8), %rcx
andq $-0x10, %rcx
subq %rcx, %rdx
movq %rdx, -0x48(%rbp)
movq %rdx, %rsp
movq %rax, -0x40(%rbp)
testl %eax, %eax
jle 0x25df
xorl %ebx, %ebx
leaq -0x130(%rbp), %r12
movq -0x48(%rbp), %r14
movl $0x58, %edi
callq 0x2110
movq %rax, %r15
leaq 0x1(%rbx), %r13
movq %r12, %rdi
movl %r13d, %esi
callq 0x9353
movq %r15, %rdi
movq %r12, %rsi
movl $0x32, %edx
movl $0xa, %ecx
movl %r13d, %r8d
callq 0x7618
movq %r15, (%r14,%rbx,8)
movq -0x130(%rbp), %rdi
leaq -0x120(%rbp), %rax
cmpq %rax, %rdi
je 0x25c8
movq -0x120(%rbp), %rsi
incq %rsi
callq 0x2120
movq (%r14,%rbx,8), %r15
leaq -0x158(%rbp), %rax
movq %rax, 0x50(%r15)
movq %r13, %rbx
cmpq %r13, -0x88(%rbp)
jne 0x256a
callq 0x7248
movq -0x40(%rbp), %rbx
leal 0x1(%rbx), %eax
imull %ebx, %eax
movl %eax, %ecx
shrl $0x1f, %ecx
addl %eax, %ecx
sarl %ecx
incl %ecx
leaq -0x60(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
movl %ebx, %r8d
callq 0x3ba6
movl %ebx, -0x30(%rbp)
leaq -0x98(%rbp), %rax
movq %rax, -0x10(%rax)
leaq 0x79e6(%rip), %rsi      # 0xa004
leaq 0x79e4(%rip), %rdx      # 0xa009
leaq -0xa8(%rbp), %rdi
callq 0x2d0e
movq 0xf998(%rip), %r15      # 0x11fd0
leaq 0xc216(%rip), %r12      # 0xe855
movq -0x48(%rbp), %r14
cmpl $0x0, -0x40(%rbp)
jle 0x2643
movl -0x30(%rbp), %eax
xorl %r13d, %r13d
cmpl $0x2, %eax
jl 0x2a4e
movq (%r14,%r13,8), %rdi
testq %rdi, %rdi
je 0x2a2e
callq 0x7728
testb %al, %al
je 0x2a2e
movq -0x48(%rbp), %rax
leaq (%rax,%r13,8), %rbx
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dc2
movl %eax, %r14d
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dcc
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
movl $0x1, %ecx
callq 0x3bfa
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x36fc
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dc2
movl %eax, %r14d
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dcc
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
xorl %ecx, %ecx
callq 0x3bfa
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dc2
movl %eax, %r14d
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dcc
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
callq 0x3412
movl %eax, %r14d
leaq -0xd8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xa8(%rbp), %rsi
movq -0xa0(%rbp), %rdx
addq %rsi, %rdx
leaq -0xe8(%rbp), %rdi
callq 0x2c70
xorl %edx, %edx
cmpl $0x1, %r14d
setne %dl
movq %rbx, %rdi
leaq -0xe8(%rbp), %rsi
callq 0x3c85
movq -0xe8(%rbp), %rdi
leaq -0xd8(%rbp), %rax
cmpq %rax, %rdi
je 0x2771
movq -0xd8(%rbp), %rsi
incq %rsi
callq 0x2120
leaq -0xb8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xa8(%rbp), %rsi
movq -0xa0(%rbp), %rdx
addq %rsi, %rdx
leaq -0xc8(%rbp), %rdi
callq 0x2c70
leaq -0xc8(%rbp), %rdi
callq 0x9a6f
movl %eax, %r14d
movq -0xc8(%rbp), %rdi
leaq -0xb8(%rbp), %rax
cmpq %rax, %rdi
je 0x27cd
movq -0xb8(%rbp), %rsi
incq %rsi
callq 0x2120
movq (%rbx), %rdi
cmpb $0x78, %r14b
jne 0x2821
movq 0x50(%rdi), %rdi
callq 0x2dc2
movl %eax, %r14d
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dcc
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
callq 0x3412
cmpl $0x1, %eax
jne 0x28b1
movq (%rbx), %rdi
callq 0x8088
movl %eax, %edi
callq 0x5c11
movb $0x1, %al
movl %eax, -0x2c(%rbp)
xorl %r14d, %r14d
jmp 0x28ff
movsbl %r14b, %esi
leaq -0x60(%rbp), %rdx
leaq -0x158(%rbp), %rcx
callq 0x7734
movl %eax, -0x34(%rbp)
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dc2
movl %eax, %r14d
movq (%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2dcc
leaq -0x60(%rbp), %rdi
movl %r14d, %esi
movl %eax, %edx
callq 0x3412
cmpl $0x2, %eax
jl 0x28a5
callq 0x9968
testb %al, %al
je 0x28a5
movq -0x48(%rbp), %rsi
movq (%rsi,%r13,8), %rdi
subq $0x8, %rsp
leaq -0x60(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl %r13d, %r8d
leaq -0x158(%rbp), %r9
leaq -0x30(%rbp), %rax
pushq %rax
callq 0x7a3a
addq $0x10, %rsp
movl %eax, %r14d
movb $0x1, %al
movl %eax, -0x2c(%rbp)
jmp 0x2906
xorl %r14d, %r14d
movl $0x0, -0x2c(%rbp)
jmp 0x2906
callq 0x9968
xorl %r14d, %r14d
movl $0x0, -0x34(%rbp)
movl $0x0, -0x2c(%rbp)
testb %al, %al
je 0x2906
movq -0x48(%rbp), %rsi
movq (%rsi,%r13,8), %rdi
subq $0x8, %rsp
leaq -0x60(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl %r13d, %r8d
leaq -0x158(%rbp), %r9
leaq -0x30(%rbp), %rax
pushq %rax
callq 0x7a3a
addq $0x10, %rsp
movl %eax, %r14d
movb $0x1, %al
movl %eax, -0x2c(%rbp)
movl $0x0, -0x34(%rbp)
movq (%rbx), %rdi
callq 0x7728
movq (%rbx), %rsi
testb %al, %al
je 0x29a6
testq %rsi, %rsi
je 0x29fe
movl $0x12, %edx
movq %r15, %rdi
leaq 0x76fe(%rip), %rsi      # 0xa02f
callq 0x2140
movq (%rbx), %rsi
leaq -0x80(%rbp), %rdi
callq 0x76d6
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
movq %r15, %rdi
callq 0x2140
movl $0x2, %edx
movq %rax, %rdi
leaq 0xbef3(%rip), %rsi      # 0xe854
callq 0x2140
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x297f
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x2120
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x36fc
movl -0x34(%rbp), %eax
orb -0x2c(%rbp), %al
movl $0x25, %ebx
je 0x2a68
leaq 0x769e(%rip), %rsi      # 0xa042
jmp 0x2a17
leaq -0x110(%rbp), %rdi
callq 0x76d6
leaq -0x110(%rbp), %rdi
movl %r14d, %esi
callq 0x6d83
movq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rax
cmpq %rax, %rdi
je 0x29e3
movq -0x100(%rbp), %rsi
incq %rsi
callq 0x2120
movq (%rbx), %rdi
leaq -0x60(%rbp), %rsi
callq 0x79e2
movq (%rbx), %rax
xorl %ecx, %ecx
movq %rcx, 0x50(%rax)
movq %rcx, (%rbx)
decl -0x30(%rbp)
movl $0x24, %ebx
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x36fc
leaq 0x75f3(%rip), %rsi      # 0xa00a
movq %r15, %rdi
movq %rbx, %rdx
callq 0x2140
movq 0xf5b7(%rip), %rdi      # 0x11fe0
callq 0x2160
movl $0x28, %ebx
movq -0x48(%rbp), %r14
movl $0x1, %edx
movq %r15, %rdi
movq %r12, %rsi
callq 0x2140
decl %ebx
jne 0x2a37
movl -0x30(%rbp), %eax
cmpl $0x1, %eax
je 0x2a7d
incq %r13
cmpq -0x88(%rbp), %r13
jne 0x264f
jmp 0x2643
movq 0xf571(%rip), %rdi      # 0x11fe0
callq 0x2230
leaq 0x75c7(%rip), %rsi      # 0xa042
jmp 0x2a17
xorl %r12d, %r12d
leaq 0x75e1(%rip), %r13      # 0xa068
leaq 0x75e3(%rip), %rbx      # 0xa071
movq 0xf54b(%rip), %r15      # 0x11fe0
cmpq $0x0, (%r14,%r12,8)
je 0x2b17
leaq -0x60(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x36fc
callq 0x7475
movq (%r14,%r12,8), %rsi
leaq -0x80(%rbp), %rdi
callq 0x76d6
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
movq 0xf506(%rip), %rdi      # 0x11fd0
callq 0x2140
movq %rax, %r14
movl $0x8, %edx
movq %rax, %rdi
movq %r13, %rsi
callq 0x2140
movl $0x21, %edx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2140
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x2b0b
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x2120
movq %r15, %rdi
callq 0x2160
movq -0x48(%rbp), %r14
incq %r12
cmpq %r12, -0x88(%rbp)
jne 0x2a95
leaq -0x60(%rbp), %rdi
movl $0x1, %esi
callq 0x34b2
movq -0xa8(%rbp), %rdi
leaq -0x98(%rbp), %rax
cmpq %rax, %rdi
je 0x2b57
movq -0x98(%rbp), %rsi
incq %rsi
callq 0x2120
movq -0xf0(%rbp), %rsp
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2c43
movq %rax, %rbx
jmp 0x2c68
jmp 0x2c43
movq %rax, %rbx
movq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rax
cmpq %rax, %rdi
je 0x2c46
movq -0x100(%rbp), %rsi
jmp 0x2c37
jmp 0x2c23
movq %rax, %rbx
movq -0xc8(%rbp), %rdi
leaq -0xb8(%rbp), %rax
cmpq %rax, %rdi
je 0x2c46
movq -0xb8(%rbp), %rsi
jmp 0x2c37
movq %rax, %rbx
movq -0xe8(%rbp), %rdi
leaq -0xd8(%rbp), %rax
cmpq %rax, %rdi
je 0x2c46
movq -0xd8(%rbp), %rsi
jmp 0x2c37
jmp 0x2c43
movq %rax, %rbx
jmp 0x2c17
movq %rax, %rbx
movq -0x130(%rbp), %rdi
leaq -0x120(%rbp), %rax
cmpq %rax, %rdi
je 0x2c17
movq -0x120(%rbp), %rsi
incq %rsi
callq 0x2120
movl $0x58, %esi
movq %r15, %rdi
jmp 0x2c63
jmp 0x2c43
movq %rax, %rbx
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x2c46
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x2120
jmp 0x2c46
jmp 0x2c43
movq %rax, %rbx
movq -0xa8(%rbp), %rdi
leaq -0x98(%rbp), %rax
cmpq %rax, %rdi
je 0x2c68
movq -0x98(%rbp), %rsi
incq %rsi
callq 0x2120
movq %rbx, %rdi
callq 0x2210