diff --git a/Engine.cpp b/Engine.cpp new file mode 100644 index 0000000..d05e61a --- /dev/null +++ b/Engine.cpp @@ -0,0 +1,214 @@ +#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; + }*/ +}