void RoboMiner::move(int cy, int cx) { Ground *gr = frame->getGround(); int maxCell_x = gr->getCols(); int maxCell_y = gr->getRows(); if(cx<0 || cx>=maxCell_x) return; if(cy<0 || cy>=maxCell_y) return; /* std::cout << "Moving from (" << cell_y << "," << cell_x << ")" << " Cell(" << cell->getY() << "," << cell->getX() << ")" << " to (" << cy << "," << cx << ") with max_y: " << maxCell_y << " max_x: " << maxCell_x << std::endl; */ Cell *destcell = &(gr->getCell(cy, cx)); if(!destcell->isDrilled()) drill(cy, cx); if(destcell->isDrilled()){ cell->clearMiner(); cell = destcell; cell->hasMiner(this); cell_y = cy; cell_x = cx; energy -= 1; } }
void RoboMiner::scan() { int radius = 6; int up_radius = radius, down_radius = radius; int left_radius = radius, right_radius = radius; int xdist, ydist; Ground *g = frame->getGround(); if(cell_x + right_radius >= g->getCols()) right_radius = g->getCols()-1-cell_x; if(cell_x - left_radius < 0) left_radius = cell_x; if(cell_y + down_radius >= g->getRows()) down_radius = g->getRows()-1-cell_y; if(cell_y - up_radius < 0) up_radius = cell_y; std::vector<Cell *> scope; // std::cout << "scan from (" << cell_y << "," << cell_x // << ")" << std::endl; for(xdist=-left_radius; xdist<=right_radius; ++xdist){ for(ydist=-up_radius; ydist<=down_radius; ++ydist){ if((abs(ydist)+abs(xdist))>radius) continue; if(ydist==0 && xdist==0) continue; Cell& scan_cell = g->getCell(cell_y+ydist, cell_x+xdist); scope.push_back(&scan_cell); } } /* std::cout << "\ty_r: " << y_radius << " x_r: " << x_radius << " tc: " << scope.size() << std::endl; for(auto& c: scope){ c->setVisible(true); if(c->mineralCount()){ mineralCells.push_back(c); } } */ std::vector<const Cell *> mineralCells; std::copy_if(scope.cbegin(), scope.cend(), std::back_inserter(mineralCells), \ [](Cell *c){ c->setVisible(true); return c->mineralCount(); }); if(mineralCells.empty() && !destCell){ int roll = rand() % 4; int x_off=0, y_off=0; switch(roll){ case 0: y_off = -up_radius; break; case 1: x_off = right_radius; break; case 2: y_off = down_radius; break; case 3: x_off = -left_radius; break; } // std::cout << "Exploring to: (" << cell_y+y_off // << "," << cell_x+x_off << ")" << std::endl; setDestination(cell_y + y_off, cell_x + x_off); exploring = true; }else if(!mineralCells.empty() && !destCell){ exploring = false; int roll = rand() % mineralCells.size(); const Cell *const hasMinerals = mineralCells[roll]; setDestination(hasMinerals->getY(), hasMinerals->getX()); } }
void RoboMiner::navigate() { int dest_y = destCell->getY(); int dest_x = destCell->getX(); int y_off = cell_y - dest_y; int x_off = cell_x - dest_x; int move_x = 0, move_y = 0; Ground *g = frame->getGround(); Cell& up = g->getCell((cell_y-1 >= 0 ? cell_y-1 : 0), cell_x); Cell& down = g->getCell((cell_y+1 < g->getRows() ? cell_y+1 : g->getRows()-1), cell_x); Cell& right = g->getCell(cell_y, (cell_x+1 < g->getCols() ? cell_x+1 : g->getCols()-1)); Cell& left = g->getCell(cell_y, (cell_x-1 >= 0 ? cell_x-1 : 0)); if(y_off > 0){ if(x_off > 0){ if(left.isDrilled()){ move_x = -1; goto done; } }else if(x_off < 0){ if(right.isDrilled()){ move_x = 1; goto done; } } move_y = -1; }else if(y_off < 0){ if(x_off > 0){ if(left.isDrilled()){ move_x = -1; goto done; } }else if(x_off < 0){ if(right.isDrilled()){ move_x = 1; goto done; } } move_y = 1; }else if(x_off > 0){ if(y_off > 0){ if(up.isDrilled()){ move_y = -1; goto done; } }else if(y_off < 0){ if(down.isDrilled()){ move_y = 1; goto done; } } move_x = -1; }else if(x_off < 0){ if(y_off > 0){ if(up.isDrilled()){ move_y = -1; goto done; } }else if(y_off < 0){ if(down.isDrilled()){ move_y = 1; goto done; } } move_x = 1; } done: move(cell_y + move_y, cell_x + move_x); if(dest_y == cell_y && dest_x == cell_x){ destCell = nullptr; if(atBase()){ ascending = true; } if(lastMinedOre){ setDestination(lastMinedOre->getY(), lastMinedOre->getX()); lastMinedOre = nullptr; } } }