예제 #1
0
void OthelloPlayerLOM::returnPlay(const OthelloBoard<8, 8>& board, int& x, int& y)
{
    std::map<int, std::vector<std::pair<int, int>>> finalMove;

    unsigned char lastPlayer = board.getLastPlayer();
    unsigned char player;
    if(lastPlayer == 1) player = 2;
    else                player = 1;

    for(auto& move : board.getValidPlays())
    {
        OthelloBoard<8, 8> hBoard(board);
        hBoard.play(player, move.first, move.second);
        int nMoves = hBoard.avaliableMoves(lastPlayer);
        if((move.first == 0 || move.first == 7) && (move.second == 0 || move.second == 7))
        {
            nMoves -= 20;
        }
        for(auto& opMove : hBoard.getValidPlays())
        {
            if((opMove.first == 0 || opMove.first == 7) && (opMove.second == 0 || opMove.second == 7))
            {
                nMoves += 100;
            }
            else if(opMove.first == 0 || opMove.first == 7 || opMove.second == 0 || opMove.second == 7)
            {
                nMoves += 10;
            }
        }
        finalMove[nMoves].push_back(move);
    }
    
    x = finalMove.begin()->second.front().first;
    y = finalMove.begin()->second.front().second;
}
예제 #2
0
int score_gen(const OthelloBoard& board,Turn turn) 
{
  int r_score = board.getRedCount();
  int b_score = board.getBlackCount();
  if(turn == RED) 
    {
      if (b_score == 0) 
        {
	  return 100;
	}
      if(r_score == 0)
	{
	    return -100;
	}
      return r_score-b_score;
    }
  else   
    {
      if (r_score == 0) 
        {
	  return 100;
	}
      if(b_score == 0)
	{
	    return -100;
	}
      return b_score-r_score;
    }
}
예제 #3
0
bool isDiagonalsFilled(int i, int j, OthelloBoard& curBoard )
{
	int k = i, l = j;
	while(0 <= k && k < 8 && 0 <= l && l < 8){
		if(curBoard.get(k,l) == EMPTY)
			return false;
		k++, l++;
	}
	k = i, l = j;
	while(0 <= k && k < 8 && 0 <= l && l < 8){
		if(curBoard.get(k,l) == EMPTY)
			return false;
		k++, l--;
	}
	k = i, l = j;
	while(0 <= k && k < 8 && 0 <= l && l < 8){
		if(curBoard.get(k,l) == EMPTY)
			return false;
		k--, l++;
	}
	k = i, l = j;
	while(0 <= k && k < 8 && 0 <= l && l < 8){
		if(curBoard.get(k,l) == EMPTY)
			return false;
		k--, l--;
	}
	return true;
}
예제 #4
0
int MyBot::countDifference(Turn turn, const OthelloBoard& board){
	int redCount = board.getRedCount();
	int blackCount = board.getBlackCount();
	if(turn == RED){
		return redCount - blackCount;
	}
	else {
	    return blackCount - redCount;
	}	
}
예제 #5
0
int MyBot::evaluationFunction(Turn turn, const OthelloBoard& board){
	
	int sum = 0;
	Turn opp = other(turn);
	for(int i = 0; i < 8; i++){
		for(int j = 0; j < 8; j++){
			if(turn == board.get(i,j)){
				sum = sum + weights[i][j];
			}
			else if(opp == board.get(i,j)){
				sum = sum - weights[i][j];
		    }	
		}
	}
	return sum;
}
예제 #6
0
/**
  * Create the children of the node, corresponding to all possible moves from node board.
  * \return True if the node has been expand, false if no move was possible.
  **/
bool OthelloSearchNode::expandNode() {
    using namespace std;
    list<OthelloAction*> * moves = _board->getMoves();
    if(moves == NULL)
        return false;

    _children = new list<OthelloSearchNode*>();
    for(list<OthelloAction*>::iterator it = moves->begin(); it != moves->end(); ++it) {
        OthelloBoard * p = new OthelloBoard(*_board);
        (*it)->apply(p);
        p->changePlayer();
        _children->push_front(new OthelloSearchNode(_level + 1, p, *it));
    }
    delete moves;
    return true;
}
예제 #7
0
Move MyBot::play(const OthelloBoard& board) {
	ourTurn = turn;
	store.clear();
	threadSuccessfull = false;
	if (!strtGame) {
		pthread_join(RGThread, NULL);
		getPrevMove(board);
		setPlyDepth();
		if(OpponentMoveDone){
			pos = getIndex();
			if(pos <= threadDone && pos != -1)
				threadSuccessfull = true;
		}
	}
	else if (ourTurn == BLACK) {
		strtGame = false;
		--gameMovesDone;
		setPlyDepth();
		PrevBoard = OthelloBoard(board);
		list<Move> moveLst = PrevBoard.getValidMoves(ourTurn);
		list<Move>::iterator it = moveLst.begin();
		int randNo = (rand() % 4);
		for (int i = 0; i < randNo - 1; ++it, ++i);

		FinalMove.x = it->x, FinalMove.y = it->y;
		PrevBoard.makeMove(ourTurn, FinalMove);
		++gameMovesDone;
		/* Initializing the thread to RG opponenet before returning the move */
		RGThreadStatus = pthread_create(&RGThread, NULL, threadFunc, (void*)NULL);

		return FinalMove;
	}
	strtGame = false;
	PrevBoard = OthelloBoard(board);
	Node* root = new Node(PrevBoard, ourTurn);
	if(!shallowDepthDone)
		shallowDepth(root);
	alphabetaMiniMax(root, 0, MIN_NUM, MAX_NUM, 0);
	PrevBoard.makeMove(ourTurn, FinalMove);
	++gameMovesDone;
	/* Initializing the thread to RG opponenet before returning the move */
	RGThreadStatus = pthread_create(&RGThread, NULL, threadFunc, (void*)NULL);

	return FinalMove;
}
예제 #8
0
void getPrevMove(const OthelloBoard& board) {
	int i, j;
	OpponentMoveDone = true;
	int numberOfMoves = 0;
	for (i = 0; i < 8; ++i) {
		for (j = 0; j < 8; ++j) {
			if (PrevBoard.get(i, j) == EMPTY && board.get(i, j) != PrevBoard.get(i, j)) {
				PrevMove.x = i, PrevMove.y = j;
				++numberOfMoves;
				if(numberOfMoves > 1)
					OpponentMoveDone = false;
			}
		}
	}
	gameMovesDone += numberOfMoves;
	if(numberOfMoves == 0)
		OpponentMoveDone = false;
}
예제 #9
0
int getIndex(){
	list<Move> moveLst = PrevBoard.getValidMoves(other(ourTurn));
	int i = 0;
	for(list<Move>::iterator it = moveLst.begin(); it != moveLst.end(); ++it, ++i){
		if(it->x == PrevMove.x && it->y == PrevMove.y)
			return i;
	}
	return -1;
}
예제 #10
0
Move MyBot::play( const OthelloBoard& board )
{
   start = clock();
   cout<<"My turn\n";
   board.print(turn);
   while(double(clock() - start)/CLOCKS_PER_SEC<2);
   start = clock();
   alphabeta(board,DEPTH,-1000,1000,turn,turn);
   return bestMove;
}
예제 #11
0
int main(int argc, char* argv[]) {
   // C++11 introduces the keyword 'auto' to use "type inference" to select
   // the type of a variable automatically when it is declared.

   auto i = 10; // i is of type int, because the rhs is int.
   auto d = 10.0; // d is of type double

   // For primitive types, this doesn't make much sense to use, so DON'T GO 
   // OVERBOARD and make all variables auto. For one, you must initialize an 
   // auto variable when declared.

   // auto unknown; <---- what type is this variable? Not allowed.

   // Second, sometimes the inferred type is misleading...
   auto s = "Hello, world!";
   // Can you guess what type s is?

   // Third, can't construct objects on the stack as easily...
   // Suppose I want to replace "Rational r(1, 3); with auto.
   // auto r(1,3); won't compile, why?




   // So when is auto useful?
   // If the return type of a function is obvious, but tedious to use.
   // Imagine I'm in your Othello project.

   OthelloBoard board;
   const vector<OthelloMove*> *history = board.GetMoveHistory(); // ugly!
   auto hist = board.GetMoveHistory(); // pretty!


   // For the same reason, auto is useful with iterators.
   for (auto itr = hist->rbegin(); itr != hist->rend(); itr++) {
      // printing in reverse order, C++11 style!
   }

}
예제 #12
0
Move MyBot::play(const OthelloBoard& board )
{
    list<Move> moves = board.getValidMoves( turn );
    if(moves.size()==0)
        return Move::pass();
    OthelloBoard b;
    list<Move>::iterator it;
    int currbest = POSLARGE;
    Move *cm = 0;
    bool firstRun = true;
    int val;
    priority_queue<MovePair> pq;

    for(it=moves.begin(); it!=moves.end(); it++){
        b = board;
        b.makeMove(turn,*it);
        int score = weights[it->x][it->y];
        MovePair *tempm = new MovePair(&(*it), score);
        pq.push(*tempm);
    }
    

    while(!pq.empty()){
        Move* m = pq.top().m;
        pq.pop();
        b = board;
        b.makeMove(turn,*m);
        val = alphaBeta(other(turn), b, NEGLARGE, val, PLY);
        if(val<currbest || firstRun){
            currbest = val;
            cm = m;
            firstRun = false;
        }
    }
    if(cm==0) cout<<"cm is null!!"<<endl<<moves.size()<<endl;
	return *cm;

}
예제 #13
0
int MyBot::alphaBeta(Turn turn, const OthelloBoard& board, int alpha, int beta, int ply)
{
	if(ply==0) {
		return evaluationFunction(turn, board);
	}
	else {
		list<Move> moves = board.getValidMoves(turn);
		int noOfMoves = moves.size();
		if(noOfMoves == 0) {
		    
		    list<Move> oppMoves = board.getValidMoves(other(turn));
			if(oppMoves.size()!= 0){
			    return (- (alphaBeta (other(turn), board, -beta, -alpha, ply-1)));
			}
			else return finalValue(turn, board);
		}
		else {
			list<Move>::iterator it = moves.begin();
			for(; it != moves.end(); it++){
				OthelloBoard board2 = board;
				board2.makeMove(turn, *it);
				//val is alpha in the case of max and beta in the case of min
				int val = - alphaBeta(other(turn), board2, - beta, -alpha, (ply-1));
				if(val >= beta)
				     return val;
				if(val >= alpha) {
				    alpha = val;
				    if(ply == PLY)
					    bestMove = &(*it);
				}
				
			}
			return alpha;
		}	
	}

}
예제 #14
0
int main(int argc, char* argv[]){
	//Welcome message
	cout << "Welcome to Othello!" << endl;
	//OthelloBoard class object
	OthelloBoard board;
	//OthelloView class object
	OthelloView view(&board);
	//Vector move pointer
	vector<OthelloMove *> move;
	//User input
	string input;

	while (!(board.IsFinished())) {
		//Display current board
		cout << view << endl;
		//Get all possible moves
		board.GetPossibleMoves(&move);
		//Possible moves variable
		string possibleMoves;

		for(OthelloMove *mov: move){
			//Retrieving all possible moves
			possibleMoves += *mov;
			//Removing all possible moves from the heap
			delete mov;

		}
		//Clear all move vector pointers
		move.clear();

		if (board.GetNextPlayer() == board.BLACK) {
			//Black's move
			cout << "\nBlack's turn" << endl;

		}

		else {
			//White's move
			cout << "\nWhite's turn" << endl;

		}
		//Display all possible moves
		cout << "Possible moves:\n" << possibleMoves << endl;

		cout << "Enter a command: ";
		//Get user input
		getline(cin, input);

		cout << endl;
		//Command input
		string choice;
		//new move position
		int position = board.EMPTY;

		for (int index = board.EMPTY; index < input.length(); index++){

			if (input[index] == ' ') {
				//Retrieving new move position
				position = index + 1;

				break;

			}
			//Retrieving command input
			choice += input[index];

		}

		if (choice == "move") {
			//Creating new move
			OthelloMove *newMove = board.CreateMove();

			try {
				//Retrieving new move
				(*newMove) = input.substr(position);

			}

			catch(OthelloException &error) {
				//Invalid new move
				cout << error.what() << endl;

				delete newMove;

			}
			//Get all new possible moves
			board.GetPossibleMoves(&move);

			bool equal = false;

			for (vector<OthelloMove *>::iterator itr = move.begin();
				itr != move.end(); ++itr){
				//Store all possible new moves
				OthelloMove *temp = *itr;

				if (*newMove == *temp && !equal) {
					//Apply new move onto the board
					board.ApplyMove(newMove);
					//Valid new move
					equal = true;

				}
				//Removing all possible moves on the heap
				delete temp;
			}

			if (!equal) {

				cout << "\nInvalid input" << endl;

				//Removing invalid new move
				delete newMove;

			}
			//Clear all move vector pointers
			move.clear();

		}


		else if (choice == "undo") {
			//Number of undoes
			int number = stoi(input.substr(position));

			if (number > board.GetMoveCount()){
				//Max number of undoes
				number = board.GetMoveCount();

			}

			while(number > board.EMPTY) {
				//Undo latest move
				board.UndoLastMove();
				//Next undo move
				number--;

			}
		}

		else if (choice == "showValue") {
			//Display current board value
			cout << "Board Value: " << board.GetValue() << endl;

		}

		else if (choice == "showHistory") {
			//History of all moves apply
			const vector<OthelloMove *> *mov = board.GetMoveHistory();
			//Number moves applied to the board
			int index = board.GetMoveCount();

			for (vector<OthelloMove *>::const_reverse_iterator temp =
				mov->crbegin(); temp != mov -> crend(); ++temp){
				//Getting latest move's history
				OthelloMove *m = *temp;

				if (index % (board.BLACK + board.BLACK) == 0) {
					//White history movement
					cout << "White: " << (string) *m << endl;
				}

				else {
					//Black history movement
					cout << "Black: " << (string) *m << endl;

				}
				//Next player's history movement
				index--;
			}

		}

		else {
			//Exit the game
			cout << "Thank you for playing" << endl;

			break;

		}

	}

	if (board.GetValue() > board.EMPTY) {
		//Black won the game
		cout << "\nBlack wins!" << endl;

	}

	else if (board.GetValue() < board.EMPTY){
		//White won the game
		cout << "\nWhite wins!" << endl;
	}

	else {
		//Tie game
		cout << "\nIt's a tie!" << endl;

	}

}
예제 #15
0
파일: main.cpp 프로젝트: mike13m/Othello
int main(int argc, char* argv[]) {
   
   // Initialization
   OthelloBoard board; // the state of the game board
   OthelloView v(&board); // a View for outputting the board via operator<<
   string userInput; // a string to hold the user's command choice
   vector<OthelloMove *> possMoves; // a holder for possible moves


   do {
      
      string command1, command2;
      //Clearing possible moves and freeing memory
      for (OthelloMove *move : possMoves) {
         delete move;
      }
      possMoves.clear();

      istringstream iss;
      bool isValidMove = false;
      cout << v << endl;
      
      board.GetPossibleMoves(&possMoves);
      
      cout << "Possible moves for " << ((board.GetNextPlayer() == -1) ? "White: " : "Black: ") << endl;
      for (OthelloMove *move : possMoves) {
         cout << (string) *move << " ";
      }
      cout << endl;

      cout << "Enter a command" << endl;
   
      getline(cin, userInput);
      iss.str(userInput);
      iss >> command1;

      if (command1 == "move") {
         
         iss >> command2;
         
         OthelloMove *m = board.CreateMove();
         
         try {
            
            *m = command2;
         
            for (OthelloMove *move : possMoves) {
               if (*m == *move) {
                  isValidMove = true;
               }
            }
            
            if (isValidMove){
               board.ApplyMove(m);
            }
            else {
               cout << "Not a valid move." << endl;
               delete m;
               continue;
            }
         }
         catch (OthelloException e) {
            cout << e.what() << endl;
            delete m;
         }
         
      }
      else if (command1 == "undo") {
         int times;
         
         iss >> times;
         
         for (int i = times; i > 0; i --) {
            if (board.GetMoveHistory()->size() == 0)
               break;
            else
               board.UndoLastMove();
         }
      }
예제 #16
0
int alphabeta(const OthelloBoard&  board,int depth,int alpha,int beta,Turn turn ,Turn max_player)
{
  Turn next_turn = other(turn);
  int k;
  if (depth == 0)
    {
      return score_gen(board,max_player);
    }
  if(board.getValidMoves( turn ).empty() && board.getValidMoves( other( turn ) ).empty())
  {
     return score_gen(board,max_player);
  }
  list<Move> Moves = board.getValidMoves(turn);
  int temp;
  OthelloBoard temp_board ;
  	    
  if (turn == max_player)
    { 
       if(!Moves.empty())
       {
         list<Move>::iterator it = Moves.begin();
         if(depth == DEPTH) 
         {
           bestMove = Move(*it);
         }
         for( ; it!=Moves.end() ; it++)   
	 {
	   temp_board = board;
	   temp_board.makeMove(turn,*it);
     /*      if(distance(it,Moves.end())<DEPTH && depth == DEPTH) 
	   {
         	k = DEPTH - distance(it,Moves.end());
	   }
	   else 
           {
                k=0;
           }*/
           if(double(clock() - start)/CLOCKS_PER_SEC>4.98)
           {
//		cout<<"broke";               
		break;
	   }
           temp = alphabeta(temp_board, depth - 1 , alpha, beta, next_turn, max_player);
           if(alpha < temp)
	    {
              alpha = temp;
              if(depth == DEPTH) {
                  bestMove = Move(*it);
              }
            }           
	    if (beta<=alpha)
	      { 
		 break;
	      }
	}
       return alpha;
       }
   }
    
   else
     {
        if(!Moves.empty())
        {
	for( list<Move>::iterator it = Moves.begin() ; it!=Moves.end() ; it++)   
	  {
	    temp_board = board;
            temp_board.makeMove(turn,*it);
            if(double(clock() - start)/CLOCKS_PER_SEC>4.98)
            {             
//	       cout<<"broke"; 
               break;
	    }
	    temp = alphabeta(temp_board, depth - 1, alpha, beta, next_turn, max_player);
	    if( beta > temp) 
              {
                beta = temp;
              }
            if (beta<=alpha)
                { 
		   break;
		}
          }
	  return beta;
	 }
      }
}
예제 #17
-1
/*Function to calculate 2 levels of Moves*/
void* threadFunc(void* ptr){
	int i, j;
	shallowDepthDone = false;
	threadDone = threadDone2 = -1;
	memset(thread2Done,false, sizeof(thread2Done));
	Turn otherTurn = other(ourTurn);
	immediateSucc = PrevBoard.getValidMoves(otherTurn);
	list<Move>::iterator it, kj;
	OthelloBoard saveBoard = PrevBoard;

	for(i = 0, it = immediateSucc.begin(); it != immediateSucc.end(); ++it, ++i){
		PrevBoard.makeMove(otherTurn, *it);
		moveLst1[i] = PrevBoard.getValidMoves(ourTurn);
		PrevBoard = saveBoard;
		++threadDone;
	}

	for(i = 0, kj = immediateSucc.begin() ; kj != immediateSucc.end(); ++kj, ++i ){
		PrevBoard.makeMove(otherTurn, *kj);
		OthelloBoard saveBoard1 = PrevBoard;
		for( j = 0, it = moveLst1[i].begin(); it != moveLst1[i].end(); ++it, ++j){
			PrevBoard.makeMove(ourTurn, *it);
			moveLst2[i][j] = PrevBoard.getValidMoves(otherTurn);
			PrevBoard = saveBoard1;
		}
		thread2Done[i] = true;
		++threadDone2;
		PrevBoard = saveBoard;
	}
	return NULL;
}