Changeset - r16442:65c76775ce4b
[Not reviewed]
master
0 2 0
alberth - 14 years ago 2010-11-13 15:07:34
alberth@openttd.org
(svn r21168) -Feature: Use desired industry counts rather than relative probability to decide which industry to build.
2 files changed with 45 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/industry.h
Show inline comments
 
@@ -146,6 +146,7 @@ void ReleaseDisastersTargetingIndustry(I
 
/** Data for managing the number of industries of a single industry type. */
 
struct IndustryTypeBuildData {
 
	uint32 probability;  ///< Relative probability of building this industry.
 
	uint16 target_count; ///< Desired number of industries of this type.
 

	
 
	void GetIndustryTypeData(IndustryType it);
 
};
 
@@ -156,6 +157,7 @@ struct IndustryTypeBuildData {
 
struct IndustryBuildData {
 
	IndustryTypeBuildData builddata[NUM_INDUSTRYTYPES]; ///< Industry build data for every industry type.
 

	
 
	void SetupTargetCount();
 
	void TryBuildNewIndustry();
 
};
 

	
src/industry_cmd.cpp
Show inline comments
 
@@ -2055,26 +2055,56 @@ void IndustryTypeBuildData::GetIndustryT
 
	this->probability = GetIndustryGamePlayProbability(it);
 
}
 

	
 
/** Decide how many industries of each type are needed. */
 
void IndustryBuildData::SetupTargetCount()
 
{
 
	for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
 
		this->builddata[it].GetIndustryTypeData(it);
 
	}
 

	
 
	uint total_amount = GetNumberOfIndustries(); // Desired number of industries.
 
	uint32 total_prob = 0; // Sum of probabilities.
 
	for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
 
		this->builddata[it].target_count = 0;
 
		total_prob += this->builddata[it].probability;
 
	}
 

	
 
	/* Assign number of industries that should be aimed for, by using the probability as a weight. */
 
	while (total_amount > 0) {
 
		uint32 r = RandomRange(total_prob);
 
		IndustryType it = 0;
 
		while (r >= this->builddata[it].probability) {
 
			r -= this->builddata[it].probability;
 
			it++;
 
			assert(it < NUM_INDUSTRYTYPES);
 
		}
 
		assert(this->builddata[it].probability > 0);
 
		this->builddata[it].target_count++;
 
		total_amount--;
 
	}
 
}
 

	
 
/**
 
 * Try to create a random industry, during gameplay
 
 */
 
void IndustryBuildData::TryBuildNewIndustry()
 
{
 
	/* Generate a list of all possible industries that can be built. */
 
	for (IndustryType j = 0; j < NUM_INDUSTRYTYPES; j++) {
 
		this->builddata[j].GetIndustryTypeData(j);
 
	}
 

	
 
	this->SetupTargetCount();
 

	
 
	int missing = 0;       // Number of industries that need to be build.
 
	uint count = 0;        // Number of industry types eligible for build.
 
	uint32 total_prob = 0; // Sum of probabilities.
 
	for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
 
		uint32 chance = this->builddata[it].probability;
 
		if (chance > 0) {
 
			total_prob += chance;
 
		int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
 
		missing += difference;
 
		if (difference > 0) {
 
			total_prob += difference;
 
			count++;
 
		}
 
	}
 

	
 
	if (missing <= 0 || total_prob == 0) count = 0; // Skip creation of an industry.
 

	
 
	if (count >= 1) {
 
		/* Pick a weighted random industry to build.
 
		 * For the case that count == 1, there is no need to draw a random number. */
 
@@ -2083,13 +2113,13 @@ void IndustryBuildData::TryBuildNewIndus
 
		uint32 r = 0; // Initialized to silence the compiler.
 
		if (count > 1) r = RandomRange(total_prob);
 
		for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
 
			uint32 chance = this->builddata[it].probability;
 
			if (chance == 0) continue;
 
			int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
 
			if (difference <= 0) continue; // Too many of this kind.
 
			if (count == 1) break;
 
			if (r < chance) break;
 
			r -= chance;
 
			if (r < (uint)difference) break;
 
			r -= difference;
 
		}
 
		assert(it < NUM_INDUSTRYTYPES);
 
		assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
 

	
 
		/* Try to create the industry. */
 
		const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
0 comments (0 inline, 0 general)