예제 #1
0
Vector2d findBestPositionToAttack(const model::World& w, const model::Trooper& trooper, const model::Trooper& enemy){
	Vector2d res(-1,-1);
	PathFinder pf;
	int bestDist = 1 << 20;
	const std::vector<std::vector<model::CellType> >& cells = w.getCells();
	for (int i = 0; i < w.getWidth(); i++){
		for (int j = 0; j < w.getHeight(); j++){
//			if (enemy.getDistanceTo(i,j) > 8 || cells[i][j] != model::FREE || PathFinder::isTropperInCell(w,Vector2d(i,j))) //dist to check. Too much???
			if (trooper.getDistanceTo(i,j) > 5 || cells[i][j] != model::FREE || PathFinder::isTropperInCell(w,Vector2d(i,j))) //dist to check. Too much???
				continue;
			
			if (!w.isVisible(trooper.getShootingRange(), i, j, model::STANDING, enemy.getX(), enemy.getY(), enemy.getStance()))
				continue;

			std::list<Vector2d> path = pf.calcOptimalPath(w, Vector2d(trooper.getX(), trooper.getY()), Vector2d(i, j));
			
			if(path.empty())
				continue;

			std::list<Vector2d> pathWithoutPlayers = pf.calcOptimalPath(w, Vector2d(trooper.getX(), trooper.getY()), Vector2d(i, j), true);

			if (pathWithoutPlayers.size() + 3 < path.size())
				continue;

			int dist = path.size();
			if (dist < bestDist){
				bestDist = dist;
				res = Vector2d(i,j);
			}
		}
	}

	return res;
}
예제 #2
0
vector<Cell> GetClosestPath(const model::World& world,
                            Cell const & start, Direction const start_dir, Cell const & finish, Game const & game)
{
    
    static map<cashe_key, vector<Cell> > cacshe;
    static int bonus_hash = 0;
    int bonus_hash_cur = 0;
    auto const & map = world.getTilesXY();
    vector<vector<int>> bonuses(map.size(), vector<int>(map[0].size(), 0));
    for (Bonus const & bonus: world.getBonuses())
    {
        bonus_hash_cur += bonus.getX() * bonus.getX() + bonus.getY() * bonus.getY();
        auto bonus_cell= GetCell(bonus, game);
        bonuses[bonus_cell.m_x][bonus_cell.m_y] = (bonus.getType() == PURE_SCORE || bonus.getType() == REPAIR_KIT) ? 1 : 0;
    }
    if (bonus_hash !=  bonus_hash_cur)
    {
        bonus_hash = bonus_hash_cur;
        cacshe.clear();
    }
    
    
    
    cashe_key ck = {start, start_dir, finish};
    if (cacshe.count(ck) == 1)
        return cacshe[ck];
    
    MapT data;
    DSF(world.getTilesXY(), {start, start_dir}, {start, start_dir}, finish, data, bonuses);
    //    PrintMap(world.getTilesXY(), data);
    
    vector<Cell> res;
    int const INF = 1000000;
    int best = INF;
    MapKeyT cur = {finish, LEFT};
    for (auto dir: AllDirections())
    {
        if (data.count({finish,dir}) == 0)
            continue;
        if (data[{finish,dir}].first < best)
        {
            best = data[{finish,dir}].first;
            cur = {finish,dir};
        }
        
    }
    if (best == INF)
        return res;
    
    
    while (cur.first != start)
    {
        res.push_back(cur.first);
        cur = data[cur].second;
    }
    res.push_back(start);
    reverse(res.begin(), res.end());
    cacshe[ck] = res;
    return res;
}
 void EntityLinkRenderer::getAllLinks(Vertex::List& links) const {
     View::MapDocumentSPtr document = lock(m_document);
     const Model::EditorContext& editorContext = document->editorContext();
     
     CollectAllLinksVisitor collectLinks(editorContext, m_defaultColor, m_selectedColor, links);
     
     Model::World* world = document->world();
     if (world != NULL)
         world->acceptAndRecurse(collectLinks);
 }
예제 #4
0
Vector2d processApproximate(const model::World& w, const Vector2d& appr){
	Vector2d res;
	const std::vector<std::vector<model::CellType> >& cells = w.getCells();
	float min = 1 << 20;
	for (int i = 0; i < w.getWidth(); i++)
	for (int j = 0; j < w.getHeight(); j++){
		float d = dist(appr, Vector2d(i, j));
		if (cells[i][j] == model::FREE && min > d){
			min = d;
			res = Vector2d (i, j);
		}
	}
	return res;
}
예제 #5
0
Map::Map(const model::Game& game, const model::World& world)
	: m_tiles(world.getTilesXY())
	, m_game(&game)
	, m_world(&world)

	, m_tileSize((int)m_game->getTrackTileSize())
	, m_tileCenter((int)m_game->getTrackTileSize() / 2, (int)m_game->getTrackTileSize() / 2)
	, m_worldWidthTiles(world.getWidth())
	, m_worldHeightTiles(world.getHeight())
{

	m_tileNodes.resize(m_worldWidthTiles * m_worldHeightTiles);
	updateNodes();
}
예제 #6
0
std::vector<Vector2d> getDstsWithDir(const model::World& w, const Vector2d susanin_v, const Vector2d dir){
	std::vector<Vector2d> res;
	const std::vector<std::vector<model::CellType> >& cells = w.getCells();
	for (int i = 0; i < w.getWidth(); i++)
	for (int j = 0; j < w.getHeight(); j++){
		float d = dist(susanin_v, Vector2d(i, j));

		if (d > kMinDist && d < kMaxDist &&
			cells[i][j] == model::FREE &&
			!PathFinder::isTropperInCell(w, Vector2d(i, j)) &&
			isFeetDirection(susanin_v, i, j, dir))
			res.push_back(Vector2d(i, j));
	}
	return res;
}
예제 #7
0
bool isTypeAlive(const model::World& w, model::TrooperType type){
	bool res = false;
	const std::vector<model::Trooper> t = w.getTroopers();
	std::vector<model::Trooper>::const_iterator it = t.begin();

	for (; it != t.end(); ++it){
		if (!(it->isTeammate()))
			continue;

		if (it->getType() == type && it->getHitpoints() > 0){
			res = true;
			break;
		}
	}
	return res;
}
예제 #8
0
Action DriveStrategy::makeDecision(ITank &tank, model::World world)
{
    Action action;
    action.setLeft(0);
    action.setRight(0);

    std::vector<model::Bonus> bonuses = world.bonuses();
    if (bonuses.empty())
        return action;
    model::Bonus best = bonuses[0];
    for (int i = 1; i < (int)bonuses.size(); i++)
    {
        model::Bonus cur = bonuses[i];
        if (tank.distanceTo(cur) < tank.distanceTo(best))
            best = cur;
    }
    //std::cerr << "Move to " << best.x() << " " << best.y() << std::endl;
    moveTo(tank, best.x(), best.y(), action);
    return action;
}
예제 #9
0
std::list<ActionChain*> ActionFactory::createChains(const model::World& w, const model::Trooper& trooper, std::list<Tactician::Tactic> tactics, bool isFirstMove){

	std::list<ActionChain*> res_chains;
	ActionChain* new_chain = NULL;
	const std::vector<model::Trooper>& troopers = w.getTroopers();


	ActionChain* heal_chain = ActionFactory::heal(w, trooper, tactics, isFirstMove);
	
	if (heal_chain){
		ActionChunk first = *((heal_chain->chain).begin());
		model::ActionType firstType = first.action_type;

		if (isActionAvailable(trooper, firstType))
			res_chains.push_back(heal_chain);
		else
			delete heal_chain;
	}
	
	ActionChain* atack_chain = ActionFactory::atack(w, trooper, tactics, isFirstMove);

	if (atack_chain){//TODO: avoid copy-paste
		ActionChunk first = *((atack_chain->chain).begin());
		model::ActionType firstType = first.action_type;

		if (isActionAvailable(trooper, firstType))
			res_chains.push_back(atack_chain);
		else
			delete atack_chain;
	}
	
	if (gMainDst == Vector2d(-1, -1)){
		if (model::COMMANDER == trooper.getType()){

			const std::vector<model::Player>players = w.getPlayers();
			if (players[0].getApproximateX() != -1 || players[1].getApproximateX() != -1 ||
				players[2].getApproximateX() != -1 || players[3].getApproximateX() != -1){
				//already we have this info
				std::vector<model::Player>::const_iterator it = players.begin();
				float min = 1 << 20;
				Vector2d approximate(-1, -1);
				for (; it != players.end(); ++it){
					if (it->getName() == "m16a" || it->getName() == "MyStrategy"|| it->getApproximateX() == -1)
						continue;
					Vector2d tmp(it->getApproximateX(), it->getApproximateY());
					float d = dist(tmp, Vector2d(trooper.getX(), trooper.getY()));
					if (min > d){
						min = d;
						approximate = tmp;
					}
				}
				gMainDst = processApproximate(w, approximate);
			}
			else if (isActionAvailable(trooper, model::REQUEST_ENEMY_DISPOSITION)){
				std::list<ActionChunk> c;
				ActionChunk chunk(model::REQUEST_ENEMY_DISPOSITION, Vector2d(-1, -1));
				c.push_back(chunk);
				ActionChain *new_chain = new ActionChain();
				new_chain->executor = &trooper;
				new_chain->chain = c;
				res_chains.push_back(new_chain);
				
			}
		}
	}

	if (tactics.end() != std::find(tactics.begin(), tactics.end(), Tactician::MOVE) && 
		isActionAvailable(trooper, model::MOVE))
	{
		do{

			if (trooper.getStance() != model::STANDING){
				std::list<ActionChunk> c;
				ActionChunk chunk(model::RAISE_STANCE, Vector2d(-1, -1));
				c.push_back(chunk);
				new_chain = new ActionChain();
				new_chain->executor = &trooper;
				new_chain->chain = c;
				if (isActionAvailable(trooper, model::RAISE_STANCE))
					res_chains.push_back(new_chain);
				break;
			}

			model::TrooperType Susanin_type = model::UNKNOWN_TROOPER;
			if (gMove_head.empty()){
				gMove_head.push_back(model::SOLDIER);
				gMove_head.push_back(model::COMMANDER);
				gMove_head.push_back(model::FIELD_MEDIC);
			}
			const model::Trooper *susanin = NULL;
			
			while(susanin == NULL){
				std::list<model::TrooperType>::iterator type_it = gMove_head.begin();
				for (; type_it != gMove_head.end() && susanin == NULL; ++type_it){
					std::vector<model::Trooper>::const_iterator tr_it = troopers.begin();
					for (; tr_it != troopers.end(); ++tr_it){
						if (tr_it->isTeammate() && tr_it->getType() == *type_it){
							susanin = &(*tr_it);
							break;
						}
					}
				}

				if (susanin == NULL){
					gMove_head.push_back(*(gMove_head.begin()));
					gMove_head.erase(gMove_head.begin());
				}

			}

			Vector2d dst = Vector2d(susanin->getX(), susanin->getY());
			Vector2d src(trooper.getX(), trooper.getY());
			if (isFirstMove){
				if (trooper.getDistanceTo(*susanin) == 0)
						gMediatorDst = findDest(w, dst);
				else
					gMediatorDst = findNearestFree(w, src, dst);
			}
			dst = gMediatorDst;

			PathFinder pf;
			std::list<Vector2d> path = pf.calcOptimalPath(w, src, dst);
			if (!path.empty()){
				path.pop_front();

				std::list<Vector2d>::iterator it = path.begin();

				std::list<ActionChunk> c;

				for (; it != path.end(); ++it){
					if (!PathFinder::isTropperInCell(w, *it)){//TODO: eliminate
						ActionChunk chunk(model::MOVE, *it);
						c.push_back(chunk);
					}
				}
				new_chain = new ActionChain();
				new_chain->executor = &trooper;
				new_chain->chain = c;
				if (isActionAvailable(trooper, model::MOVE))
					res_chains.push_back(new_chain);
			}
			else if (susanin->getDistanceTo(trooper) == 0){//try to change susanin
				gMove_head.push_back(*(gMove_head.begin()));
				gMove_head.erase(gMove_head.begin());
			}
		}while(0);
	}


	return res_chains;

}