示例#1
0
Move AlphaBetaQId::findBestMove() {
	auto start_time = std::chrono::steady_clock::now();

	tt->aging();

	std::list<Move> l = possibleMoves();

	if (l.empty())		return NoMove;		// game over. i lost
	if (l.size() == 1)	return l.back();	// if only one move possible, return at once

	unsigned int r = tree_depth+1;			// for TT

	std::list<std::pair<int, Move> > sl;
	for (const auto& m: l) { sl.push_back(std::pair<int, Move>(value, m)); }	// copy possible moves

	for (tree_depth = 1; tree_depth <r; tree_depth++) {
		std::cerr << "depth=" << std::setw(2) << tree_depth << "\t";
		for (auto &p: sl) {
			move(p.second);
			p.first =  -evaluateMoveTree(tree_depth-1, -mateValue(), mateValue());
			undo(p.second);

			std::cerr << moveValueString	(p.second, p.first) << "\t";
		}
		auto end_time  = std::chrono::steady_clock::now();
		std::cerr << "(" << std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count() << " s)" << "\r"; // std::endl;
		sl.sort(std::greater<std::pair<int, Move> >());
	}
	tree_depth--;	// restore from last ++, for next run
	std::cerr << std::endl;
	auto end_time  = std::chrono::steady_clock::now();
	std::cerr << "Time elapsed " << std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << "us.\n";

	return sl.front().second;	// best move;
}
示例#2
0
int AlphaBetaQId::evaluateMoveTreeQuiesce(int depth, int alpha, int beta) {
#ifdef USE_POSITION_KEY
	int a = alpha;	// remember argument
	int w;
	if (probe(w, alpha, beta, depth)) return w;
#endif
	std::list<Move> l = possibleMoves();

	if (l.empty())		 { return -mateValue(tree_depth-depth);	}	// game over, node is terminal. return mate in plies
	if (l.front().isQuiet()) { return evaluatePosition();		}	// no jumps, so quiesence search over. node is (at least) quiet

	Move best_move = NoMove;

	for (const auto& m: l) {						// play forced moves
		move(m);
		int v = -evaluateMoveTreeQuiesce(depth-1, -beta, -alpha);
		undo(m);

		if (v >= beta)  { store(v, a, beta, NoMove, depth); return v; }
		if (v >  alpha) { alpha = v; best_move = m; }
	}

	store(alpha, a, beta, best_move, depth);				// allow negative depthes in TT

	return alpha;
}
示例#3
0
int AlphaBetaQId::evaluateMoveTree(unsigned int depth, int alpha, int beta) {
#ifdef USE_POSITION_KEY
	int a = alpha;
	int w;
	if (probe(w, alpha, beta, depth)) return w;
#endif
	if (!depth) { return evaluateMoveTreeQuiesce(depth, alpha, beta); }	// end of search depth. just forward all args to qsearch.

	std::list<Move> l = possibleMoves();

	if (l.empty()) { return -mateValue(tree_depth-depth);		 }	// game over, node is terminal

	Move best_move = NoMove;

	for (const auto& m: l) {
		move(m);
		int v = -evaluateMoveTree(depth-1, -beta, -alpha);
		undo(m);

		if (v >= beta)  { store(v, a, beta, NoMove, depth); return v; }
		if (v >  alpha)	{ alpha = v; best_move = m; }
	}

	store(alpha, a, beta, best_move, depth);

	return alpha;
}
示例#4
0
文件: Damas_C.cpp 项目: TaynaCT/damaC
///condiciona os movimentos, de acordo com a disponibilidades das casas. Adicionando os possiveis a arvore
void possibleMoves(Movimentos tree, int x, int y, char tipo, char nome [10], int turno) {

	int contador = 0;

	if (tabuleiro[x][y] == 1) {

		if (tabuleiro[x + 1][y + 1] == 0)
			inserirMovimentoPossivel(tree, x + 1, y + 1, tipo, nome, turno);
			
		if (tabuleiro[x - 1][y + 1] == 0)
			inserirMovimentoPossivel(tree, x + 1, y + 1, tipo, nome, turno);
				
		while (contador < 5) {
			//recorre 5 vezes a função 		
			
			possibleMoves(tree, x + 1, y + 1, tipo, nome, turno);
			possibleMoves(tree, x - 1, y + 1, tipo, nome, turno);
			contador++;
		}
	}

	if (tabuleiro[x][y] == 2) {

		if (tabuleiro[x + 1][y - 1] == 0)
			inserirMovimentoPossivel(tree, x + 1, y + 1, tipo, nome, turno);
				
		if (tabuleiro[x - 1][y - 1] == 0)
			inserirMovimentoPossivel(tree, x + 1, y + 1, tipo, nome, turno);
		

		while (contador < 5) {//recorre 5 vezes a função 
			possibleMoves(tree, x - 1, y - 1, tipo, nome, turno);
			possibleMoves(tree, x + 1, y - 1, tipo, nome, turno);
			contador++;
		}
	}

}
示例#5
0
文件: mc.c 项目: dsteuer/laska
Move MCBoard::randomMove() {
	std::list<Move> l = possibleMoves();

	if (!l.empty()) {
		unsigned int choose = rand() % l.size(); 
		unsigned int c = 0;
		for (const auto& m: l) {
			if (c == choose) { return m; }
			c++;
		}
	}	

	return NoMove;
}
示例#6
0
vector<Point> AIPlayer::getAllPossibleMoves(GameField gameField)
{
	int i, j;
	vector<Point> possibleMoves(0);

	for (i = 0; i < gameField.getSize(); i++)
	{
		for (j = 0; j < gameField.getSize(); j++)
		{
			if (gameField.isEmpty(i, j))
			{
				possibleMoves.push_back(Point(i, j));
				cout << i << " " << j << endl;
			}
		}
	}

	return possibleMoves;
}
示例#7
0
文件: mc.c 项目: dsteuer/laska
Move MCBoard::findBestMove() {
	Move best_move = NoMove;
	std::list<Move> l = possibleMoves();

	int best_value = -mateValue();
	for (const auto& m: l) {
		move(m);
		std::cerr << m.toString() << std::endl;
		int r = evaluatePosition(turn);
		if (r > best_value) {
			best_value = r;
			best_move = m;
		}
		std::cerr << r << " - " << best_value << std::endl;

		undo(m);
	}

	return best_move;
}
示例#8
0
Move *Player::doMove(Move *opponentsMove, int msLeft) {
    /* 
     * TODO: Implement how moves your AI should play here. You should first
     * process the opponent's opponents move before calculating your own move
     */ 
     Side opside;
     if (side == BLACK)
     {
        opside = WHITE;
     }
     else
     {
        opside = BLACK;
     }
     board.doMove(opponentsMove, opside);
     updateWeights(opponentsMove);

    if(board.hasMoves(side))
    {

        std::vector<Move*> moves = possibleMoves();
        int max_index = 0; //index of the move whose square has the highest known heuristic value
        for (unsigned i = 0; i < moves.size(); i++)
        {
            if (getSquareWeight(moves[i]) > getSquareWeight(moves[max_index]))
            {
                max_index = i;
            }

        }
        board.doMove(moves[max_index], side);
        updateWeights(moves[max_index]);
        return moves[max_index];
    }
    else
    {
        return NULL;
    }

}
示例#9
0
int Minimax::doMinimax(std::vector<VolcanoBoard>& res, const VolcanoBoard& vb, int depth) {
    VolcanoBoard currVb, bestVb;
    std::vector<VolcanoBoard> currList, bestList;
    depth--;

    bool touched = false;
    int bestScore = MAX_SCORE;
    if (vb.isFirstPlayer()) {
        bestScore = -bestScore;
    }
    int currScore = 0;

    // get all possible moves.
    VolcanoMoveGen possibleMoves(vb);

    while (!possibleMoves.isEnd()) {
        currVb = *possibleMoves;
        if (testEndCondition(vb) || depth <= 0) {
            // game over, get score
            currScore = getScore(vb);
        } else {
            // score by calling doMinimax recursively
            currVb.changePlayer();
            currScore = doMinimax(currList, currVb, depth);
        }
        if (!vb.isFirstPlayer()) {
            currScore = -currScore;
        }
        if (vb.isFirstPlayer() && currScore > bestScore) {
            // if p1, return max scoring move
            bestScore = currScore;
            bestVb = currVb;
            bestList = currList;
            touched = true;
        } else if (!vb.isFirstPlayer() && currScore < bestScore) {
            // if p2, return min scoring move
            bestScore = currScore;
            bestVb = currVb;
            bestList = currList;
            touched = true;
        }
        possibleMoves++;
    }
    
    if (touched) {
         TODO : curr/bestLists
        
        res.push_back(bestVb);
    } else {
        // raise error
    }
    return bestScore;
    /*
    function minimax(node, depth, maximizingPlayer)
    if depth = 0 or node is a terminal node
        return the heuristic value of node
    
    bestValue := -∞
    for each child of node
        val := minimax(child, depth - 1, FALSE)
        bestValue := max(bestValue, val)
    return -bestValue
    */

}
示例#10
0
// graph where s_i = {pos_D, pos_R, cost}, pointer to parents.
// possible entries (diamond pushes) are added with wavefront
// the shortest path till now is explored further (heap)
// hash table to check if node exists
bool Sokoban::findPath(){
    printMap(map_);

    std::cout << "Init. finding paths..." << std::endl;
    // graph to store the tree of possibilities
    graph paths;
    // has a solution been found
    bool solution_found = false;

    // - make needed maps
    // heuristic map
    std::vector< std::vector<char> > heuristic_map = map_;
    wavefront(heuristic_map, goals_);
//    printMap(heuristic_map);

//    std::cout << std::endl;
    // deadlock map
    std::vector< std::vector<char> > deadlock_map = map_;
    deadlocks(deadlock_map);
//    printMap(deadlock_map);


    // the next child to consider (lowest cost)
    node * cheapest_leaf = nullptr;

    // node to add
    node nextnode(0, cheapest_leaf, heuristic_map);
    nextnode.setRobot(pos_t(robot_.x_, robot_.y_));
    nextnode.setDiamonds(diamonds_);
    std::cout << "# of Diamonds: " << diamonds_.size() << std::endl;
    // add the initial position
    paths.createChild(nextnode);


    int lastCost = 0;
    std::cout << "Exploring paths..." << std::endl;
    // run this until the path is found or no paths can be taken
    int iterations = 0; // debug thing
    while(!solution_found && paths.getNextChild(cheapest_leaf)){
        iterations++;
//        if(lastCost < cheapest_leaf->getCost() + cheapest_leaf->getHeuristic()){
//            lastCost = cheapest_leaf->getCost() + cheapest_leaf->getHeuristic();
//            std::cout << "current cost: " << lastCost << ", open-/closed-list size: " << paths.getOpenListSize() << " / " << paths.getClosedListSize() << std::endl;

//        }
        // check cheapest leaf if it is the solution
        solution_found = cheapest_leaf->compSolution(map_);
        if(!solution_found){
            // generate the key for the element
            std::string key = cheapest_leaf->getKey(map_size_.x_);
            // check that this node has not already been found, if so, remove it
            bool unique_node = paths.nodeUnique(key);
            bool valid_node = false;
            std::vector< pos_t > * diamonds;
            if(unique_node){
                paths.addChild(cheapest_leaf, key);
                // get diamonds pointer
                diamonds = cheapest_leaf->getDiamonds();
                // check that the node is valid (all diamonds are in valid positions)
                valid_node = validNode(diamonds, deadlock_map);

            }
            else{
                paths.deleteChild(cheapest_leaf);
            }
            std::vector< std::vector<char> > wf_map;
            if(unique_node && valid_node){
                wf_map = map_;
                // make wf map
                for(int d = 0; d < diamonds->size(); d++){
                    int x = (*diamonds)[d].x_;
                    int y = (*diamonds)[d].y_;
                    wf_map[y][x] = MAP_DIAMOND;
                }
                // make wavefront from pos to see the distance to the diamonds
                std::vector< pos_t > robot_position = {*(cheapest_leaf->getRobotPos())};
                wavefront(wf_map, robot_position);
                // find the diamonds that can be moved
                std::vector< node > moves;
                possibleMoves(wf_map, diamonds, moves, cheapest_leaf);
                // add the moves to the heap (does not take care of states being the same)
                for(int newChild = 0; newChild < moves.size(); newChild++){
                    // update heuristics first
                    moves[newChild].updateHeuristic(heuristic_map);
                    // add the child
//                    paths.createChild(moves[newChild]);
                }
                paths.createChild(moves);
            }
        }
        else{
            // return shortest path
            node * parent = cheapest_leaf->getParent();
            node * child = cheapest_leaf;
            path_ = "";
            while(parent != nullptr){
                std::vector< pos_t > p_diamonds;
                std::vector< pos_t > c_diamonds;
                std::vector< std::vector<char> > wf_map;
                p_diamonds = *(parent->getDiamonds());
                c_diamonds = *(child->getDiamonds());
                // set diamonds to walls to generate wfamp to move with
                wf_map = map_;
                for(int d = 0; d < p_diamonds.size(); d++){
                    int x = (p_diamonds)[d].x_;
                    int y = (p_diamonds)[d].y_;
                    wf_map[y][x] = MAP_DIAMOND;
                }
                // robot pos
                pos_t p_position = *(parent->getRobotPos());
                pos_t c_position = *(child->getRobotPos());
                std::vector< pos_t > wf_start = {p_position};
                wavefront(wf_map, wf_start);
                // find the diamond that was moved
                int p_d = 0;
                int c_d = 0;
                while(p_diamonds.size() != 1){
                    bool somethingremoved = false;
                    c_d = 0;
                    while(c_d < c_diamonds.size() && !somethingremoved){
                        if((p_diamonds)[p_d].y_ == (c_diamonds)[c_d].y_ &&(p_diamonds)[p_d].x_ == (c_diamonds)[c_d].x_){
                            // remove the diamond
                            p_diamonds.erase(p_diamonds.begin() + p_d);
                            c_diamonds.erase(c_diamonds.begin() + c_d);
                            somethingremoved = true;

                        }
                        c_d++;
                    }
                    p_d++;
                    if(p_d >= p_diamonds.size()){
                        p_d = 0;
                    }
                }
                // adjust the start pos to be t push spot
                int x = (p_diamonds)[0].x_ - (c_diamonds)[0].x_;
                int y = (p_diamonds)[0].y_ - (c_diamonds)[0].y_;
                c_position.x_ += x;
                c_position.y_ += y;
                // find sub path
                std::string subpath = "";
                findSubPath(subpath,wf_map, p_position, c_position);
                // add the final push
                if(x == 1 && y == 0){
                    subpath += "W";
                } else if(x == -1 && y == 0){
                    subpath += "E";
                } else if(x == 0 && y == 1){
                    subpath += "N";
                } else if(x == 0 && y == -1){
                    subpath += "S";
                }
                // add the path
                path_ = subpath + path_;
                // find new nodes
                child = parent;
                parent = child->getParent();
            }
            std::cout << "Cheapest path length: " << cheapest_leaf->getCost() << std::endl;
        }
    }

    if(!paths.getNextChild(cheapest_leaf)){
        std::cout << "No more possible paths left to explore.\n";
    }

    std::cout << "# of iterations gone through: " << iterations << "\n";

    std::cout << "# of elements in closed list: " << paths.getClosedListSize() << "\n";

    std::cout << "# of elements in open list: " << paths.getOpenListSize() << "\n";


    return solution_found;
}