Exemplo n.º 1
0
 /// <summary>
 /// Avalia a Dama.
 /// </summary>
 /// <remarks>
 /// Mobilidade e ataques a casas perto ao rei pode ser addicionada.
 /// </remarks>
 /// <param name="pontuacao">Pontuação do lado branco ou preto</param>
 /// <param name="indice">Índice da casa da dama</param>
 private void AvaliaDama(Pontuacao pontuacao, int indice)
 {
     Fase -= Pontuacao.Fase.DAMA;
     pontuacao.Inicial += Pontuacao.Material.DAMA_INICIO;
     pontuacao.Final   += Pontuacao.Material.DAMA_FINAL;
     pontuacao.Final   += Pontuacao.Tabela.CENTRALIZACAO[Defs.Converte12x12Para8x8(indice)] / 2;
 }
Exemplo n.º 2
0
 /// <summary>
 /// Avalia o bispo.
 /// </summary>
 /// <remarks>
 /// Vai tentar centralizar o bispo.
 /// Outro item que pode ser adicionado é uma relação com os próprios peões,
 /// não estando no quadrado da mesma cor do bispo.
 /// </remarks>
 /// <param name="pontuacao">Pontuação do lado branco ou preto</param>
 /// <param name="indice">Índice da casa do bispo</param>
 private void AvaliaBispo(Pontuacao pontuacao, int indice)
 {
     Fase -= Pontuacao.Fase.BISPO;
     pontuacao.Inicial += Pontuacao.Material.BISPO_INICIO;
     pontuacao.Inicial += Pontuacao.Tabela.CENTRALIZACAO[Defs.Converte12x12Para8x8(indice)];
     pontuacao.Final   += Pontuacao.Material.BISPO_FINAL;
     pontuacao.Final   += Pontuacao.Tabela.CENTRALIZACAO[Defs.Converte12x12Para8x8(indice)];
 }
Exemplo n.º 3
0
 /// <summary>
 /// Avalia o Rei.
 /// </summary>
 /// <remarks>
 /// Apenas dá um bônus para peões na frente do rei, ou seja, escudo de peão (pawn shield).
 /// O que pode ser adicionado é uma penalidade para muitos peões inimigos perto do rei, o que
 /// significa que um ataque de peão está se formando.
 /// Especialmente em termos de segurança do rei, se as peças inimigas estão atacando a área próxima ao rei,
 /// pode ser um grande valor a este item. Em geral a segurança do rei é difícil de calibrar corretamente e
 /// requer muitos testes.
 /// Além disso, algo a considerar é a presença da dama inimiga ao avaliar a segurança do rei. Sem a dama o
 /// valor da segurança do rei reduz drasticamente.
 /// </remarks>
 /// <param name="pontuacao">Pontuação do lado branco ou preto</param>
 /// <param name="indice">Índice da casa do rei</param>
 /// <param name="dados_rei">Informação relativa à cor a ser avaliada.</param>
 private void AvaliaRei(Pontuacao pontuacao, int indice, DadosRei dados_rei)
 {
     for (int i = 0; i < dados_rei.DirecaoEmFrente.Length; i++)
     {
         if (Tabuleiro.ObtemPeca(indice + i) == dados_rei.PeaoAmigo)
         {
             pontuacao.Inicial += Pontuacao.Rei.PEAO_ESCUDO;
         }
     }
     pontuacao.Inicial += dados_rei.TabelaInicio[Defs.Converte12x12Para8x8(indice)];
 }
Exemplo n.º 4
0
 /// <summary>
 /// Avalia peões pretos.
 /// </summary>
 /// <see cref="AvaliaPeaoBranco(int)"/>
 /// <param name="indice">Índice da casa do peão</param>
 private void AvaliaPeaoPreto(int indice)
 {
     Fase          -= Pontuacao.Fase.PEAO;
     Preto.Inicial += Pontuacao.Material.PEAO_INICIO;
     Preto.Inicial += Pontuacao.Tabela.PEAO_PRETO[Defs.Converte12x12Para8x8(indice)];
     if (indice == (int)Defs.INDICE.D5 || indice == (int)Defs.INDICE.E5)
     {
         Preto.Inicial += Pontuacao.Peao.PEAO_CENTRAL_1;
     }
     if (indice == (int)Defs.INDICE.D6 || indice == (int)Defs.INDICE.E6)
     {
         Preto.Inicial += Pontuacao.Peao.PEAO_CENTRAL_2;
     }
     Preto.Final += Pontuacao.Material.PEAO_FINAL;
     Preto.Final += Pontuacao.Tabela.PEAO_PRETO[Defs.Converte12x12Para8x8(indice)];
 }
Exemplo n.º 5
0
 /// <summary>
 /// Avalia peões brancos.
 /// </summary>
 /// <remarks>
 /// Valor material, valor na casa de acordo com uma tabela e bônus de centralização.
 /// Outros termos que podems ser adicionados:
 /// Peões passados: bônus para peões que não podem ser capturados por peões inimigos.
 /// Peões isolados: penalidade para peões sem peões amigos em colunas vizinhas.
 /// Peões conectados: bônus para peões que se apoiam.
 /// Peões duplicados: penalidade para peões na mesma coluna.
 /// Peões para trás: penalidade para peões que não podem avançar sem encontrar os peões inimigos.
 /// Peões candidatos: bônus para peões que podem se tornar passados.
 /// Outra idéia é armazenar o valor da estrutura de peões em uma tabela, e quando encontramos
 /// a mesma estrutura de peões mais tarde, podemos usar o valor calculado dessa tabela. Isso ajuda
 /// o desempenho, pois a estrutura do peão pode repetir muito em uma pesquisa.
 /// Neste caso, podemos usar uma chave zobrist para a estrutura do peão. Normalmente, isso é
 /// chamado de "pawn hash table".
 /// </remarks>
 /// <param name="indice">Índice da casa do peão</param>
 private void AvaliaPeaoBranco(int indice)
 {
     Fase           -= Pontuacao.Fase.PEAO;
     Branco.Inicial += Pontuacao.Material.PEAO_INICIO;
     Branco.Inicial += Pontuacao.Tabela.PEAO_BRANCO[Defs.Converte12x12Para8x8(indice)];
     if (indice == (int)Defs.INDICE.D4 || indice == (int)Defs.INDICE.E4)
     {
         Branco.Inicial += Pontuacao.Peao.PEAO_CENTRAL_1;
     }
     if (indice == (int)Defs.INDICE.D3 || indice == (int)Defs.INDICE.E3)
     {
         Branco.Inicial += Pontuacao.Peao.PEAO_CENTRAL_2;
     }
     Branco.Final += Pontuacao.Material.PEAO_FINAL;
     Branco.Final += Pontuacao.Tabela.PEAO_BRANCO[Defs.Converte12x12Para8x8(indice)];
 }
Exemplo n.º 6
0
        /// <summary>
        /// Retorna a lista ordenada de movimentos.
        /// </summary>
        /// <remarks>
        /// Ordem de classificação:
        /// 1. Movimento melhor vindo da tabela de transposição.
        /// 2. Capturas
        /// 3. Movimentos simples classificados pela tabela de valores.
        ///
        /// Falta aqui os movimentos matadores (killer moves). Quase todos os programas de xadrez
        /// usam esta técnica. Eu me pergunto se alguém poderia fazer isso e se faria o Enxadrista
        /// um pouco melhor.
        /// </remarks>
        /// <param name="cor">Cor do lado com movimentos a ordenar.</param>
        /// <param name="lista">List de movimentos.</param>
        /// <param name="melhor">Melhor movimento que será ordenado primeiro, normalmente da tabela de transposição</param>
        /// <returns>Lista ordenada de movimentos.</returns>
        public List <Movimento> Orderna(Cor cor, List <Movimento> lista, Movimento melhor)
        {
            foreach (var movimento in lista)
            {
                if (movimento.Equals(melhor))
                {
                    movimento.ValorOrdenacao = 100000000;
                    continue;
                }
                if (movimento.Captura())
                {
                    movimento.ValorOrdenacao = ValorCaptura(movimento) * 10000;
                    continue;
                }
                int indice_peca = IndicePeca(movimento.Peca);
                int indice_casa = Defs.Converte12x12Para8x8(movimento.IndiceDestino);
                movimento.ValorOrdenacao = Tabela[indice_peca][indice_casa];
            }

            return(lista.OrderByDescending(m => m.ValorOrdenacao).ToList());
        }
Exemplo n.º 7
0
        /// <summary>
        /// Atualiza informação sempre que um bom movimento é encontrada.
        /// </summary>
        /// <remarks>
        /// Note que consideramos somente os movimentos simples. Captura já possui
        /// um valor maior do que movimentos simples.
        /// </remarks>
        /// <param name="cor">Cor do lado fazendo o movimento.</param>
        /// <param name="movimento">Movimento considerado bom.</param>
        /// <param name="profundidade">Profundidade que o movimento foi pesquisado.</param>
        public void AtualizaHistoria(Cor cor, Movimento movimento, int profundidade)
        {
            if (movimento.Tatico())
            {
                return;
            }

            int indice_peca = IndicePeca(movimento.Peca);
            int indice_casa = Defs.Converte12x12Para8x8(movimento.IndiceDestino);

            Tabela[indice_peca][indice_casa] += profundidade;

            // Se o valor na tabela estiver muito alto, é feito um ajuste a todos valores.
            if (Tabela[indice_peca][indice_casa] > 9000)
            {
                for (int peca = 0; peca < NUMERO_PECAS; peca++)
                {
                    for (int casa = 0; casa < NUMERO_CASAS; casa++)
                    {
                        Tabela[peca][casa] /= 8;
                    }
                }
            }
        }