diff --git a/Board.cpp b/Board.cpp index b1473b4..b423b00 100755 --- a/Board.cpp +++ b/Board.cpp @@ -5,34 +5,42 @@ using namespace std; Board::Board() { - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) { for (int j = 0; j < 8; ++j) { - boardArray[i][j] = 'X'; + xpieces.push_back(new Piece(i, j, 'X')); + } + } + for (int i = 6; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + opieces.push_back(new Piece(i, j, 'O')); + } + } +} + +bool Board::elemInXs(int r, int c){ + for (int i = 0; i < xpieces.size(); ++i){ + if (xpieces[i]->getX() == r && xpieces[i]->getY() == c){ + return true; } } - - for (int i = 2; i < 6; ++i) { - for (int j = 0; j < 8; ++j) { - boardArray[i][j] = '_'; + return false; +} + +bool Board::elemInOs(int r, int c){ + for (int i = 0; i < opieces.size(); ++i){ + if (opieces[i]->getX() == r && opieces[i]->getY() == c){ + return true; } } - - for (int i = 6; i <= 7; ++i) { - for (int j = 0; j < 8; ++j) { - boardArray[i][j] = 'O'; - } - } + return false; } moves Board::parse(string input) { - input = myToUpper(input); - cout<getX() == 0){ + cout<<"\n\n\nPlayer X wins!\n\n\n"<getX() == 7){ + cout<<"\n\n\nPlayer O wins!\n\n\n"< 8 || row < 0 || kolumn > 8 || kolumn < 0) - { - cout<<"ERROR: index out of bound in move()!"< 8 || row < 0 || kolumn > 8 || kolumn < 0) - { - cout<<"ERROR: index out of bound in second move()!"< 8 || row < 0 || column > 8 || column < 0) { + cout<<"ERROR: index out of bound."<getType(); + cout << "temp: " << temp << "\n"; + + if (temp != turn || temp == '_') { + cout<<"ERROR: attempting to move an invalid piece."<moveFwd(); } - - if (jugada.moveType == "FWD") - { - - if(boardArray[row+reflector][kolumn] != '_') - { - cout<<"you can't move that piece forward"<getType() == temp) cout<<"you hate your own team or something? you can't do that!"<moveLeft(); } - else if (jugada.moveType == "RIGHT") - { - if (kolumn == 7) - { + else if (jugada.moveType == "RIGHT") { + if (column == 7) cout<<"Destination Spot out of range!"<getType() == temp) cout<<"you hate your own team or something? you can't do that!"<moveRight(); } - - else - { - cout<<"Unrecognized movetype!"<getType(); if (pieceToMove != turn) //trying to move invalid piece { + cout << "Error in Board::isThisMovePossible: trying to move a piece outside your turn.\n"; return false; } @@ -382,22 +233,26 @@ bool Board::isThisMovePossible(int r, int c, string moveType) { if (moveType == "FWD") { - - if (boardArray[r+reflector][c] == '_') return true; - else return false; - + if (boardArray[r+reflector][c]->getType() == '_') + return true; + else + return false; } else if (moveType == "RIGHT") { - if (boardArray[r+reflector][c+1] != pieceToMove && (r+reflector >= 0) && (r+reflector <= 7) && (c+1 <= 7) ) return true; - else return false; + if (boardArray[r+reflector][c+1]->getType() != pieceToMove && (r+reflector >= 0) && (r+reflector <= 7) && (c+1 <= 7) ) + return true; + else + return false; } else if (moveType == "LEFT") { - if (boardArray[r+reflector][c-1] != pieceToMove && (r+reflector >= 0) && (r+reflector <= 7) && (c+1 >= 0) ) return true; - else return false; + if (boardArray[r+reflector][c-1]->getType() != pieceToMove && (r+reflector >= 0) && (r+reflector <= 7) && (c+1 >= 0) ) + return true; + else + return false; } else return false; @@ -412,7 +267,7 @@ vector Board::viewPossibleMoves() { for (int c = 0; c < 8; ++c) { - if (boardArray[r][c] == turn) + if (boardArray[r][c]->getType() == turn) { if (isThisMovePossible(r,c,"FWD")) { @@ -438,7 +293,7 @@ vector Board::viewPossibleMoves() return output; } - +*/ string Board::myToUpper(string input) { string output; @@ -455,11 +310,6 @@ string Board::myToUpper(string input) else output.push_back(input[i]); } - for (int i = 0; i < output.size(); ++i) - { - cout< record; @@ -509,7 +360,7 @@ void Board::interpret(string input, Board& tablero) //determines what kind of co else tablero.move(input); } - +*/ void Board::snapshot(vector& inputVec, Board inputBoard) { if (inputVec.size() == 10) @@ -522,31 +373,21 @@ void Board::snapshot(vector& inputVec, Board inputBoard) cout<<"QUEUE OVERFLOW!"< listOfMoves = viewPossibleMoves(); - - //obvious moves - if (false){ - return; +int Board::evaluate(char max, char min){ + //right now just evaluating number of pieces + if (max == 'X'){ + return (xpieces.size() - opieces.size()); } - - //random - else { - srand(time(NULL)); - int randomChoice = rand() % (listOfMoves.size()-1) - 0; // choose a move betwen listOfMoves[0] to last element - - //3) execute movement - int temp = randomChoice; - - move(listOfMoves[randomChoice]); + + else if (max == 'O'){ + return (opieces.size() - xpieces.size()); + } + + else { + cout << "Unidentified max, must be either X or O.\n"; + return 0; } } \ No newline at end of file diff --git a/Board.h b/Board.h index f17eb4d..8f3284c 100755 --- a/Board.h +++ b/Board.h @@ -2,6 +2,7 @@ #include #include +#include "Piece.h" using namespace std; @@ -18,13 +19,16 @@ struct moves { }; class Board { - char boardArray [8][8]; + //vector> boardArray; + vector xpieces; + vector opieces; + //char boardArray [8][8]; char turn = 'O'; public: Board(); - char elementAt(int r, int k) { return boardArray[r][k]; } - void modifyAt(int r, int k, char input) { boardArray[r][k] = input; } + bool elemInXs(int r, int c); + bool elemInOs(int r, int c); moves parse(string input); char getTurn() { return turn; } bool isGameOver(); @@ -32,13 +36,14 @@ public: void displayBoard(); int charToIntColumn(char input); char intToCharColumn(int input); - void move(string inputMove); - void move(moves jugada); - bool isThisMovePossible(int r, int c, string moveType); - vector viewPossibleMoves(); + //void move(string inputMove); + //void move(moves jugada); + void moveWOPrint(moves jugada); + //bool isThisMovePossible(int r, int c, string moveType); + //vector viewPossibleMoves(); string myToUpper(string input); void undo(Board& tablero); void interpret(string input, Board& tablero); void snapshot(vector& inputVec, Board inputBoard); - void easyAI(); + int evaluate(char max, char min); }; \ No newline at end of file diff --git a/Engine.cpp b/Engine.cpp new file mode 100755 index 0000000..c68e650 --- /dev/null +++ b/Engine.cpp @@ -0,0 +1,135 @@ +#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->displayBoard(); + cout<<"\nEnter command: "; + cin>>move; + cout << "\n"; + b->interpret(move, *b); + } + + b->changeTurns(); + + while(b->getTurn() == 'X' ) + { + cout << "\n\n\n\nit gets here\n\n\n\n"; + easyAI(); + } + + gameOver = b->isGameOver(); + + b->snapshot(record, *b); + } +} + +void Engine::easyAI() +{ + //1) see all possible movements + vector listOfMoves = b->viewPossibleMoves(); + + //obvious moves + if (false){ + b->changeTurns(); + } + + //random + else { + srand(time(NULL)); + int randomChoice = rand() % (listOfMoves.size()-1) - 0; // choose a move betwen listOfMoves[0] to last element + + //3) execute movement + int temp = randomChoice; + b->move(listOfMoves[randomChoice]); + } +} + +void Engine::AI(){ + cout << "----------------------BEGIN AI FUNCTION----------------------\n"; + vector listOfMoves = b->viewPossibleMoves(); + Board temp = *b; + + //probably not needed, check later + if (temp.getTurn() != 'X'){ + cout << "a changing of turns is needed. \n"; + temp.changeTurns(); + } + + //only doing 1 branch right now because testing + /*for (int i = 0; i < listOfMoves.size(); ++i){ + minMax(temp, listOfMoves[i]); + }*/ + + b->moveWOPrint(minMax(temp, listOfMoves[0], 0)); + + //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(Board temp, moves m, int c){ + //testing purposes only + if (c > 5){ + return m; + } + + if (temp.isGameOver() == true){ + cout << "END OF PATH REACHED\n"; + return m; + } + + else { + if(temp.isThisMovePossible(8 - m.row, temp.charToIntColumn(m.column), m.moveType)){ + cout << "piece has been moved in minMax\n"; + temp.moveWOPrint(m); + } + cout << "c: " << c << "\n\n"; + cout << "current turn: " << temp.getTurn() << "\n"; + vector listOfMoves = temp.viewPossibleMoves(); + + for (int i = 0; i < listOfMoves.size(); ++i){ + //return minMax(temp, listOfMoves[i]); + } + + //limited recursion + return minMax(temp, listOfMoves[0], ++c); + + //testing + return m; + } +} \ No newline at end of file diff --git a/Engine.h b/Engine.h new file mode 100755 index 0000000..463d05c --- /dev/null +++ b/Engine.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Board.h" + +using namespace std; + +class Engine { + Board* b; + +public: + Engine(); + void startGame(); + void easyAI(); + void AI(); + moves minMax(Board temp, moves m, int c); +}; \ No newline at end of file diff --git a/Piece.cpp b/Piece.cpp new file mode 100755 index 0000000..6796826 --- /dev/null +++ b/Piece.cpp @@ -0,0 +1,69 @@ +#include +#include "Piece.h" + +using namespace std; + +Piece::Piece(){ + x = -1; + y = -1; + type = '?'; +} + +Piece::Piece(int r, int c){ + x = r; + y = c; + type = '_'; +} + +Piece::Piece(int r, int c, char t){ + x = r; + y = c; + type = t; +} + +void Piece::moveFwd(){ + if (type == 'X'){ + x++; + } + + else if (type == 'O'){ + x--; + } + + else + cout << "Error: trying to move an empty piece forward."; +} + +void Piece::moveLeft(){ + if (type == 'X'){ + x++; + y--; + } + + else if (type == 'O'){ + x--; + y++; + } + + else + cout << "Error: trying to move an empty piece left."; +} + +void Piece::moveRight(){ + if (type == 'X'){ + x++; + y++; + } + + else if (type == 'O'){ + x--; + y--; + } + + else + cout << "Error: trying to move an empty piece left."; +} + +void Piece::isTaken(){ + // +} \ No newline at end of file diff --git a/Piece.h b/Piece.h new file mode 100755 index 0000000..60a3a00 --- /dev/null +++ b/Piece.h @@ -0,0 +1,25 @@ +#pragma once + +using namespace std; + +class Piece { + int x; + int y; + char type; + +public: + Piece(); + Piece(int r, int c); + Piece(int r, int c, char t); + void moveFwd(); + void moveLeft(); + void moveRight(); + int getX(){ return x; } + void setX(int r){ x = r; } + int getY(){ return y; } + void setY(int c){ y = c; } + char getType(){ return type; } + void setType(char t){ type = t; } + void makeEmpty(){ type = '_'; } + void isTaken(); +}; \ No newline at end of file diff --git a/a.out b/a.out deleted file mode 100755 index 8a730d5..0000000 Binary files a/a.out and /dev/null differ diff --git a/test.cpp b/test.cpp index 7dd63ca..fd5452f 100755 --- a/test.cpp +++ b/test.cpp @@ -1,76 +1,15 @@ -#include -#include -#include -#include #include "Board.h" +#include "Engine.h" using namespace std; int main() { - cout<<"WELCOME\n"; - - cout<<"1. Play against AI?\n"; - cout<<"2. Play against a human?\n"; - //cout<<"CHANGE THIS TO PARSE THINGS\n"; - cout<<"Enter choice: \n"; - - int choice; - cin >> choice; - cout << "OK" << endl; - + //board testing Board b; - string move; + b.displayBoard(); - bool gameOver = false; - vector record; - b.snapshot(record,b); - - while (gameOver != true) - { - gameOver = b.isGameOver(); - - while(b.getTurn() == 'O' ) - { - b.displayBoard(); - cout<<"\nEnter command: "; - cin>>move; - b.interpret(move,b); - } - - - vector possibleMoves = b.viewPossibleMoves(); - - if (choice == 1) - { - b.easyAI(); - } - - else - { - while(b.getTurn() == 'X' ) - { - b.displayBoard(); - cout<<"\nEnter command: "; - cout<<"OK\n"; - cin>>move; - b.interpret(move,b); - } - } - - //b.snapshot(); - gameOver = b.isGameOver(); - - b.snapshot(record,b); - } - - //for debugging purposes - cout<<"Record:"<