#include #include #include #include #include #include "Engine.h" Engine::Engine(){ Board* brd = new Board(); b = brd; } void Engine::startGame(){ cout<<"WELCOME\n"; cout<<"1. Play against AI?\n"; cout<<"2. Play against a human?\n"; cout<<"Enter choice: \n"; int choice = -1; cin >> choice; cout << "OK" << endl; string move; bool gameOver = false; vector record; b->snapshot(record, *b); while (gameOver != true){ gameOver = b->isGameOver(); while(b->getTurn() == 'O' && !b->isValid()){ b->displayBoard(); cout<<"\nEnter command: "; cin>>move; cout << "\n"; b->interpret(move, *b); if(b->isValid()){ b->changeTurns(); b->setValidFalse(); } } while(b->getTurn() == 'X' ){ //easyAI(); AI(3); } gameOver = b->isGameOver(); b->setValidFalse(); b->snapshot(record, *b); } } void Engine::easyAI(){ vector listOfMoves = b->viewPossibleMoves(); srand(time(NULL)); int randomChoice = rand() % (listOfMoves.size()-1) - 0; b->move(listOfMoves[randomChoice]); b->changeTurns(); } void Engine::AI(int depth){ Board* state = new Board(*b); moves m; MNode* root = new MNode(*state, m, 0); createMMTree(root, depth); m = evaluateMMTree(root); /* printTree(0, root); cout << "\n"; cout << "AI move: (" << m.row << ", " << m.column << "): " << m.moveType << "\n"; */ b->move(m); b->changeTurns(); b->displayBoard(); } void Engine::createMMTree(MNode* node, int depth){ MNode* temp; Board current = node->getState(); vector listOfMoves = current.viewPossibleMoves(); if (depth >= 0){ for (int i = 0; i < listOfMoves.size(); ++i){ if(current.getPiece(8 - listOfMoves[i].row, listOfMoves[i].column)->getType() == current.getTurn() && current.isThisMovePossible(8 - listOfMoves[i].row, listOfMoves[i].column, listOfMoves[i].moveType)){ current = current.move(listOfMoves[i]); current.changeTurns(); temp = new MNode(current, listOfMoves[i], current.evaluate('X')); node->addChild(temp); createMMTree(temp, --depth); current.changeTurns(); } } } return; } moves Engine::evaluateMMTree(MNode* node){ //returns the move from children that maximizes evaluate() MNode* temp; moves m; int max = INT_MIN; int val; vector children = node->getChildren(); for (auto &c : children){ val = evaluateMMBranch(c, 0); if(val > max){ temp = c; max = val; } } return temp->getMove(); } //return sum of eval values //pass in each child of root and 0 int Engine::evaluateMMBranch(MNode* node, int sum){ sum += node->getMMVal(); vector children = node->getChildren(); for (auto &c : children){ sum += evaluateMMBranch(c, sum); } return sum; }