← Back to team overview

widelands-dev team mailing list archive

Re: [Merge] lp:~widelands-dev/widelands/ai_blocked_fields_tweaks into lp:widelands

 

Review: Approve

Looks good to me - just some minor nits. Please feel free to merge once you have addressed those to your liking. Don't forget to set the commit message above ;)

Diff comments:

> === modified file 'src/ai/ai_help_structs.cc'
> --- src/ai/ai_help_structs.cc	2018-02-16 20:42:21 +0000
> +++ src/ai/ai_help_structs.cc	2018-03-16 07:47:06 +0000
> @@ -83,6 +83,55 @@
>  	return true;
>  }
>  
> +
> +// CheckStepOwnTerritory
> +CheckStepOwnTerritory::CheckStepOwnTerritory(Player* const pl, uint8_t const mc, bool const oe)
> +   : player(pl), movecaps(mc), open_end(oe) {
> +}
> +
> +// Defines when movement is allowed:
> +// 1. startfield is walkable (or it is the first step)
> +// And endfield either:
> +// 2a. is walkable
> +// 2b. has our PlayerImmovable (building or flag)
> +bool CheckStepOwnTerritory::allowed(
> +   const Map& map, FCoords start, FCoords end, int32_t, CheckStep::StepId const id) const {
> +	uint8_t endcaps = player->get_buildcaps(end);
> +	uint8_t startcaps = player->get_buildcaps(start);

Make these const - this will help the compiler to optimize.

> +
> +	// We should not cross fields with road or flags (or any other immovable)
> +	// Or rather we can step on it, but not go on from such field
> +	if ((map.get_immovable(start)) && !(id == CheckStep::stepFirst)) {
> +		return false;
> +	}
> +
> +	// Start field must be walkable
> +	if (!(startcaps & movecaps))

Please add the {}. Leaving them out can cause bugs that are hard to find.

> +		return false;
> +
> +	// Endfield can not be water
> +	if (endcaps & MOVECAPS_SWIM)

Please add the {}. Leaving them out can cause bugs that are hard to find.

> +		return false;
> +
> +	return true;
> +}
> +
> +// We accept either walkable teritory or field with own immovable

territory

> +bool CheckStepOwnTerritory::reachable_dest(const Map& map, const FCoords& dest) const {
> +	uint8_t endcaps = player->get_buildcaps(dest);

const

> +	if (BaseImmovable const* const imm = map.get_immovable(dest)) {
> +		if (upcast(PlayerImmovable const, player_immovable, imm)) {

use imm->descr().type() instead - much more efficient than doing a dynamic cast.

> +			return true;
> +		} else {
> +			return false;
> +		}
> +	}
> +	if (endcaps & MOVECAPS_WALK) {
> +		return true;
> +	}
> +	return false;
> +}
> +
>  // We are looking for fields we can walk on
>  // and owned by hostile player.
>  FindNodeEnemy::FindNodeEnemy(Player* p, Game& g) : player(p), game(g) {
> 
> === modified file 'src/ai/defaultai.cc'
> --- src/ai/defaultai.cc	2018-03-02 07:50:34 +0000
> +++ src/ai/defaultai.cc	2018-03-16 07:47:06 +0000
> @@ -3819,19 +3825,41 @@
>  		game().send_player_build_road(player_number(), path);
>  		return true;
>  	}
> -	// if all possible roads skipped
> -	if (last_attempt_) {
> -		Building* bld = flag.get_building();
> -		// first we block the field and vicinity for 15 minutes, probably it is not a good place to
> -		// build on
> -		MapRegion<Area<FCoords>> mr(map, Area<FCoords>(map.get_fcoords(bld->get_position()), 2));
> -		do {
> -			blocked_fields.add(mr.location(), game().get_gametime() + 15 * 60 * 1000);
> -		} while (mr.advance(map));
> -		remove_from_dqueue<Widelands::Flag>(eco->flags, &flag);
> -		game().send_player_bulldoze(*const_cast<Flag*>(&flag));
> -		dead_ends_check_ = true;
> -		return true;
> +	// We cant build a road so let block the vicinity as an indication this area is not connectible

can't, let's

> +	// Usually we block for 2 minutes, but if it is a last attempt we block for 10 minutes
> +	// Note: we block the vicinity only if this economy (usually a sole flag with a building) is not
> +	// connected to a warehouse
> +	if (flag.get_economy()->warehouses().empty()) {
> +
> +		// blocking only if latest block was less then 60 seconds ago or it is last attempt
> +		if (eco->fields_block_last_time + 60000 < gametime || last_attempt_) {
> +			eco->fields_block_last_time = gametime;
> +
> +			uint32_t block_time = 2 * 60 * 1000;

Suggestion:

const uint32_t block_time = last_attempt_ ? 10 * 60 * 1000 : 2 * 60 * 1000;

> +			if (last_attempt_) {
> +				block_time = 10 * 60 * 1000;
> +			}
> +
> +			FindNodeAcceptAll buildable_functor;
> +			CheckStepOwnTerritory check_own(player_, MOVECAPS_WALK, true);
> +
> +			// get all flags within radius
> +			std::vector<Coords> reachable_to_block;
> +			map.find_reachable_fields(Area<FCoords>(map.get_fcoords(flag.get_position()), checkradius),
> +			                          &reachable_to_block, check_own, buildable_functor);
> +
> +			for (auto coords : reachable_to_block) {
> +				blocked_fields.add(coords, game().get_gametime() + block_time);
> +			}
> +		}
> +
> +		// If it last attempt we also destroy the flag (with a building if any attached)
> +		if (last_attempt_) {
> +			remove_from_dqueue<Widelands::Flag>(eco->flags, &flag);
> +			game().send_player_bulldoze(*const_cast<Flag*>(&flag));
> +			dead_ends_check_ = true;
> +			return true;
> +		}
>  	}
>  	return false;
>  }


-- 
https://code.launchpad.net/~widelands-dev/widelands/ai_blocked_fields_tweaks/+merge/341483
Your team Widelands Developers is subscribed to branch lp:~widelands-dev/widelands/ai_blocked_fields_tweaks.


References