motores continuam jogando o mesmo jogo


8

Acabei de escrever a personalização de um mecanismo de xadrez, basicamente adicionando um bitboard ao mecanismo tscp disponível gratuitamente. Agora estou testando no winboard e percebo que muitas vezes as duas máquinas jogam o mesmo jogo várias vezes em uma partida. Eu gostaria de adicionar alguma variedade aos jogos, pelo menos, escolhendo movimentos iguais aleatoriamente. Estou apenas usando a pesquisa alfa-beta com ordenação de movimentos simples. Estou pensando em adicionar um pequeno número aleatório aos nós das folhas para romper os laços, mas eu realmente não gosto dessa solução, porque alguns dos bônus menores que a função de avaliação usa são de 3 a 5 centipawns. Portanto, não tenho "espaço" suficiente para o número aleatório romper os laços.

meu outro pensamento era fazer com que o mecanismo escolhesse aleatoriamente o que manter quando encontrasse uma avaliação == alfa. Eu realmente não gosto disso porque suspeito que favorece os movimentos ordenados em último lugar na pesquisa.

A pergunta é como posso escolher aleatoriamente os nós das folhas com a mesma pontuação? e também uniformemente?

Respostas:


7

Nota:

É uma boa ideia para o seu motor ser determinístico. Não há motivo para selecionar um movimento aleatoriamente. Você faria isso apenas para diminuir a força do seu motor. Se você tornar seu mecanismo não determinístico, será muito difícil depurar e reproduzir um bug. Minha recomendação é não fazer isso.

Você não deve modificar seu mecanismo. Você pode usar um livro de abertura e escolher uma linha aleatoriamente. Muitas interfaces gráficas de xadrez podem fazer isso, por exemplo, o software CuteChess . A GUI da Arena também pode fazer isso.

Mas se você insistir:

Vamos dar uma olhada no código fonte do Stockfish .

 Move Skill::pick_best(size_t multiPV) {

    const RootMoves& rootMoves = Threads.main()->rootMoves;
    static PRNG rng(now()); // PRNG sequence should be non-deterministic

    // RootMoves are already sorted by score in descending order
    Value topScore = rootMoves[0].score;
    int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg);
    int weakness = 120 - 2 * level;
    int maxScore = -VALUE_INFINITE;

    // Choose best move. For each move score we add two terms, both dependent on
    // weakness. One is deterministic and bigger for weaker levels, and one is
    // random. Then we choose the move with the resulting highest score.
    for (size_t i = 0; i < multiPV; ++i)
    {
        // This is our magic formula
        int push = (  weakness * int(topScore - rootMoves[i].score)
                    + delta * (rng.rand<unsigned>() % weakness)) / 128;

        if (rootMoves[i].score + push > maxScore)
        {
            maxScore = rootMoves[i].score + push;
            best = rootMoves[i].pv[0];
        }
    }

    return best;   }
  • O Stockfish inicia o multi-PV (não é suportado no TSCP, então você precisará codificá-lo!)
  • Calcule um número aleatório e adicione-o à pontuação de cada PV
  • Compare cada PV ponderado e escolha o melhor

Você pode achar úteis os seguintes links:

Recomendação: Não faça isso a menos que queira enfraquecer seu mecanismo.


a abordagem do livro funcionou muito bem, obrigado! Publiquei uma pergunta de acompanhamento sobre tabelas de transposição e matrizes triangulares.
Nak3c
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.