int minDistance(int height, int width, vector<int>& tree, vector<int>& squirrel, vector<vector<int>>& nuts) { vector<int> tree_nuts, squirrel_nuts; for (auto nut : nuts) { tree_nuts.push_back(manhattan(nut, tree)); squirrel_nuts.push_back(manhattan(nut, squirrel)); } int max_diff = INT_MIN; for (int i = 0; i < nuts.size(); ++i) { max_diff = max(max_diff, tree_nuts[i]-squirrel_nuts[i]); } return 2*accumulate(tree_nuts.begin(), tree_nuts.end(), 0) - max_diff; }
vector<MoveCommand> SoulFind::getCommand(int playerId, const Status& status) { vector<MoveCommand> command; auto soulPoints = status.getSoulPoints(); if (soulPoints.empty()) return command; const Point point = status.getNinjas()[playerId].point; int num = 0; int range = manhattan(point, soulPoints[0]); for (int i = 1; i < int(soulPoints.size()); i++) { int r = manhattan(point, soulPoints[i]); if (range > r) { range = r; num = i; } } const Point d = soulPoints[num] - point; command = move(playerId, status, d); if (command.empty()) { command.resize(2); auto stage = status.getStage(); for (int i = 0; i < 4; i++) { Stage stage01(stage.getStage()); const Point p1 = stage.moveSimulation(point, MoveCommand(i), stage01); if (p1 != point) { for (int j = 0; j < 4; j++) { Stage stage02(stage01.getStage()); const Point p2 = stage.moveSimulation(p1, MoveCommand(j), stage02); if (p2 != p1) { command[0] = MoveCommand(i); command[1] = MoveCommand(j); } } } } } return command; }
void CombatLogic::simpleCombatAI() { Creature* currCreature = getActiveCreature(); intp currPos = currCreature->combatPos; float bestDist = oo; int bestMove = 0; for (int i = 0; i < (int)creatures.size(); i++) { if (creatures[i]->getFactionId() != currCreature->getFactionId() && creatures[i]->count > 0) { intp enemyPos = creatures[i]->combatPos; for (int j = 0; j < (int)validMoves.size(); j++) { intp nextPos = validMoves[j]; // TODO ranged if (abs(nextPos.x - enemyPos.x) <= 1 + eps && abs(nextPos.y - enemyPos.y) <= 1 + eps) { move(validMoves[j], enemyPos - nextPos); return; } else { float manDist = manhattan(nextPos, enemyPos); if (manDist < bestDist) { bestMove = j; bestDist = manDist; } } } } } move(validMoves[bestMove], 0); }
void Pathfinder::search() { init(); BinaryHeap openHeap; mStart->g = 0; mStart->h = manhattan(mStart, mGoal); mStart->opened = true; openHeap.push(mStart); while (openHeap.size() > 0) { // Pop the node with the smallest f value Node* currentNode = openHeap.pop(); // Check if we hit the target if (currentNode == mGoal) { // Compute the path and exit generatePath(currentNode); return; } currentNode->closed = true; std::vector<Node*> neighbors = getNeighborsAdjacentTo(currentNode); for (int i = 0; i < neighbors.size(); i++) { Node* neighbor = neighbors[i]; if (neighbor->closed || neighbor->worldRef->getMaterial()->isCollidable()) continue; int gScore = currentNode->g + 1; if(!neighbor->opened || gScore < neighbor->g) { neighbor->g = currentNode->g + 1; neighbor->h = manhattan(currentNode, neighbor); neighbor->parent = currentNode; neighbor->opened = true; openHeap.push(neighbor); } } } }
void print() { std::cout << toString(); std::cout << "Dimension "<< dimension()<< '\n'; std::cout << "is Goal "<< isGoal() << '\n'; std::cout << "hamming "<< hamming() << '\n'; std::cout << "manhattan " << manhattan() << '\n'; }
void _identifySuccessors(struct grid *gd, struct node *activeNode, struct open_list *current, struct node *endNode) { int endX = endNode->x; int endY = endNode->y; int *jumpPoint; struct neighbor_xy_list *neighbors_head = _findNeighbors(gd, activeNode); struct neighbor_xy_list *neighbors_current = neighbors_head; while (neighbors_head != (neighbors_current = neighbors_current->right)) { if (DEBUG) { if (isWalkableAt(gd, neighbors_current->x, neighbors_current->y)) printf("Neighbor x:%d/y:%d is walkable!\n", neighbors_current->x, neighbors_current->y); else printf("Neighbor x:%d/y:%d is NOT walkable!\n", neighbors_current->x, neighbors_current->y); } jumpPoint = _jump(gd, neighbors_current->x, neighbors_current->y, activeNode->x, activeNode->y, endNode); if (DEBUG) printf("Jump point not set!\n\n"); if (jumpPoint != NULL) { int jx, jy, d, ng; struct node *jumpNode; if (DEBUG) printf("Jump point set!\n\n"); jx = jumpPoint[0]; jy = jumpPoint[1]; free(jumpPoint); malloc_count--; /* [ Malloc Count ] */ jumpNode = getNodeAt(gd, jx, jy); if (jumpNode->closed) { continue; } d = euclidean(abs(jx - activeNode->x), abs(jy - activeNode->y)); ng = activeNode->g + d; if (!jumpNode->opened || ng < jumpNode->g) { jumpNode->g = ng; if (!jumpNode->h) jumpNode->h = manhattan(abs(jx - endX), abs(jy - endY)); /* jumpNode->h = jumpNode->h || manhattan(abs(jx - endX), abs(jy - endY)); // ASK FIDELIS !! */ jumpNode->f = jumpNode->g + jumpNode->h; if (DEBUG) printf("Node g:%d h:%d f:%d\n", jumpNode->g, jumpNode->h, jumpNode->f); jumpNode->parent = activeNode; if (!jumpNode->opened) { current = ol_insert_right(current, jumpNode); jumpNode->opened = true; } else { ol_listsort(current->right); } } } } neighbor_xy_clean(neighbors_head); }
std::vector<Coord> AStar( std::vector< std::vector< int > > grid, Point start, Point end ) { //The current 'focal' point. Point *cur; //The open and closed lists. std::vector< Point* > closed; std::vector< Point* > open; //Start by adding the starting position to the list. open.push_back( &start ); //Just so it knows whether or not to try and reconstruct a path. bool error = true; while( open.size() > 0 ) { //The current point is the first entry in the open list. cur = open.at(0); if( cur->getPos() == end.getPos() ) { error = false; break; } //Add in all the neighbors of the current point. for( int y = -1; y <= 1; y++ ) { for( int x = -1; x <= 1; x++ ) { int curX = cur->getPos().x+x; int curY = cur->getPos().y+y; int movCost = 10; //If it is a diagonal, make it cost 14 instead of 10. if( (y == -1 && x == -1)|| (y == 1 && x == -1)|| (y == -1 && x == 1)|| (y == 1 && x == 1)) { movCost = 14; //continue; } Coord temp( curX, curY ); bool make = true; //If it is outside the range of the map, continue. if( curY >= grid.size() || curX >= grid.size() ) { continue; } /* These two loops are to check whether or not the point's neighbors already exist. This feels really sloppy to me. Please tell me if there is a better way. */ for( int i = 0; i < open.size(); i++ ) { if( temp == open.at(i)->getPos() ) { make = false; break; } } for( int i = 0; i < closed.size(); i++ ) { if( temp == closed.at(i)->getPos() ) { make = false; break; } } //If the point in the map is a zero, then it is a wall. Continue. if( (grid.at(temp.x).at(temp.y) == 0 ) || ( temp.x<0 || temp.y < 0 ) ) { continue; } //If it is allowed to make a new point, it adds it to the open list. if( make ) { int gScore = cur->getCost(); int hScore = manhattan( end.getPos(), Coord( curX, curY ) ); int tileCost = grid[curX][curY]; int fScore = gScore+hScore+tileCost+movCost; open.push_back( new Point( curX, curY, fScore, cur ) ); } } } //It then pushes back the current into the closed set as well as erasing it from the open set. closed.push_back( cur ); open.erase( open.begin() ); //Heapsort works, guranteed. Not sure if it's a stable sort, though. From what I can tell that shouldn't matter, though. open = heapsort( open ); } std::vector<Coord> path; if( error ) { return path; } //Reconstruct a path by tracing through the parents. while( cur->getParent() != nullptr ) { path.push_back( cur->getPos() ); cur = cur->getParent(); } path.push_back( cur->getPos() ); return path; }
/** * @brief Résout un puzzle * @param[in,out] p le puzzle à résoudre * @param[in] t le damier initial * @param[in,out] os flux de sortie */ void jouer(Puzzle& p, const Tab2D& t, std::ostream& os) { Etat etatInitial; Etat etatCourant; Tab2D damierFinal; Etat etatDerive; double tempsDebutRecherche = getTime(); but(damierFinal, t.nbL, t.nbC); initialiser(etatInitial.damier, t.nbL, t.nbC); etatInitial.mouvement = FIXE; etatInitial.precedent = 0; etatInitial.g = 0; //Copie du damier inititial dans etatInitial for (unsigned int l = 0; l < t.nbL; ++l) { for (unsigned int c = 0; c < t.nbC; ++c) { etatInitial.damier.tab[l][c] = t.tab[l][c]; } } etatInitial.h = manhattan(etatInitial.damier, damierFinal); initialiser(etatDerive.damier, t.nbL, t.nbC); inserer(p.lEAE, 0, etatInitial); //étatInitial dans LEAE bool solutionTrouvee = false; bool mvtPossible; unsigned int pos; while (p.lEAE.nb != 0) { pos = minimal(p.lEAE); etatCourant = lire(p.lEAE, pos); //on prend le 1er état à explorer //insérer étatCourant dans LEE inserer(p.lEE, longueur(p.lEE), etatCourant); supprimer(p.lEAE, pos); //supprimer étatCourant de LEAE if (etatCourant.h == 0) { // le damier de étatCourant est le damier but solutionTrouvee = true; break; //sortir de la boucle while } /*pour_tout (mouvement possible associé à étatCourant) mouvement possible relatif à damier de étatCourant (etatCourant.damier) ordre d'exploration (obligatoire) NORD, EST, SUD, OUEST */ //initialiser un étatDérivé // d'après le mouvement for(int m = OUEST; m >= NORD; --m) { mvtPossible = deriver(etatCourant, (Mouvement) m, etatDerive); if (mvtPossible && !rechercher(etatDerive, p.lEAE)\ && !rechercher(etatDerive, p.lEE)) { etatDerive.precedent = longueur(p.lEE) - 1; etatDerive.h = manhattan(etatDerive.damier, damierFinal); etatDerive.g = etatCourant.g + 1; //insérer étatDérivé dans LEAE inserer(p.lEAE, longueur(p.lEAE), etatDerive); } } } double tempsFinRecherche = getTime(); cout << "Durée de recherche : " << tempsFinRecherche - tempsDebutRecherche <<" seconde(s)."<< endl; if (solutionTrouvee) { Pile sol; Etat etatSol; initialiser(sol, 3, 2); initialiser(etatSol.damier, t.nbL, t.nbC); //Stockage de la solution etatSol = lire(p.lEE, longueur(p.lEE)-1); empiler(sol, etatSol); while (etatSol.precedent != 0) { etatSol = lire(p.lEE, etatSol.precedent); empiler(sol, etatSol); } empiler(sol, etatInitial); //Affichage de la solution os << "Damier : " << t.nbL << " lignes " << t.nbC << " colonnes" << endl; os << "Solution en " << sol.sommet << " mouvements" << endl; while (!estVide(sol)) { afficher(sommet(sol), os); os << endl; depiler(sol); } detruire(sol); detruire(etatSol.damier); } else { os << "Solution non trouvée" << endl; } detruire(etatInitial.damier); detruire(etatCourant.damier); detruire(etatDerive.damier); detruire(damierFinal); }
/* * pathfinder(info,monster, x1, y1, x2, y2) * * Get path between x1,y1 and x2,y2. * Uses info->is_walkable to determine if monster can * walk on grid position (x,y). Passes monster to this function */ node_t * pathfinder(pathfinder_info *info, void *monster, int x1, int y1, int x2, int y2)// int *x2_ptr, int *y2_ptr) { node_t *start_node; node_t *node; node_t *neighbour; int steps; unsigned char temp_g_score; start_node = node_new_pos(info, x1, y1); bin_heap_clear(info->open_heap); bin_heap_add(info->open_heap, start_node); /* Set all scores to 0 */ memset(info->g_score, 0, info->grid_width*info->grid_height); memset(info->h_score, 0, info->grid_width*info->grid_height); /* Set all nodetypes to 0 */ memset(info->node_type, 0, info->grid_width*info->grid_height); #define P(node) node->x + node->y*info->grid_width info->g_score[P(start_node)] = 0; info->h_score[P(start_node)] = manhattan(x1, y1, x2, y2); /* cost = f_score */ start_node->cost = info->g_score[P(start_node)] + info->h_score[P(start_node)]; steps = 0; while (info->open_heap->heap_size) { node = bin_heap_get_min(info->open_heap); steps ++; if (node->x == x2 && node->y == y2) { /* Reverse path, and remove path * from node-list */ node = reconstruct_path(info, node); /* clear up open-heap */ bin_heap_clear(info->open_heap); pathfinder_free_nodes(info); return node; } bin_heap_del_min(info->open_heap); /* Set type to CLOSED */ info->node_type[P(node)] = TYPE_CLOSED; int direction; /* Look at node's neighbours */ for (direction=0;direction<4;direction++) { int x,y; x = node->x + mod_x[direction]; y = node->y + mod_y[direction]; /* Don't walk off map */ if (x < 0 || y < 0 || x > info->grid_width - 1 || y > info->grid_height - 1) continue; /* Don't go back */ if (node->parent && node->parent->x == x && node->parent->y == y) continue; /* check if we can walk that way */ if (!info->is_walkable(x, y, monster)) continue; temp_g_score = info->g_score[P(node)] + 1; char added = 0; char type; int neighbour_idx = 0; int curr_score; /* If neighbour in OPEN-set and cost is lower */ type = info->node_type[x + y*info->grid_width]; curr_score = info->g_score[x + y*info->grid_width]; if (type != TYPE_CLOSED && (curr_score == 0 || temp_g_score < curr_score)) { /* Neighbour not in OPEN and not in CLOSED */ if (type != TYPE_OPEN) { added = 1; neighbour = node_new_pos(info, x, y); }else{ neighbour_idx = find_node(info->open_heap, x, y); neighbour = info->open_heap->data[neighbour_idx]; } info->g_score[P(neighbour)] = temp_g_score; info->h_score[P(neighbour)] = manhattan(x, y, x2, y2); neighbour->cost = info->g_score[P(neighbour)] + info->h_score[P(neighbour)]; neighbour->parent = node; /* We've just changed the cost for this node, so update the binheap */ if (! added) bin_heap_bubble_up(info->open_heap, neighbour_idx); else { bin_heap_add(info->open_heap, neighbour); info->node_type[P(neighbour)] = TYPE_OPEN; } } } } pathfinder_free_nodes(info); return NULL; }
double heuristic(Util::Point s, Util::Point g){ if(EUCLIDEAN) return euclidean(s, g); else return manhattan(s, g); }
int linearConflict(Node n1,Node n2){ int conflict = manhattan(n1,n2); int count1 =0; vector<int> state = n1.data._state; for(int i =0;i<3;i++){ if(state[i] ==1 || state[i] ==2 || state[i] ==3 ){ count1++; } } if(count1 >=2){ // common pairs for(int i =0;i<3;i++){ for(int j=i+1;j<3;j++){ if((state[i] ==1 || state[i] ==2 || state[i] ==3)) if((state[j] ==1 || state[j] ==2 || state[j] ==3)) if(state[i] > state[j]){ conflict +=2; } } } } count1 =0; for(int i =3;i<6;i++){ if(state[i] ==4 || state[i] ==5 || state[i] ==6 ){ count1++; } } if(count1 >=2){ // common pairs for(int i =3;i<6;i++){ for(int j=i+1;j<6;j++){ if((state[i] ==4 || state[i] ==5 || state[i] ==6)) if((state[j] ==4 || state[j] ==5 || state[j] ==6)) if(state[i] > state[j]){ conflict +=2; } } } } count1 =0; for(int i =6;i<9;i++){ if(state[i] ==7 || state[i] ==8){ count1++; } } if(count1 >=2){ // common pairs for(int i =6;i<9;i++){ for(int j=i+1;j<9;j++){ if(state[i] ==7 || state[i] ==8) if((state[j] ==7 || state[j] ==8)) if(state[i] > state[j]){ conflict +=2; } } } } return conflict; }
int heuristic(char state[3][3]) { return manhattan(state); }