From 40470187abf3b9f65c92848c1e88fdfe14c804b0 Mon Sep 17 00:00:00 2001 From: David Jardim Date: Fri, 21 Apr 2017 19:53:03 -0400 Subject: [PATCH] added Heurisitc class --- include/Heuristic.hpp | 34 ++++++++++ src/Heuristic.cpp | 154 ++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 4 +- 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 include/Heuristic.hpp create mode 100644 src/Heuristic.cpp diff --git a/include/Heuristic.hpp b/include/Heuristic.hpp new file mode 100644 index 0000000..2deda63 --- /dev/null +++ b/include/Heuristic.hpp @@ -0,0 +1,34 @@ +#ifndef HEURISTIC_H +#define HEURISTIC_H + +#include "BitBoard.h" + +class Heuristic +{ + // Feature coefficients + int coeff[10] = {1,1,1,1,1,1,1,1,1,1}; + + // Feature Functions + int h1() const; + int h2() const; + int h3() const; + int h4() const; + int h5() const; + int h6() const; + int h7() const; + int h8() const; + int h9() const; + int h10() const; + + const int count(uint32_t i) const; + + uint32_t b,w,k; + bool isBlacksTurn; + BitBoard *board; + + public: + // Heuristic(int *co[10]) { coeff = *co;}; + const int evaluate(bup &bitboard); +}; + +#endif diff --git a/src/Heuristic.cpp b/src/Heuristic.cpp new file mode 100644 index 0000000..6a66bfe --- /dev/null +++ b/src/Heuristic.cpp @@ -0,0 +1,154 @@ +#include +#include +#include +#include "Heuristic.hpp" + +/* Heuristic Functions */ + +// counts number of setbits + +using BB = BitBoard; + +const int Heuristic::count(uint32_t i) const{ + return std::bitset<32>(i).count(); +} + +const int Heuristic::evaluate(bup &bitboard){ + b = bitboard->getBlackPieces(); + w = bitboard->getWhitePieces(); + k = bitboard->getKings(); + isBlacksTurn = bitboard->getIsBlacksTurn(); + board = &(*bitboard); + + return + coeff[0]*h1() + + coeff[1]*h2() + + coeff[2]*h3() + + coeff[3]*h4();// + + + // Test game was taking too long, let just do 4 for now... + + // coeff[4]*h5() + + //coeff[5]*h6() + + //coeff[6]*h7() + + //coeff[7]*h8() + + //coeff[8]*h9() + + //coeff[9]*h10() ; +} + +// Number of pawns +int Heuristic::h1() const +{ + return count((isBlacksTurn ? b : w) & ~k); +} + +// Number of kings +int Heuristic::h2() const +{ + return count((isBlacksTurn ? b : w) & k); +} + +// Number of safe pawns +int Heuristic::h3() const +{ + return count((isBlacksTurn ? b : w) & ~k & BB::edgeLoc); +} + +// Number of safe kings +int Heuristic::h4() const +{ + return count((isBlacksTurn ? b : w) & k & BB::edgeLoc); +} + +// Aggregated distance of pawns to promotion line +int Heuristic::h5() const +{ + int aggrDistance = 0; + if(isBlacksTurn) + for(int i=0; i<7; i++) + aggrDistance += (7-i)*count(b & k & BB::rowMask(i)); + else + for(int i=1; i<8; i++) + aggrDistance += i*count(w & k & BB::rowMask(i)); + + return aggrDistance; +} + +// Number of defender pieces, closest two BB::rows on players side +int Heuristic::h6() const +{ + if(isBlacksTurn) + return count(b & (BB::rowMask(0) | BB::rowMask(1))); + else + return count(w & (BB::rowMask(6) | BB::rowMask(7))); +} + +// Number of attacking pawns, position in upper three most BB::rows, opponents side +int Heuristic::h7() const +{ + if(isBlacksTurn) + return count(b & ~k & ( BB::rowMask(7) | BB::rowMask(6) | BB::rowMask(5))); + else + return count(w & ~k & ( BB::rowMask(2) | BB::rowMask(1) | BB::rowMask(0))); +} + +// Number of unoccupied fields on promotion line +int Heuristic::h8() const +{ + if(isBlacksTurn) + return count( (b | w) & BB::rowMask(7)); + else + return count( (b | w) & BB::rowMask(0)); +} + +// Number of moveable pawns +int Heuristic::h9() const +{ + uint32_t accumP; + uint32_t emptyPos = ~(b | w); + + + // these heuristics are not calculated correctly, TODO + if(isBlacksTurn) + { + accumP |= board->rotr32(board->rotr32(b & ~k & BB::downLeft, 1) & emptyPos, -1); + accumP |= board->rotl32(board->rotl32(b & ~k & BB::downRight, 1) & emptyPos, -1); + + + } + else + { + accumP |= board->rotr32(board->rotr32(w & ~k & BB::upRight, -1) & emptyPos, 1); + accumP |= board->rotl32(board->rotl32(w & ~k & BB::upLeft, -1) & emptyPos, 1); + } + return count(accumP); +} + +// Number of moveable kings +int Heuristic::h10() const +{ + + // these heuristics are not calculated correctly, TODO + + uint32_t accumK; + uint32_t kings; + uint32_t emptyPos = ~(b | w); + if(isBlacksTurn) + { + kings = b & k; + accumK |= board->rotr32(board->rotr32(kings & BB::downLeft, 1) & emptyPos, -1); + accumK |= board->rotl32(board->rotl32(kings & BB::downRight, 1) & emptyPos, -1); + accumK |= board->rotr32(board->rotr32(kings & BB::upRight, -1) & emptyPos, 1); + accumK |= board->rotl32(board->rotl32(kings & BB::upLeft, -1) & emptyPos, 1); + } + else { + kings = w & k; + accumK |= board->rotr32(board->rotr32(kings & BB::downLeft, 1) & emptyPos, -1); + accumK |= board->rotl32(board->rotl32(kings & BB::downRight, 1) & emptyPos, -1); + accumK |= board->rotr32(board->rotr32(kings & BB::upRight, -1) & emptyPos, 1); + accumK |= board->rotl32(board->rotl32(kings & BB::upLeft, -1) & emptyPos, 1); + } + return count(accumK); +} + + diff --git a/src/main.cpp b/src/main.cpp index 86c238c..1d1ff06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,10 +5,12 @@ #include "BitBoard.h" #include "Move.h" #include "MinimaxSearch.h" +#include "Heuristic.hpp" int main(int argc, const char * argv[]) { std::unique_ptr board (new BitBoard); - MinimaxSearch searchDriver; + Heuristic heur_test; + MinimaxSearch searchDriver(heur_test); for (int i = 0; i < 100; ++i) { board->printState();