Пример #1
0
int minimax_threat(int player, luint m[4], int depth, int hash, int u, int v){
	//minimax ale player musí hrat na hranu (u,v) ktera je volna
//	print_adjacency_matrix(m,"");

timer++;
	luint m2[4];
	int hash2;

	if ( NORMALIZATION_FREQUENCY > 0 && depth % NORMALIZATION_FREQUENCY == 0) 
		hash = normalization(m,hash);

	int winner;
	if ( (winner = get_from_cache(m,hash) ) != 42){
//	if ( depth % 3 == 1 && (winner = get_from_cache(m,hash) ) != 42 ) {
		//je v cachy
		return winner;
	}

	if (depth == (N*(N-1))/2 )
		//vse je obarvene remiza
		//TODO diky poctu zbylych hran a tomu jake jsou hrozby by mohlo jit skoncit driv
		return 0;

	int x,y;
	int t = threats(player,m,u,v,&x,&y);
	if (t > 1){
		if (player == GREEN)
			return 1;
		else
			return -1;
	}
	copy_graph(m2,m);
	hash2 = set_edge_color(player,m2,hash,u,v);

	if (t == 1){
		winner = minimax_threat(next(player),m2,depth+1,hash2,x,y);
	} else {
		winner = minimax(next(player),m2,depth+1,hash2);
	}

	if ( depth % 3 == 1 ) 
		put_into_cache(m2,hash2,winner);	
	return winner;
}
Пример #2
0
std::pair<Move, int> AIShell::IDSearchRecurse(int depth, int** state, int turn, int alpha, int beta, struct timeval& start)
{
    std::pair<Move, int> inValid = std::make_pair(Move(-1, -1), -1);
    
    //AI_PIECE bigger better (MAX); HU_PIECE smaller better (MIN).
    int thisAlpha = alpha;
    int thisBeta = beta;
    
    // Create a copy of the current gameState
    int** tempGameState = new int*[numCols];
    for (int col = 0; col < numCols; col++)
    {
        tempGameState[col] = new int[numRows];
        for(int row = 0; row < numRows; row++)
        {
            tempGameState[col][row] = state[col][row];
        }
    }
    
    // Makes sure time is still under the limit
    if(!isUnderLimit(start)) {return inValid;}
    
    // Base Case for MinMax
    if (depth == 0)  //At leaf node, actual move is not important since we just care the eval of this node
    {
        Move dummyMove;
        int hValue = heuristicEval(state, turn, start);
        
        std::pair<Move, int> dummyMoveEval = std::make_pair(dummyMove, hValue);
        return dummyMoveEval;
    }
    
    // Recursive Step for MinMax
    else
    {
        // Search for threats (k-1 in a row) on the board
        std::vector<int> evalNodes;
        std::vector<std::pair<int, int> > movesList = threats(tempGameState);
        
        // If there are no threats find all available moves
        if(movesList.size() == 0 && isUnderLimit(start))
        {
            movesList = emptyBlock(tempGameState);
        }
      
        // Makes sure time is still under the limit
        if(!isUnderLimit(start)) {return inValid;}
        
        for (int i = 0; i < movesList.size(); i++)
        {
            // If there's only 1 possible move.
            if(movesList.size() == 1)
            {
                Move bestMove(movesList[i].first, movesList[i].second);
                std::pair<Move, int> evalValue = std::make_pair(bestMove, 0);
                return evalValue;
            }
            
            // If there's more than 1 possible move.
            tempGameState[movesList[i].first][movesList[i].second] = turn;
            
            if (turn == AI_PIECE){
                int nextLevelEval = IDSearchRecurse(depth - 1, tempGameState, HUMAN_PIECE, thisAlpha, thisBeta, start).second;
                // Makes sure time is still under the limit
                if(!isUnderLimit(start)) {return inValid;}
                
                evalNodes.push_back(nextLevelEval);
                if (nextLevelEval >= thisBeta){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    break;
                }
                
                if (nextLevelEval >= thisAlpha){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    thisAlpha=nextLevelEval;
                }
                
                // Makes sure time is still under the limit
                if(!isUnderLimit(start)) {return inValid;}
                
            }
            
            else{
                int nextLevelEval = IDSearchRecurse(depth - 1, tempGameState, AI_PIECE, thisAlpha, thisBeta, start).second;
                // Makes sure time is still under the limit
                    if(!isUnderLimit(start)) {return inValid;}
                
                evalNodes.push_back(nextLevelEval);
                if (nextLevelEval <= thisAlpha){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    break;
                }
                
                if (nextLevelEval <= thisBeta){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    thisBeta = nextLevelEval;
                }
                // Makes sure time is still under the limit
                if(!isUnderLimit(start)) {return inValid;}
            }
            
            tempGameState[movesList[i].first][movesList[i].second] = 0;   //Set the block back
            // Makes sure time is still under the limit
            if(!isUnderLimit(start)) {return inValid;}
        }
        
        if (turn == AI_PIECE)
        {
                
            Move bestMove(movesList[0].first, movesList[0].second);
            std::pair<Move, int> evalValue = std::make_pair(bestMove, evalNodes[0]);
                
            deleteBoard(tempGameState);
                
            // Makes sure time is still under the limit
            if(!isUnderLimit(start)) {return inValid;}
                
            return evalValue;
        }
            
        else
        {
            Move bestMove(movesList[0].first, movesList[0].second);
            std::pair<Move, int> evalValue = std::make_pair(bestMove, evalNodes[0]);
                
            deleteBoard(tempGameState);
                
            // Makes sure time is still under the limit
            if(!isUnderLimit(start)) {return inValid;}
                
            return evalValue;
        }
    }
}
Пример #3
0
int minimax(int player, luint m[4], int depth, int hash){
	//1 zeleny vyhraje 
	//0 remiza obarvene bez k4 
	//-1 cerveny vyhraje
//	print_adjacency_matrix(m,"");
timer++;
	int max = -1;
	int min = 1;
	luint m2[4];
	int hash2 = 0;

	if ( NORMALIZATION_FREQUENCY > 0 && depth % NORMALIZATION_FREQUENCY == 0) 
		hash = normalization(m,hash);

	int winner;
	if ( (winner = get_from_cache(m,hash) ) != 42 && depth > 0){
//	if ( depth % 3 == 1 && (winner = get_from_cache(m,hash) ) != 42 ) {
		//je v cachy a zaroven neni prazdny
		return winner;
	}
	if ( depth == (N*(N-1))/2 )
		//vse je obarvene remiza
		return 0;

	for (uint i=0; i<N; i++)
		for (uint j=i+1; j<N; j++){
			if (get_edge_color(m,i,j) == 0){
				//pro vsechny neobarvene hrany (i,j)
				int x,y;
				int t = threats(player,m,i,j,&x,&y);
				if (t > 1){
					if (player == GREEN)
						return 1;
					else
						return -1;
				}
/*
				if (win(player,m,i,j)){
					if (player == GREEN)
						return 1;
					else
						return -1;
				}				
*/				copy_graph(m2,m);
				hash2 = set_edge_color(player,m2,hash,i,j);
				int tmp;
				if (t == 1){
					tmp = minimax_threat(next(player),m2,depth+1,hash2,x,y);
				} else {
					tmp = minimax(next(player),m2,depth+1,hash2);
				}
				if (tmp > max)
					max = tmp;
				if (tmp < min)
					min = tmp;
			}

				
		}
	if (player == GREEN)
		winner = max;
	else
		winner = min;

	if ( depth % 3 == 1 ) 
		put_into_cache(m2,hash2,winner);	
	return winner;
}