⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 be_ai_weight.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
	{
		if (fprintf(fp, " return ") < 0) return qfalse;
		if (!WriteFloat(fp, fs->weight)) return qfalse;
		if (fprintf(fp, ";\n") < 0) return qfalse;
	} //end else
	return qtrue;
} //end of the function WriteFuzzyWeight
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean WriteFuzzySeperators_r(FILE *fp, fuzzyseperator_t *fs, int indent)
{
	if (!WriteIndent(fp, indent)) return qfalse;
	if (fprintf(fp, "switch(%d)\n", fs->index) < 0) return qfalse;
	if (!WriteIndent(fp, indent)) return qfalse;
	if (fprintf(fp, "{\n") < 0) return qfalse;
	indent++;
	do
	{
		if (!WriteIndent(fp, indent)) return qfalse;
		if (fs->next)
		{
			if (fprintf(fp, "case %d:", fs->value) < 0) return qfalse;
		} //end if
		else
		{
			if (fprintf(fp, "default:") < 0) return qfalse;
		} //end else
		if (fs->child)
		{
			if (fprintf(fp, "\n") < 0) return qfalse;
			if (!WriteIndent(fp, indent)) return qfalse;
			if (fprintf(fp, "{\n") < 0) return qfalse;
			if (!WriteFuzzySeperators_r(fp, fs->child, indent + 1)) return qfalse;
			if (!WriteIndent(fp, indent)) return qfalse;
			if (fs->next)
			{
				if (fprintf(fp, "} //end case\n") < 0) return qfalse;
			} //end if
			else
			{
				if (fprintf(fp, "} //end default\n") < 0) return qfalse;
			} //end else
		} //end if
		else
		{
			if (!WriteFuzzyWeight(fp, fs)) return qfalse;
		} //end else
		fs = fs->next;
	} while(fs);
	indent--;
	if (!WriteIndent(fp, indent)) return qfalse;
	if (fprintf(fp, "} //end switch\n") < 0) return qfalse;
	return qtrue;
} //end of the function WriteItemFuzzyWeights_r
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean WriteWeightConfig(char *filename, weightconfig_t *config)
{
	int i;
	FILE *fp;
	weight_t *ifw;

	fp = fopen(filename, "wb");
	if (!fp) return qfalse;

	for (i = 0; i < config->numweights; i++)
	{
		ifw = &config->weights[i];
		if (fprintf(fp, "\nweight \"%s\"\n", ifw->name) < 0) return qfalse;
		if (fprintf(fp, "{\n") < 0) return qfalse;
		if (ifw->firstseperator->index > 0)
		{
			if (!WriteFuzzySeperators_r(fp, ifw->firstseperator, 1)) return qfalse;
		} //end if
		else
		{
			if (!WriteIndent(fp, 1)) return qfalse;
			if (!WriteFuzzyWeight(fp, ifw->firstseperator)) return qfalse;
		} //end else
		if (fprintf(fp, "} //end weight\n") < 0) return qfalse;
	} //end for
	fclose(fp);
	return qtrue;
} //end of the function WriteWeightConfig
#endif
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int FindFuzzyWeight(weightconfig_t *wc, char *name)
{
	int i;

	for (i = 0; i < wc->numweights; i++)
	{
		if (!strcmp(wc->weights[i].name, name))
		{
			return i;
		} //end if
	} //end if
	return -1;
} //end of the function FindFuzzyWeight
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
float FuzzyWeight_r(int *inventory, fuzzyseperator_t *fs)
{
	float scale, w1, w2;

	if (inventory[fs->index] < fs->value)
	{
		if (fs->child) return FuzzyWeight_r(inventory, fs->child);
		else return fs->weight;
	} //end if
	else if (fs->next)
	{
		if (inventory[fs->index] < fs->next->value)
		{
			//first weight
			if (fs->child) w1 = FuzzyWeight_r(inventory, fs->child);
			else w1 = fs->weight;
			//second weight
			if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
			else w2 = fs->next->weight;
			//the scale factor
			scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
			//scale between the two weights
			return scale * w1 + (1 - scale) * w2;
		} //end if
		return FuzzyWeight_r(inventory, fs->next);
	} //end else if
	return fs->weight;
} //end of the function FuzzyWeight_r
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
float FuzzyWeightUndecided_r(int *inventory, fuzzyseperator_t *fs)
{
	float scale, w1, w2;

	if (inventory[fs->index] < fs->value)
	{
		if (fs->child) return FuzzyWeightUndecided_r(inventory, fs->child);
		else return fs->minweight + random() * (fs->maxweight - fs->minweight);
	} //end if
	else if (fs->next)
	{
		if (inventory[fs->index] < fs->next->value)
		{
			//first weight
			if (fs->child) w1 = FuzzyWeightUndecided_r(inventory, fs->child);
			else w1 = fs->minweight + random() * (fs->maxweight - fs->minweight);
			//second weight
			if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
			else w2 = fs->next->minweight + random() * (fs->next->maxweight - fs->next->minweight);
			//the scale factor
			scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
			//scale between the two weights
			return scale * w1 + (1 - scale) * w2;
		} //end if
		return FuzzyWeightUndecided_r(inventory, fs->next);
	} //end else if
	return fs->weight;
} //end of the function FuzzyWeightUndecided_r
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
float FuzzyWeight(int *inventory, weightconfig_t *wc, int weightnum)
{
#ifdef EVALUATERECURSIVELY
	return FuzzyWeight_r(inventory, wc->weights[weightnum].firstseperator);
#else
	fuzzyseperator_t *s;

	s = wc->weights[weightnum].firstseperator;
	if (!s) return 0;
	while(1)
	{
		if (inventory[s->index] < s->value)
		{
			if (s->child) s = s->child;
			else return s->weight;
		} //end if
		else
		{
			if (s->next) s = s->next;
			else return s->weight;
		} //end else
	} //end if
	return 0;
#endif
} //end of the function FuzzyWeight
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
float FuzzyWeightUndecided(int *inventory, weightconfig_t *wc, int weightnum)
{
#ifdef EVALUATERECURSIVELY
	return FuzzyWeightUndecided_r(inventory, wc->weights[weightnum].firstseperator);
#else
	fuzzyseperator_t *s;

	s = wc->weights[weightnum].firstseperator;
	if (!s) return 0;
	while(1)
	{
		if (inventory[s->index] < s->value)
		{
			if (s->child) s = s->child;
			else return s->minweight + random() * (s->maxweight - s->minweight);
		} //end if
		else
		{
			if (s->next) s = s->next;
			else return s->minweight + random() * (s->maxweight - s->minweight);
		} //end else
	} //end if
	return 0;
#endif
} //end of the function FuzzyWeightUndecided
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void EvolveFuzzySeperator_r(fuzzyseperator_t *fs)
{
	if (fs->child)
	{
		EvolveFuzzySeperator_r(fs->child);
	} //end if
	else if (fs->type == WT_BALANCE)
	{
		//every once in a while an evolution leap occurs, mutation
		if (random() < 0.01) fs->weight += crandom() * (fs->maxweight - fs->minweight);
		else fs->weight += crandom() * (fs->maxweight - fs->minweight) * 0.5;
		//modify bounds if necesary because of mutation
		if (fs->weight < fs->minweight) fs->minweight = fs->weight;
		else if (fs->weight > fs->maxweight) fs->maxweight = fs->weight;
	} //end else if
	if (fs->next) EvolveFuzzySeperator_r(fs->next);
} //end of the function EvolveFuzzySeperator_r
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void EvolveWeightConfig(weightconfig_t *config)
{
	int i;

	for (i = 0; i < config->numweights; i++)
	{
		EvolveFuzzySeperator_r(config->weights[i].firstseperator);
	} //end for
} //end of the function EvolveWeightConfig
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void ScaleFuzzySeperator_r(fuzzyseperator_t *fs, float scale)
{
	if (fs->child)
	{
		ScaleFuzzySeperator_r(fs->child, scale);
	} //end if
	else if (fs->type == WT_BALANCE)
	{
		//
		fs->weight = (fs->maxweight + fs->minweight) * scale;
		//get the weight between bounds
		if (fs->weight < fs->minweight) fs->weight = fs->minweight;
		else if (fs->weight > fs->maxweight) fs->weight = fs->maxweight;
	} //end else if
	if (fs->next) ScaleFuzzySeperator_r(fs->next, scale);
} //end of the function ScaleFuzzySeperator_r
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void ScaleWeight(weightconfig_t *config, char *name, float scale)
{
	int i;

	if (scale < 0) scale = 0;
	else if (scale > 1) scale = 1;
	for (i = 0; i < config->numweights; i++)
	{
		if (!strcmp(name, config->weights[i].name))
		{
			ScaleFuzzySeperator_r(config->weights[i].firstseperator, scale);
			break;
		} //end if
	} //end for
} //end of the function ScaleWeight
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void ScaleFuzzySeperatorBalanceRange_r(fuzzyseperator_t *fs, float scale)
{
	if (fs->child)
	{
		ScaleFuzzySeperatorBalanceRange_r(fs->child, scale);
	} //end if
	else if (fs->type == WT_BALANCE)
	{
		float mid = (fs->minweight + fs->maxweight) * 0.5;
		//get the weight between bounds
		fs->maxweight = mid + (fs->maxweight - mid) * scale;
		fs->minweight = mid + (fs->minweight - mid) * scale;
		if (fs->maxweight < fs->minweight)
		{
			fs->maxweight = fs->minweight;
		} //end if
	} //end else if
	if (fs->next) ScaleFuzzySeperatorBalanceRange_r(fs->next, scale);
} //end of the function ScaleFuzzySeperatorBalanceRange_r
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void ScaleFuzzyBalanceRange(weightconfig_t *config, float scale)
{
	int i;

	if (scale < 0) scale = 0;
	else if (scale > 100) scale = 100;
	for (i = 0; i < config->numweights; i++)
	{
		ScaleFuzzySeperatorBalanceRange_r(config->weights[i].firstseperator, scale);
	} //end for
} //end of the function ScaleFuzzyBalanceRange
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int InterbreedFuzzySeperator_r(fuzzyseperator_t *fs1, fuzzyseperator_t *fs2,
								fuzzyseperator_t *fsout)
{
	if (fs1->child)
	{
		if (!fs2->child || !fsout->child)
		{
			botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal child\n");
			return qfalse;
		} //end if
		if (!InterbreedFuzzySeperator_r(fs2->child, fs2->child, fsout->child))
		{
			return qfalse;
		} //end if
	} //end if
	else if (fs1->type == WT_BALANCE)
	{
		if (fs2->type != WT_BALANCE || fsout->type != WT_BALANCE)
		{
			botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal balance\n");
			return qfalse;
		} //end if
		fsout->weight = (fs1->weight + fs2->weight) / 2;
		if (fsout->weight > fsout->maxweight) fsout->maxweight = fsout->weight;
		if (fsout->weight > fsout->minweight) fsout->minweight = fsout->weight;
	} //end else if
	if (fs1->next)
	{
		if (!fs2->next || !fsout->next)
		{
			botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal next\n");
			return qfalse;
		} //end if
		if (!InterbreedFuzzySeperator_r(fs1->next, fs2->next, fsout->next))
		{
			return qfalse;
		} //end if
	} //end if
	return qtrue;
} //end of the function InterbreedFuzzySeperator_r
//===========================================================================
// config1 and config2 are interbreeded and stored in configout
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void InterbreedWeightConfigs(weightconfig_t *config1, weightconfig_t *config2,
								weightconfig_t *configout)
{
	int i;

	if (config1->numweights != config2->numweights ||
		config1->numweights != configout->numweights)
	{
		botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal numweights\n");
		return;
	} //end if
	for (i = 0; i < config1->numweights; i++)
	{
		InterbreedFuzzySeperator_r(config1->weights[i].firstseperator,
									config2->weights[i].firstseperator,
									configout->weights[i].firstseperator);
	} //end for
} //end of the function InterbreedWeightConfigs
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void BotShutdownWeights(void)
{
	int i;

	for( i = 0; i < MAX_WEIGHT_FILES; i++ )
	{
		if (weightFileList[i])
		{
			FreeWeightConfig2(weightFileList[i]);
			weightFileList[i] = NULL;
		} //end if
	} //end for
} //end of the function BotShutdownWeights

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -