Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //alpha-beta search algorithm variables and functions
- int maxDepth;
- int nodeCount;
- int maxPrune;
- int minPrune;
- int tempMaxDepth;
- int tempNodeCount;
- int tempMaxPrune;
- int tempMinPrune;
- double duration;
- clock_t start;
- int boardEval(int wCount, int bCount, vector<Space>& bvec){ //evaluates the score of a game that is not over yet
- int score = 0;
- if (bvec[0].color == 'w' && bvec[1].color != 'w') { score -= 10; }
- if (bvec[1].color == 'w' && bvec[0].color != 'w') { score -= 10; }
- if (bvec[86].color == 'b' && bvec[87].color != 'b') { score += 10; }
- if (bvec[87].color == 'b' && bvec[86].color != 'b') { score += 10; }
- score += (bCount - wCount) * 4;
- return score;
- }
- treeInfo alphaBetaScore(Space*& spo, vector<Space>& bveco, int nodeDepth, int depthLimit, bool isMaxTurn, int alpha, int beta){ //alpha-beta search function
- vector<Space> bvec = bveco;
- Space* sp = &bvec[spo->vectorNum];
- tempNodeCount += 1;
- treeInfo ti;
- ti.depth = nodeDepth;
- auto whitepc = 0;
- auto blackpc = 0;
- for (Space i : bvec){
- if (i.color == 'w') { whitepc += 1; }
- if (i.color == 'b') { blackpc += 1; }
- }
- if (whitepc == 1 && blackpc == 1) { //check for draw
- ti.score = 0;
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- else if ((whitepc > 1 && blackpc == 0) || (bvec[0].color == 'w' && bvec[1].color == 'w')) { //check for white win
- ti.score = -1000;
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- else if ((blackpc > 1 && whitepc == 0) || (bvec[86].color == 'b' && bvec[87].color == 'b')) { //check for black win
- ti.score = 1000;
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- else {
- if (isMaxTurn){ //max-value function
- if (nodeDepth == depthLimit){
- if (checkIfBlackCanCapture(bvec)){ blackCapToSpace(sp, bvec); }
- else { blackMoveToSpace(sp, bvec); }
- ti.score = boardEval(whitepc, blackpc, bvec); //evaluation function
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- else{
- vector<Space*> spVec;
- ti.score = alpha;
- if (checkIfBlackCanCapture(bvec)){
- blackCapToSpace(sp, bvec);
- spVec = getBlackCaptureArray(bvec);
- for (int i = 0; i < spVec.size(); i++){
- treeInfo cti = alphaBetaScore(spVec[i], bvec, nodeDepth + 1, depthLimit, false, alpha, beta);
- ti.score = max(ti.score, cti.score);
- ti.depth = max(ti.depth, cti.depth);
- alpha = max(alpha, ti.score);
- if (beta <= alpha) {
- tempMaxPrune += 1;
- break;
- }
- }
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- else {
- blackMoveToSpace(sp, bvec);
- spVec = getBlackMoveArray(bvec);
- for (int i = 0; i < spVec.size(); i++){
- treeInfo cti = alphaBetaScore(spVec[i], bvec, nodeDepth + 1, depthLimit, false, alpha, beta);
- nodeCount += 1;
- ti.score = max(ti.score, cti.score);
- ti.depth = max(ti.depth, cti.depth);
- alpha = max(alpha, ti.score);
- if (beta <= alpha) {
- tempMaxPrune += 1;
- break;
- }
- }
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- }
- }
- else { //min-value function
- if (nodeDepth == depthLimit){
- if (aiCheckIfWhiteCanCapture(bvec)){ aiWhiteCapToSpace(sp, bvec); }
- else { aiWhiteMoveToSpace(sp, bvec); }
- ti.score = boardEval(whitepc, blackpc, bvec); //evaluation function
- return ti;
- }
- else{
- vector<Space*> spVec;
- ti.score = beta;
- if (aiCheckIfWhiteCanCapture(bvec)){
- aiWhiteCapToSpace(sp, bvec);
- spVec = getWhiteCaptureArray(bvec);
- for (int i = 0; i < spVec.size(); i++){
- treeInfo cti = alphaBetaScore(spVec[i], bvec, nodeDepth + 1, depthLimit, true, alpha, beta);
- nodeCount += 1;
- ti.score = min(ti.score, cti.score);
- ti.depth = max(ti.depth, cti.depth);
- beta = min(alpha, ti.score);
- if (beta <= alpha) {
- tempMinPrune += 1;
- break;
- }
- }
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- else {
- aiWhiteMoveToSpace(sp, bvec);
- spVec = getWhiteMoveArray(bvec);
- for (int i = 0; i < spVec.size(); i++){
- treeInfo cti = alphaBetaScore(spVec[i], bvec, nodeDepth + 1, depthLimit, true, alpha, beta);
- nodeCount += 1;
- ti.score = min(ti.score, cti.score);
- ti.depth = max(ti.depth, cti.depth);
- beta = min(alpha, ti.score);
- if (beta <= alpha) {
- tempMinPrune += 1;
- break;
- }
- }
- duration = (clock() - start) / (double)CLOCKS_PER_SEC;
- return ti;
- }
- }
- }
- }
- }
- Space* alphaBetaBestChoice(vector<Space*>& spvec){ //displays information regarding the alpha-beta algorithm and returns the chosen move
- int bestScore = -1000;
- int bestIndex = 0;
- vector<int> scoreVec;
- start = clock(); //timer starts here
- for (int i = 0;; i++){ //performs iterative deepening on algorithm and returns early results in case the algorithm does not finish in time
- vector<int> depthVec;
- tempMaxDepth = 0;
- tempNodeCount = 0;
- tempMaxPrune = 0;
- tempMinPrune = 0;
- for (Space* j : spvec) {
- treeInfo ti = alphaBetaScore(j, boardVec, 0, i, true, -1000, 1000);
- depthVec.push_back(ti.score);
- if (tempMaxDepth < ti.depth) { tempMaxDepth = ti.depth; }
- if (duration > 10.0) { break; } //timer ends search here
- }
- scoreVec = depthVec;
- maxDepth = tempMaxDepth;
- nodeCount = tempNodeCount;
- maxPrune = tempMaxPrune;
- minPrune = tempMinPrune;
- if (i > tempMaxDepth || duration > 10.0) { break; } //ends iterative deepening loop if depth exceeds max algorithm tree depth
- }
- for (int i = 0; i < scoreVec.size(); i++){
- if (bestScore < scoreVec[i]){
- bestScore = scoreVec[i];
- bestIndex = i;
- }
- }
- cout << "\nMaximum depth of game tree reached: " << maxDepth
- << "\nTotal number of nodes generated: " << nodeCount
- << "\nNumber of times pruning occurred within the MAX-VALUE function: " << maxPrune
- << "\nNumber of times pruning occurred within the MIN-VALUE function: " << minPrune
- << "\nTime elapsed: " << duration << " seconds\n"
- << "Computer's move: " << spvec[bestIndex]->yCoord << spvec[bestIndex]->xCoord << "\n\n";
- return spvec[bestIndex];
- }
- void aiTurn(){
- cout << "\nComputer's turn.\n";
- if (checkIfBlackCanCapture(boardVec)){ //checks if AI can capture this turn
- cout << "Computer is obligated to capture an enemy piece.\n\n";
- vector<Space*> spVec = getBlackCaptureArray(boardVec); //gets vector of potential capture moves
- Space* spp = alphaBetaBestChoice(spVec); //runs alpha-beta search
- blackCapToSpace(spp, boardVec);
- }
- else{
- vector<Space*> spVec = getBlackMoveArray(boardVec); //gets vector of potential non-capture moves
- Space* spp = alphaBetaBestChoice(spVec); //runs alpha-beta search
- blackMoveToSpace(spp, boardVec);
- }
- humanTurn = true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement