Exemple #1
0
map_location pathfind::find_vacant_tile(const gamemap& map,
				const unit_map& units,
				const map_location& loc,
				pathfind::VACANT_TILE_TYPE vacancy,
				const unit* pass_check)
{
	if (!map.on_board(loc)) return map_location();
	std::set<map_location> pending_tiles_to_check, tiles_checked;
	pending_tiles_to_check.insert(loc);
	// Iterate out 50 hexes from loc
	for (int distance = 0; distance < 50; ++distance) {
		if (pending_tiles_to_check.empty())
			return map_location();
		//Copy over the hexes to check and clear the old set
		std::set<map_location> tiles_checking;
		tiles_checking.swap(pending_tiles_to_check);
		//Iterate over all the hexes we need to check
		foreach (const map_location &loc, tiles_checking)
		{
			//If this area is not a castle but should, skip it.
			if (vacancy == pathfind::VACANT_CASTLE && !map.is_castle(loc)) continue;
			const bool pass_check_and_unreachable = pass_check
				&& pass_check->movement_cost(map[loc]) == unit_movement_type::UNREACHABLE;
			//If the unit can't reach the tile and we have searched
			//an area of at least radius 10 (arbitrary), skip the tile.
			//Neccessary for cases such as an unreachable
			//starting hex surrounded by 6 other unreachable hexes, in which case
			//the algorithm would not even search distance==1
			//even if there's a reachable hex for distance==2.
			if (pass_check_and_unreachable && distance > 10) continue;
			//If the hex is empty and we do either no pass check or the hex is reachable, return it.
			if (units.find(loc) == units.end() && !pass_check_and_unreachable) return loc;
			map_location adjs[6];
			get_adjacent_tiles(loc,adjs);
			foreach (const map_location &loc, adjs)
			{
				if (!map.on_board(loc)) continue;
				// Add the tile to be checked if it hasn't already been and
				// isn't being checked.
				if (tiles_checked.find(loc) == tiles_checked.end() &&
				    tiles_checking.find(loc) == tiles_checking.end())
				{
					pending_tiles_to_check.insert(loc);
				}
			}
		}
		tiles_checked.swap(tiles_checking);
	}
	return map_location();
}
Exemple #2
0
map_location find_vacant_tile(const gamemap& map,
				const unit_map& units,
				const map_location& loc,
				VACANT_TILE_TYPE vacancy,
				const unit* pass_check)
{
	std::set<map_location> pending_tiles_to_check;
	std::set<map_location> tiles_checked;
	pending_tiles_to_check.insert( loc );
	// Iterate out 50 hexes from loc
	for (int distance = 0; distance < 50; ++distance) {
		if (pending_tiles_to_check.empty())
			return map_location();
		//Copy over the hexes to check and clear the old set
		std::set<map_location> tiles_checking = pending_tiles_to_check;
		std::set<map_location>::const_iterator tc_itor = tiles_checking.begin();
		pending_tiles_to_check.clear();
		//Iterate over all the hexes we need to check
		for ( ; tc_itor != tiles_checking.end(); ++tc_itor )
		{
			//If the unit cannot reach this area or it's not a castle but should, skip it.
			if ((vacancy == VACANT_CASTLE && !map.is_castle(*tc_itor))
			|| (pass_check && pass_check->movement_cost(map[*tc_itor])
					== unit_movement_type::UNREACHABLE))
				continue;
			//If the hex is empty, return it.
			if (map.on_board(*tc_itor) && units.find(*tc_itor) == units.end())
				return (*tc_itor);
			map_location adjs[6];
			get_adjacent_tiles(*tc_itor,adjs);
			for (int i = 0; i != 6; ++i)
			{
				//Add the tile to be checked if it hasn't already been and isn't already
				//pending to be checked
				if (pending_tiles_to_check.find(adjs[i]) == pending_tiles_to_check.end() &&
					tiles_checked.find(adjs[i]) == tiles_checked.end() &&
					tiles_checking.find(adjs[i]) == tiles_checking.end())
				{
					pending_tiles_to_check.insert(adjs[i]);
				}
			}
		}
		tiles_checked = tiles_checking;
	}
	return map_location();
}
map_location pathfind::find_vacant_tile(const gamemap& map,
				const unit_map& units,
				const map_location& loc,
				pathfind::VACANT_TILE_TYPE vacancy,
				const unit* pass_check)
{
	if (!map.on_board(loc)) return map_location();
	std::set<map_location> pending_tiles_to_check, tiles_checked;
	pending_tiles_to_check.insert(loc);
	// Iterate out 50 hexes from loc
	for (int distance = 0; distance < 50; ++distance) {
		if (pending_tiles_to_check.empty())
			return map_location();
		//Copy over the hexes to check and clear the old set
		std::set<map_location> tiles_checking;
		tiles_checking.swap(pending_tiles_to_check);
		//Iterate over all the hexes we need to check
		foreach (const map_location &loc, tiles_checking)
		{
			//If the unit cannot reach this area or it's not a castle but should, skip it.
			if ((vacancy == pathfind::VACANT_CASTLE && !map.is_castle(loc))
			|| (pass_check && pass_check->movement_cost(map[loc])
					== unit_movement_type::UNREACHABLE))
				continue;
			//If the hex is empty, return it.
			if (units.find(loc) == units.end())
				return loc;
			map_location adjs[6];
			get_adjacent_tiles(loc,adjs);
			foreach (const map_location &loc, adjs)
			{
				if (!map.on_board(loc)) continue;
				// Add the tile to be checked if it hasn't already been and
				// isn't being checked.
				if (tiles_checked.find(loc) == tiles_checked.end() &&
				    tiles_checking.find(loc) == tiles_checking.end())
				{
					pending_tiles_to_check.insert(loc);
				}
			}
		}
		tiles_checked.swap(tiles_checking);
	}
	return map_location();
}