Un piccolo "essere lì, fatto quel" suggerimento ... migrare il mio motore di scacchi da una rappresentazione della scheda 0x88 al bitboard era relativamente semplice. Ottenere un miglioramento delle prestazioni è stato molto più difficile di quanto mi aspettassi.
Il fatto è che puoi avere un design meraviglioso per la tua classe tavola / pezzo, perfetta modularità, dipendenze minime tra le classi ... ma è sicuro che devi aver organizzato la tua logica di valutazione a seconda di cosa puoi fare veloce o lento (e questo è collegato alla rappresentazione della scheda).
La modifica della rappresentazione della scheda determinerà cambiamenti nella logica di valutazione statica: è complessa, dispendiosa in termini di tempo e rischiosa.
Inoltre, mentre cambi la logica di valutazione, scopri che alcune estensioni di ricerca non sono più necessarie o che hai bisogno di una ricerca di quiescenza migliore.
Alla fine potresti avere un giocatore completamente diverso.
Quindi puoi iniziare con una rappresentazione "temporanea" della scheda ma tutto dovrebbe essere fatto tenendo presente la rappresentazione finale (i punti di forza / debole di una rappresentazione che non stai usando potrebbero essere inaspettati).
La tua implementazione è la tipica relazione Team / Membri.
L'oggetto Team (la scacchiera) avrà dei puntatori ai suoi membri (i pezzi) e i membri avranno anche un puntatore posteriore all'oggetto Team.
Quindi weak_ptr
viene usato per interrompere il ciclo di dipendenza: il "proprietario" usa shared_ptr
e il "proprietario" usa un weak_ptr
al suo genitore e lo converte temporaneamente in shared_ptr
quando ha bisogno di accedere al suo genitore.
Quindi, da questo punto di vista, è un'implementazione corretta.
Tuttavia la funzione getPossibleMoves()
richiederà la posizione del pezzo per eseguire il suo compito.
La funzione potrebbe scoprire la posizione di scansione della scheda, ma questo rallenterebbe la generazione del movimento. Per evitare la ridondanza dei dati, non devi memorizzare le coordinate all'interno di Piece
e getPossibleMoves()
avrà bisogno di due argomenti:
std::list<Move> ThePiece::getPossibleMoves(unsigned row, unsigned column)
{
// ...
}
// ...
Board b;
// ...
auto moves = b[row][column]->getPossibleMoves(row, column);
Ora perché non rimuovere la dipendenza iniettata myBoard
da Piece
e aggiungere un altro argomento a getPossibleMoves
?
std::list<Move> ThePiece::getPossibleMoves(const Board &b, unsigned row, unsigned column)
{
// ...
}
Dopo questa modifica, shared_ptr non è più necessario ... in questo modo cambieremo completamente il design.