/*Score Tree using Alfa Beta pruning*/ void alfabeta(MinimaxNode *node, int a, int b, Color col) { if (node->sons == NULL) { if (node->depth%2==0) node->val = scoreBoard(node->game, col, node->depth); else node->val = scoreBoard(node->game, oppositeCol(col), node->depth); return; } if (node->depth % 2 == 0) { int val = -ALFA_BETA_INFINITY; int i; for (i = 0; i < node->sonsK; i++) { alfabeta(node->sons[i], a, b, oppositeCol(col)); val = maximum(val, node->sons[i]->val); a = maximum(val, a); if (b < a) break; //if ((node->depth>2)&&(b <= a))break; //if ((node->depth<=2) && (b < a))break; } node->val = val; } else { int val = ALFA_BETA_INFINITY; int i; for (i = 0; i<node->sonsK; i++) { alfabeta(node->sons[i], a, b, oppositeCol(col)); val = minimum(val, node->sons[i]->val); b = minimum(val, b); if (b < a) break; //if ((node->depth>2) && (b <= a))break; //if ((node->depth <= 2) && (b < a))break; } node->val = val; } }
int MoveEvaluater::alfabeta(int alfa, int beta, int depth, int who) { if(depth >= maxdepth) { return state.evaluate(who); } push(); Move m; int v,e,p,r; bool done = false; for(v = alfa, p = state.firstMove(who,m); p >= 0 && !done; p = state.nextMove(who,m)) { state.doMove(who, m); if((e = -alfabeta(-beta,-v,depth+1, -who)) > v) { v = e; r = p; } if(v >= beta) { done = true; } restore(); }; pop(); if(depth == 0 && v > bestscore) { bestscore = v; bestmove = r; } return v; }
int MoveEvaluater::findmove(int who, int lookahead, const GameState &g) { bestscore = MIN_SCORE; bestmove = 0; maxdepth = lookahead; state = g; stacktop = 0; state.setEvaluate(); alfabeta(MIN_SCORE,MAX_SCORE,0, who); return bestmove; }
/*Build Minimax Tree according to Difficulty Level and Score Tree*/ MinimaxNode *getTree(Game *game, Color uCol) { MinimaxNode *root = NULL; if (game->difficulty < 5) { root = getMinimaxTreeFixedDepth(game, 0, NULL, uCol); } else { root = getMinimaxTreeBestDepth(game, uCol); } alfabeta(root, -ALFA_BETA_INFINITY, ALFA_BETA_INFINITY, uCol); //printf("Root val is - %d\n", root->val); return root; }