text: #include "dominoModel.h"
  
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <stdbool.h>
  #include <time.h>
  
  void embaralharPecas(peca pedras[], peca aux[]){
      srand(time(NULL));
      int r;
  
      for (int i=0; i < 28; i++){
          r = rand() % 28;
  
          aux[0] = pedras[i];
          pedras[i] = pedras[r];
          pedras[r] = aux[0];
      }
  }
  
  /*
      Busca a primeira peca das pecas n�o compradas do tabuleiro e retorna a posicao desta.
      A partir dai a funcao comprarPeca assume.
  */
  
  int pecaAleatoria(peca pedras[]){
      int pecaComprada;
      bool sentinela = false;
  
  
      for(int i = 0; i < 28; i++){
          if(pedras[i].comprada != true && sentinela != true){
             pecaComprada = pedras[i].posicaoPeca;
             sentinela = true;
          }
      }
  
      return pecaComprada;
  }
  
  /*
          Caso eu embaralhe as pecas, o iniciarPecas tratara de alocar as posicoes adequadamente, para nao haver
          confusao.
          Ex:
          Antes de embaralhar a peca 0|0 estara na posicao 0. Digamos que ela foi para a posicao 7, se nao tivesse
          adequado as posicoes novamente, ela ainda estaria na posicao 0, interferindo no programa
  */
  
  void iniciaPeca(peca pedras[], int opcaoInicial){
  
  
      int cont = 0;
  
      if(opcaoInicial == 0){
      for(int i = 0; i < 7; i++){
          for(int j = i; j < 7; j++){
              pedras[cont].comprada = false;
              pedras[cont].posicaoPeca = cont;
              pedras[cont].ladoEsquerdo = i;
              pedras[cont].ladoDireto = j;
              cont++;
              }
          }
      }
  
      else if(opcaoInicial == 1){
          cont = 0;
          for(int a = 0; a < 7; a++){
          for(int b = a; b < 7; b++){
              pedras[cont].posicaoPeca = cont;
              cont++;
              }
          }
      }
  }
  
  /*Funcao apenas para dar scan*/
  
  int obterOpcao(){
      int opt;
      tabulacao();
      scanf("%d", &opt);
      return opt;
  }
  
  /*
      Distribui as 7 primeiras pecas do peca pedras (0-6), sejam elas embaralhadas ou nao, ao primeiro jogador
      Depois distribui as outras 7 para o jogador 2 (7-13). Ao criar essa alocacao, ja setam as pecas como compradas
  */
  
  void distribuirPeca(peca pedras[], peca jogador_1[], peca jogador_2[]){
      int contador = 0, j, i;
      int maiorPecaJogo;
  
      /*
          A distribuicao de pecas ocorre conforme a posicao das pecas quando iniciamos a funcao iniciarPecas()
          ou seja, a peca 0|0 estara na posicao 0
      */
  
  
      for(contador; contador <= 6; contador++){
           pedras[contador].comprada = true;
          jogador_1[contador] = pedras[contador];
      }
      j = contador;
  
      jogador_1[0].qtdPecas = j-1;
      jogador_1[0].contador = contador; //Aloca na posi��o 0 do jogador o contador, pra poder servir de referencia na aloca��o da compra
  
       for(i = 0; i <= 6; contador++, i++){
          pedras[contador].comprada = true;
          jogador_2[i] = pedras[contador];
          jogador_2[i].posicaoPeca = i;
      }
  
      /*
          pecasTabuleiro serve como parametro para printar as pecas na funcao printaPecasTabuleiro, pois
          comeca a printar de 27 a 14
          E .contador serve para indicar at� quando devo printar na funcao printaPecasJogador e tamb�m serve para
          alocar determinada peca no proximo espaco do Array ao comprar uma peca
      */
  
      pedras[0].pecasTabuleiro = 27-13;
      jogador_2[0].contador = i;
      jogador_2[0].qtdPecas = i-1;
  }
  /*
  
  */
  int comprarPeca(peca pedras[], peca jogador[], int opcao){
      int contador = jogador[0].contador;
  
      bool aceito = false;
  
      if (pedras[opcao].comprada != true){
  
          /*
              Atribuindo determinada peca do tabuleiro para a peca do jogador e colocando a peca do tabuleiro
              como comprada, para n�o haver interferencia
          */
  
          pedras[opcao].comprada = true;
          jogador[contador] = pedras[opcao];
          jogador[contador].posicaoPeca = contador;
  
          /*
              Essas opcoes de .contador e .pecasTabuleiro s�o apenas parametros na hora de printar as pecas do jogador
              e as pecas do tabuleiro
              O .contador tamb�m serve para alocar em determinado espaco do Array a peca comprada
          */
  
          jogador[0].contador++;
          jogador[0].qtdPecas++;
          jogador[1].contador++;
          pedras[0].pecasTabuleiro--;
          aceito = true;
      }
  
      return aceito;
  }
  /*
      Funcao acionada apenas se a verificao da peca for 1. Seta alguns parametros como jogada, coloca ela na struct mesa,
      diminui a quantidade de pecas na mao do jogador e muda o indice para a proxima peca ser alocada
  */
  bool alocarPecaMesaJogador(mesa pecasMesas[], peca jogador[], int posicao, int lado){
      int verificador;
      bool jogadaValida;
  
      verificador = verificaLadoPeca(pecasMesas, jogador, posicao, lado);
  
      if(verificador == 1){
          if(jogador[0].qtdPecas > 0){
              if(lado == 1){
                  pecasMesas[pecasMesas[0].qtdEsquerda].ladoDireito = jogador[posicao].ladoDireto;
                  pecasMesas[pecasMesas[0].qtdEsquerda].ladoEsquerdo = jogador[posicao].ladoEsquerdo;
                  pecasMesas[pecasMesas[0].qtdEsquerda].temPeca = true;
                  jogador[posicao].jogadaTabuleiro = true;
                  jogador[1].contador--;
                  pecasMesas[0].qtdEsquerda--;
              }
          else if(lado == 2){
                  pecasMesas[pecasMesas[0].qtdDireita].ladoDireito = jogador[posicao].ladoDireto;
                  pecasMesas[pecasMesas[0].qtdDireita].ladoEsquerdo = jogador[posicao].ladoEsquerdo;
                  pecasMesas[pecasMesas[0].qtdDireita].temPeca = true;
                  jogador[posicao].jogadaTabuleiro = true;
                  jogador[1].contador--;
                  pecasMesas[0].qtdDireita++;
  
              }
          }
          pecasMesas[0].qtdPecas++;
      }
      else{
          return jogadaValida = false;
      }
      return jogadaValida = true;
  }
  
  void iniciaMesa(mesa pecaMesa[]){
      for(int i = 0; i < 61; i++){
          pecaMesa[i].temPeca = false;
      }
  
  }
  /*
      Funcao que verifica a peca que o usuario quer jogar na mesa. Verifica tanto no lado direito quanto no lado esquerdo
      Caso a peca esteja virada ao contrario, faz essa mudanca automatica da peca
  */
  int verificaLadoPeca(mesa pecaMesa[], peca jogador[], int posicao, int lado){
      int verificador = 0;
      int indiceEsquerdo;
      int indiceDireito;
      int auxiliarPeca = 0; //Auxilia ao trocar os lados da peca
  
  
      indiceDireito = pecaMesa[0].qtdDireita-1;
      indiceEsquerdo = pecaMesa[0].qtdEsquerda+1;
  
      if(jogador[posicao].jogadaTabuleiro == false){
          if(lado == 1){
              if(pecaMesa[indiceEsquerdo].ladoEsquerdo == jogador[posicao].ladoDireto){
                  verificador = 1;
              }else if(pecaMesa[indiceEsquerdo].ladoEsquerdo == jogador[posicao].ladoEsquerdo){
                  auxiliarPeca = jogador[posicao].ladoEsquerdo;
                  jogador[posicao].ladoEsquerdo = jogador[posicao].ladoDireto;
                  jogador[posicao].ladoDireto = auxiliarPeca;
                  verificador = 1;
              }
  
          }
          if(lado == 2){
              if(pecaMesa[indiceDireito].ladoDireito == jogador[posicao].ladoEsquerdo){
                  verificador = 1;
              }
  
              else if(pecaMesa[indiceDireito].ladoDireito == jogador[posicao].ladoDireto){
                  auxiliarPeca = jogador[posicao].ladoEsquerdo;
                  jogador[posicao].ladoEsquerdo = jogador[posicao].ladoDireto;
                  jogador[posicao].ladoDireto = auxiliarPeca;
                  verificador = 1;
              }
          }
      }
      return verificador;
  }
  /*Funcao para setar todas as pecas ainda como se nao fossem jogadas no tabuleiro*/
  
  void jogadasTabuleiro(peca jogador[], peca jogador_2[]){
      for(int i = 0; i < 28; i++){
          jogador[i].jogadaTabuleiro = false;
          jogador_2[i].jogadaTabuleiro = false;
      }
  }
  
  /*
      Basicamaente faz uma busca linear por todas as pecas, buscando as dobradas. Se existir dobrada na mao dos jogadores faz comparacoes
      retornando a maior. Se nao existir, busca sequencialmente a maior peca que nao e dobrada e retorna a posicao dela.
  */
  
  int maiorPeca(peca jogador[], peca jogador_2[], int qualJogador[])
  {
      int i = 0, ladoEsq = 0, ladoDir = 0, posicaoMaior_jog1, posicaoMaior_jog2, posicaoMaior; //Pecas nao dobradas
      int posicaoIguais_1, posicaoIguais_2; //Para pecas dobradas
      bool achou_1 = false, achou_2 = false; //Para pecas dobradas
      int posicaoFinal;
      int dobradaMaior = -1, dobradaMaior_2= -1;
  
      for(i; i <= 6; i++)
      {
          //Verifica se existem pecas dobradas no jogador
          if(jogador[i].ladoEsquerdo == jogador[i].ladoDireto)
          {
              if(dobradaMaior < jogador[i].ladoEsquerdo){
                  dobradaMaior = jogador[i].ladoEsquerdo;
                  posicaoIguais_1 = i;
              }
              achou_1 = true;
          }
          if(jogador_2[i].ladoEsquerdo == jogador_2[i].ladoDireto)
          {
              if(dobradaMaior_2 < jogador_2[i].ladoEsquerdo){
                  dobradaMaior_2 = jogador_2[i].ladoEsquerdo;
                  posicaoIguais_2 = i;
              }
              achou_2 = true;
          }
      }
          if(achou_1 == false && achou_2 == false)
          {
              //Verifica se a peca i, é maior que a peca i+1, e atribui a posicaoMaior a i caso ache. Caso não for nenhuma
              //Coloca a posicao 6 como a maior em ambos os lados
              for(i = 0; i < 6; i++){
                  if(i < 6)
                  {
                      if(jogador[i].ladoEsquerdo > jogador[i+1].ladoEsquerdo || jogador[i].ladoDireto > jogador[i+1].ladoDireto)
                      {
                          posicaoMaior_jog1 = i;
                      }
                      if(jogador_2[i].ladoEsquerdo > jogador[i+1].ladoEsquerdo || jogador_2[i].ladoDireto > jogador[i+1].ladoDireto)
                      {
                          posicaoMaior_jog2 = i;
                      }
                      else
                      {
                          posicaoMaior_jog1 = 6;
                          posicaoMaior_jog2 = 6;
                      }
                  }
              }
          }
  
      if(achou_1 == true || achou_2 == true){
          if(achou_1 == true &&  achou_2 == true){
              if(jogador[posicaoIguais_1].ladoDireto > jogador_2[posicaoIguais_2].ladoDireto){
                      posicaoFinal = posicaoIguais_1;
                      qualJogador[0] = 1;
              }else{
                  posicaoFinal = posicaoIguais_2;
                  qualJogador[0] = 2;
              }
          }
          else if(achou_1 == true && achou_2 == false){
              qualJogador[0] = 1;
          }
          else if(achou_2 == true && achou_1 == false){
              qualJogador[0] = 2;
          }
      }
      else{
          //Caso os lados esquerdos sejam diferentes, verificar qual lado é maior, e atribuir posicaoFinal a este
          if(jogador[posicaoMaior_jog1].ladoEsquerdo != jogador_2[posicaoMaior_jog2].ladoEsquerdo){
              if(jogador[posicaoMaior_jog1].ladoEsquerdo > jogador_2[posicaoMaior_jog2].ladoEsquerdo){
                  posicaoFinal = posicaoMaior_jog1;
                  qualJogador[0] = 1;
              }
              else{
                  posicaoFinal = posicaoMaior_jog2;
                  qualJogador[0] = 2;
              }
          }
          //caso os lados esquerdos sejam iguais, verificar qual dos direitos é maior, e atribuir posicaoFinal a este
          if(jogador[posicaoMaior_jog1].ladoEsquerdo == jogador_2[posicaoMaior_jog2].ladoEsquerdo){
              if(jogador[posicaoMaior_jog1].ladoDireto > jogador_2[posicaoMaior_jog2].ladoDireto){
                  posicaoFinal = posicaoMaior_jog1;
                  qualJogador[0] = 1;
              }
              else{
                  posicaoFinal = posicaoMaior_jog2;
                  qualJogador[0] = 2;
              }
          }
      }
      return posicaoFinal;
  }
  
  /*
      Funcao que aloca a maior peca dos jogadores
  
      Colcoa na posicao mesaJogo[30], que é o meio do array da mesa, e atribui essa peca alguns valores como comprada e jogada no
      tabuleiro
      qualJogador == 1 -> Jogador 1
      qualJogador == 2 -> Jogador 2
  */
  
  void alocaMaiorPeca(int maiorPecaJogo, mesa mesaJogo[], int qualJogador[], peca jogador[], peca jogador_2[]){
  
      if(qualJogador[0] == 1){
          mesaJogo[30].ladoDireito = jogador[maiorPecaJogo].ladoDireto;
          mesaJogo[30].ladoEsquerdo = jogador[maiorPecaJogo].ladoEsquerdo;
          jogador[maiorPecaJogo].comprada = true;
          jogador[maiorPecaJogo].jogadaTabuleiro = true;
          jogador[1].contador--;
  
      }else if(qualJogador[0] == 2){
          mesaJogo[30].ladoDireito = jogador_2[maiorPecaJogo].ladoDireto;
          mesaJogo[30].ladoEsquerdo = jogador_2[maiorPecaJogo].ladoEsquerdo;
          jogador_2[maiorPecaJogo].comprada = true;
          jogador_2[maiorPecaJogo].jogadaTabuleiro = true;
          jogador_2[1].contador--;
      }
  
      mesaJogo[30].temPeca = true;
      mesaJogo[0].qtdPecas = 1;
  }
  
  bool jogadorGanhou(peca jogador[]){
      bool ganhou = false;
  
      if(jogador[1].contador == 0){
          ganhou = true;
      }
      return ganhou;
  }
  
  /*
      Funcao principal para a jogada do computador
      Basicamente percorre todos as pecas do jogador_comp, e ao achar a primeira peca compativel ele sai do loop,
      sendo atribuindo ao jogadorPC os lados e as posicoes
      No loop verificamos cada peca do lado 1 e depois do lado 2
  */
  
  void jogarPecaComputador(peca jogador_comp[], mesa pecaMesa[], peca pedras[], computer jogadorPC[]){
      int verificador, lado, i;
      bool passar;
  
      for(i = 0; i <= jogador_comp[0].contador-1; i++){
          verificador = verificaLadoPeca(pecaMesa, jogador_comp, i, 1);
          //Gambiarra para melhorar depois, para sair do for
          if(verificador == 1)
          {
              jogadorPC[0].posicaoPeca = i;
              lado = 1;
              i = jogador_comp[0].contador-1;
          }
      }
  
      //Lado esquerdo do tabuleiro
      if(verificador != 1){
         for(i = 0; i <= jogador_comp[0].contador-1; i++){
          verificador = verificaLadoPeca(pecaMesa, jogador_comp, i, 2);
          //Gambiarra para melhorar depois, para sair do for
          if(verificador == 1)
          {
              jogadorPC[0].posicaoPeca = i;
              lado = 2;
              i = jogador_comp[0].contador-1;
          }
      }
      }
  
      jogadorPC[0].lado = lado;
  
      //Se não conseguiu achar nenhuma peca, ele compra
      while(verificador == 0){
          comprarPeca(pedras, jogador_comp, pecaAleatoria(pedras));
          verificador = verificaUltimaPecaPC(pecaMesa, jogador_comp, jogadorPC);
          if(pedras[0].pecasTabuleiro == 0){
              verificador = 2;
              passar = passarVez(jogadorPC, pecaMesa, pedras);
          }
      }
  
      if(verificador == 1){
          alocarPecaMesaJogador(pecaMesa, jogador_comp, jogadorPC[0].posicaoPeca, jogadorPC[0].lado);
      }
  }
  
  /*
      Vai apenas ser usado quando não achar pecas na mao e quando for comprar
      jogadorPC.lado jogadorPC.posicaoPeca é atribuido qual lado e qual a posicao da peca deve ser alocada na mesa
  */
  int verificaUltimaPecaPC(mesa pecasMesa[], peca jogador_comp[], computer jogadorPC[]){
      int posicaoPeca = jogador_comp[0].contador-1;
      int verificador;
  
  
      //Verifica lado Esquerdo
      verificador = verificaLadoPeca(pecasMesa, jogador_comp, posicaoPeca, 1);
      jogadorPC[0].lado = 1;
  
  
      //Verificado lado Direito
      if(verificador == 0){
         verificador = verificaLadoPeca(pecasMesa, jogador_comp, posicaoPeca, 2);
         jogadorPC[0].lado = 2;
      }
  
      jogadorPC[0].posicaoPeca = posicaoPeca;
  
      return verificador;
  }
  
  /*
      Faz uma busca sequencial ate achar a primeira peca da mao que e possivel jogar, se achar sai do loop, se nao vai para
      a o lado direito do tabuleiro e faz o mesmo
      Retorna true caso ache alguma peca ou se ainda tiver pecas a comprar
  */
  
  bool passarVez(peca jogador[], mesa pecaMesa[], peca tabuleiro[]){
      int i = 0;
      bool temPeca = false;
      int verificador;
  
      /* Lado Esquerdo */
      if(tabuleiro[0].pecasTabuleiro == 0)
      {
          for(i = 0; i <= 27; i++)
          {
              if(jogador[i].jogadaTabuleiro == false)
              {
                  verificador = verificaLadoPeca(pecaMesa, jogador, i, 1);
                  if(verificador == 1)
                  {
                      temPeca = true;
                      i = jogador[0].contador-1;
                  }
              }
          }
  
      /*Se nao achou nenhuma peca compativel no primeiro for. Agora vai pro lado direito*/
      if(temPeca == false){
              /* Lado Direito */
              for(i = 0; i <= 27; i++)
              {
                  if(jogador[i].jogadaTabuleiro == false)
                  {
                      verificador = verificaLadoPeca(pecaMesa, jogador, i, 2);
                      if(verificador == 1)
                      {
                          temPeca = true;
                          i = jogador[0].contador-1;
                      }
                  }
              }
          }
      }
  
      /*Se ainda tiver peca pra jogar ou se ainda tiver pecas para coomprar*/
      if(!temPeca || tabuleiro[0].pecasTabuleiro != 0){
          naoPassa();
          temPeca = true;
          return temPeca;
      }
      else{
          return temPeca;
      }
  }
  