i motori continuano a giocare allo stesso gioco


8

Ho appena finito di scrivere personalizzando un motore di scacchi aggiungendo sostanzialmente un bitboard al motore tscp disponibile gratuitamente. Ora lo sto provando su winboard e noto che spesso le due macchine giocheranno lo stesso gioco più volte in una partita. Vorrei aggiungere un po 'di varietà ai giochi facendogli almeno scegliere mosse uguali a caso. Sto solo usando la ricerca alpha-beta con un semplice ordinamento delle mosse. Sto pensando di aggiungere un piccolo numero casuale ai nodi foglia per rompere i legami, ma non mi piace molto questa soluzione perché alcuni dei bonus più piccoli che la funzione di valutazione utilizza sono 3-5 centesimi. Quindi non ho abbastanza "spazio" per un numero casuale per interrompere i legami.

l'altro mio pensiero era di scegliere il motore in modo casuale che si muovesse per mantenere quando ha trovato una valutazione == alfa. Non mi piace molto perché sospetto che favorisca le mosse ordinate per ultime nella ricerca.

La domanda è: come posso scegliere casualmente tra i nodi foglia uguali? e anche in modo uniforme?

Risposte:


7

Nota:

È una buona idea che il tuo motore sia deterministico. Non c'è motivo di selezionare una mossa in modo casuale. Lo faresti solo per ridurre la potenza del tuo motore. Se rendi il tuo motore non deterministico, troverai molto difficile eseguire il debug e riprodurre un bug. La mia raccomandazione è di non farlo.

Non dovresti modificare il tuo motore. Potresti voler usare un libro di apertura e scegliere una riga a caso. Molte GUI di scacchi possono farlo, ad esempio il software CuteChess . Anche la GUI di Arena può farlo.

Ma se insisti:

Diamo un'occhiata al codice sorgente dello stoccafisso .

 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;   }
  • Lo stoccafisso avvia il multi-PV (non supportato in TSCP, quindi dovrai codificarlo tu stesso!)
  • Calcola un numero casuale e aggiungilo al punteggio per ogni PV
  • Confronta ogni PV ponderato e scegli quello migliore

Potresti trovare utili i seguenti link:

Raccomandazione: non farlo a meno che non si desideri indebolire il motore.


l'approccio del libro ha funzionato alla grande, grazie! Ho pubblicato una domanda di follow-up riguardante le tabelle di trasposizione e le matrici triangolari.
nak3c,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.