Pulse sisteminde bir pozisyonun
değerlendirilmesi Evaluation sınıfı ile gerçekleşmektedir.
class Evaluation {
int evaluate(Position position) {
int myColor = position.activeColor;
int oppositeColor = opposite(myColor);
int value = 0;
int materialScore = (evaluateMaterial(myColor, position) - evaluateMaterial(oppositeColor, position)) * materialWeight / MAX_WEIGHT;
value += materialScore;
int mobilityScore = (evaluateMobility(myColor, position) - evaluateMobility(oppositeColor, position)) * mobilityWeight / MAX_WEIGHT;
value += mobilityScore;
return value;
}
//...}
Burada önce pozisyondaki materyal
skoru bulunmaktadır. Örneğin bir piyon fazlası var ise materyal
skoru 1 olarak bulunur. Ardından mobilite skoru bulunmaktadır.
Örneğin bir fil, çapraz karelerde serbest olarak dolaşabiliyorsa
mobilite skoru yüksek olur. Satranç motorları güçlendikçe
değerlendirme kriterleri de artmakta ve kod da
karmaşıklaşmaktadır.
private int evaluateMaterial(int color, Position position) {
int material = position.material[color];
// Fil çifti için bonus skor ver
if (position.pieces[color][BISHOP].size() >= 2) {
material += 50;
}
return material;
}
Pozisyondaki materyal skoru
belirlenirken, Position sınıfında sürekli güncel olarak tutulan
int dizileri kullanılmaktadır. Aslında beyaz ve siyah için iki
int değer tutulmaktadır. Birçok metot "color"
parametresi aldığı için dizinin "color" elemanına
erişmek, materyal skoru almak anlamına gelmektedir.
private int evaluateMobility(int color, Position position) {
int knightMobility = 0;
for (long squares = position.pieces[color][KNIGHT].squares; squares != 0; squares = remainder(squares)) {
int square = next(squares);
knightMobility += evaluateMobility(color, position, square, knightDirections);
}
//...}
Yukarıda bir at için mobilitenin
belirlenmesi gösterilmiştir. Burada Position sınıfında yer alan
taş yerleşim bilgilerinin kullanıldığı görülmektedir. Her at
için gidebileceği kareler üzerinden mobilite hesaplanmaktadır.
class Position {
Bitboard[][] pieces = new
Bitboard[Color.values.length][PieceType.values.length];
}
Pozisyonu ifade eden sınıfta siyah ve
beyaz için olmak üzere iki tane dizi tutulmaktadır. Bunlardan her
biri altı tane Bitboard tutmaktadır. Örneğin "beyaz at"
istediğimizde bize bunların yerleşimini ifade eden bir Bitboard
dönecektir. Pozisyonların bit dizisi şeklinde ifade edilmesi oyun
programlamada kullanılan önemli bir yöntemdir ve satrançta 64
bitlik bir Java long türü, bir satranç tahtasını ifade etmekte
yeterli olacaktır. [3]
Hamle Oluşturma
Motor öncelikle tüm legal hamleleri
belirlemektedir. Bunu MoveGenerator sınıfına yaptırır.
class MoveGenerator {
private final MoveList moves = new MoveList<>(MoveEntry.class);
MoveList getLegalMoves(Position position, int depth, boolean isCheck) {
MoveList legalMoves = getMoves(position, depth, isCheck);
int size = legalMoves.size;
legalMoves.size = 0;
for (int i = 0; i < size; ++i) {
int move = legalMoves.entries[i].move;
position.makeMove(move);
// açmaz durumlarına karşı kontrol if (!position.isCheck(opposite(position.activeColor))) {
legalMoves.entries[legalMoves.size++].move = move;
}
position.undoMove(move);
}
return legalMoves;
}
Burada özellikle Position sınıfının
makeMove ve undoMove metotlarının ne kadar önemli olduğu ve hızlı
olmaları gerektiği görülmektedir. Legal hamleler belirlenirken,
hamleyi yapan tarafın şahının tehdit altında olmaması gerektiği
(açmazda olma) kuralı da kontrol edilmektedir.
private void addMoves(MoveList list, Position position) {
for (long squares = position.pieces[activeColor][PAWN].squares; squares != 0; squares = remainder(squares)) {
int square = next(squares);
addPawnMoves(list, square, position);
}
}
Her taş çeşidi için olası hamleler
belirlenirken bir kez daha BitBoard temsilinin önemi görülmektedir.
Buradaki döngü programın birçok kısmında karşımıza
çıkmaktadır. Geçerli hamleler belirlendikten sonra "En
Değerli Kurban, En Değersiz Saldırgan" adı verilen sezgisel
yaklaşıma göre değerlendirilmektedir. [5]
[3] Bošković,
Borko, et al. "The representation of chess game." Information
Technology Interfaces, 2005.
[4]
https://chessprogramming.wikispaces.com/Pulse
[5] Groß,
Roderich, et al. "Evolving chess playing programs." GECCO
2002.
No. LSRO-CONF-2008-037. Morgan Kaufmann, 2002.
Comments