#include #include #include #include #include #include #include #include #include #include #include "Engine.h" Engine::Engine(){ Board* brd = new Board(); b = brd; } void Engine::startGame(int port){ cout << "Launching server..." << endl; int sockfd, newsockfd, portno; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; int n; if (port < 2) { cout << "ERROR, no port provided\n"; exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) cout << "ERROR opening socket"; bzero((char *) &serv_addr, sizeof(serv_addr)); portno = port; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) cout << "ERROR on binding"; listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) cout << "ERROR on accept"; string move; bool gameOver = false; vector record; b->snapshot(record, *b); char buffer[256]; char info[256]; int choice = -1; int choice_difficulty = -1; string final_move; //Ask client about game type string introduction = "WELCOME\n1. Play against AI?\n2. Watch AI vs. AI?\nEnter choice: \n"; write(newsockfd, introduction.c_str(), introduction.length()); n = read(newsockfd,info,255); //Reads choice as a string istringstream convert(info); //Converts the read string to an integer convert >> choice; //Sets value equal to the converted value //Later in the project, we need to check for AI and Human modes cout << "OK" << endl; bzero(info,256); //Resets info back to normal /*//Becca- once your AI code is working, use this code: string difficulty_select = "Choose Difficulty\n1. Easy\n2. Medium\n4. Hard\nEnter choice: \n"; write(newsockfd, difficulty_select.c_str(), difficulty_select.length()); n = read(newsockfd,info,255); istringstream convert(info); convert >> choice_difficulty; cout << "OK" << endl; bzero(info,256); */ while (gameOver != true) { gameOver = b->isGameOver(); while(b->getTurn() == 'O' && !b->isValid()) { b->displayBoard(); string boardState = b->boardToString(); final_move = b->boardToString(); write(newsockfd, boardState.c_str(), boardState.length());//Display the board to the client (line by line) cout<<"\nStanding by for client... \n"; n = read(newsockfd,buffer,255);//Read the client's input move = buffer; bzero(buffer,256); b->interpret(move, *b); if(b->isValid()) { b->changeTurns(); b->setValidFalse(); } } if(b->isValid()) cout << b->getTurn(); while(b->getTurn() == 'X' ) { easyAI(); /*Becca- once you finish your AI, uncomment this out and remove the line directly above this if(choice_difficulty == 1) easyAI(); else if(choice_difficulty == 2) mediumAI(); else hardAI(); */ } gameOver = b->isGameOver(); b->setValidFalse(); b->snapshot(record, *b); } final_move = b->boardToString(); string game_over = "\n\nGAME OVER!!!\n"; write(newsockfd, final_move.c_str(), final_move.length()); //Display the board to the client (line by line) write(newsockfd, game_over.c_str(), game_over.length()); //Tell the client the game is over cout << game_over; usleep(1); close(newsockfd); close(sockfd); } void Engine::easyAI() { vector listOfMoves = b->viewPossibleMoves(); /* for(int x = 0; x < listOfMoves.size(); ++x) { cout << listOfMoves[x].row << " " << listOfMoves[x].column << " " << listOfMoves[x].moveType << "\n\n"; } */ srand(time(NULL)); int randomChoice = rand() % (listOfMoves.size()-1) - 0; int temp = randomChoice; cout << "easy AI move: " << listOfMoves[randomChoice].row << listOfMoves[randomChoice].column << listOfMoves[randomChoice].moveType << "\n"; b->move(listOfMoves[randomChoice]); b->changeTurns(); } void Engine::AI(){ cout << "----------------------BEGIN AI FUNCTION----------------------\n"; vector listOfMoves = b->viewPossibleMoves(); //Board* b = new Board(*b); //probably not needed, check later /* if (b->getTurn() != 'X'){ cout << "a changing of turns is needed. \n"; b->changeTurns(); } */ //only doing 1 branch right now because testing /*for (int i = 0; i < listOfMoves.size(); ++i){ minMax(b, listOfMoves[i]); }*/ b->move(minMax(listOfMoves[0], 0)); b->changeTurns(); //verification of correct turn /* if (b->getTurn() != 'O'){ cout << "ERROR in Engine::AI: b is on the wrong turn. \n"; } */ b->displayBoard(); cout << "----------------------END AI FUNCTION----------------------\n"; } moves Engine::minMax(moves m, int c){ //testing purposes only, c = finite depth /* if (c > 5){ return m; } if (b->isGameOver() == true){ cout << "END OF PATH REACHED\n"; return m; } else { if(b->isThisMovePossible(8 - m.row, b->charToIntColumn(m.column), m.moveType)){ cout << "piece has been moved in minMax\n"; b->move(m); b->changeTurns(); } cout << "c: " << c << "\n\n"; cout << "current turn: " << b->getTurn() << "\n"; vector listOfMoves = b->viewPossibleMoves(); for (int i = 0; i < listOfMoves.size(); ++i){ //return minMax(b, listOfMoves[i]); } b->displayBoard(); //limited recursion return minMax(b, listOfMoves[0], ++c); //testing return m; }*/ }