Seite 32 von 32 ErsteErste ... 222829303132
Ergebnis 466 bis 473 von 473

Thema: Debug-Dll

  1. #466
    Moderator Avatar von Kathy
    Registriert seit
    11.10.07
    Beiträge
    17.012
    Wenn ich das richtig vestehe, müsste ich hier eigentlich verhindern, dass iValue so hoch wird. Da MAX_INT bei positiven und negativen Zahlen = 2.147.483.647 ist, ist MAX_INT/1000 ja immer noch 2.147.483
    iValue muss also mindestens 2.147.484 sein. Wie kommt man auf so hohe Werte?

    Interessant wäre allerdings, ob es bedeutsam ist. Wenn die KI einmal eine "falsche" Entscheidung trifft und das wertvollste Gebäude nicht baut, wäre das vielleicht nicht so dramatisch. Wenn es aber dann regelmäßig so ist bzw. sie ein besonders wertvolles Gebäude nie baut, weil es immer einen zu hohen Wert hat, wäre das natürlich ein ernstes Handcap für die KI.
    Geändert von Kathy (31. Dezember 2013 um 17:29 Uhr)

  2. #467
    Civ4 BASE Coder Avatar von rucivfan
    Registriert seit
    10.07.11
    Ort
    Antarktika
    Beiträge
    19.016
    Mal ein kleiner Performancetipp:

    Suche mal nach int pathCost(FAStarNode* parent, FAStarNode* node, int data, const void* pointer, FAStar* finder)

    Diese Methode bestimmt die Kosten eines Weges für die kürzeste Wegeroutine.

    Dort wird in einer Schleife für jede Einheit der kleinste Rest Bewegung ermittelt, danach entschieden ob die Einheiten weniger als im bisherigen schlechtesten Fall an Restbewegung verursacht und dann abhängig von den Bewegungskosten die Wegekosten ermittelt.

    Zum Beispiel gibt es dort Wegekostenerhöhungen wie folgt:


    Code:
    					if (pToPlot->getTeam() != pLoopUnit->getTeam())
    					{
    						iCost += PATH_TERRITORY_WEIGHT;
    					}
    Diese Abfrage befindet sich in der Schleife. Jedoch ist das bei den Beispiel nicht notwendig. pToPlot ist vor der Schleife schon bekannt und das Team erhält man auch über pSelectionGroup->getTeam(). pSelectionGroup sind dabei alle angeklickten Einheiten die man bewegen will zum Beispiel. Sagt ja auch der Name. Diese Addition kann man ohne weiteres also ans Ende außerhalb der Schleife packen.

    Da wie gesagt, die Bewegungsroutine eine immer größeren Performanceeinfluss nimmt, je mehr Einheiten es gibt, ist das nicht unerheblich. So kann man auch mit den anderen zusätzlichen additionen mit "iCost +=" verfahren. Nur die Erstsetzungen von "iCost =" sollte in Ruhe gelassen werden.

    Wenn du Schäden durch Gelände verwenden möchtest, ist es zu empfehlen,

    Code:
    						if (pToPlot->getExtraMovePathCost() > 0)
    						{
    							iCost += (PATH_MOVEMENT_WEIGHT * pToPlot->getExtraMovePathCost());
    						}
    auszukommendieren. Der Extrakosten Aufruf getExtraMovePathCost()ist nicht optimal für die Wegefindung. Die Schadensberechnung unter if(0 != GC.getPATH_DAMAGE_WEIGHT()) kann man mit der Abfrage iWorstMovesLeft == 0 auch außerhalb der Schleife verlegen.

    Die Bewegunszusätze für die KI kannst du auch überlegen ob du sie möchtest.

    Code:
    					if (pSelectionGroup->AI_isControlled())
    					{
    						if (pLoopUnit->canAttack())
    						{
    							if (gDLL->getFAStarIFace()->IsPathDest(finder, pToPlot->getX_INLINE(), pToPlot->getY_INLINE()))
    							{
    								if (pToPlot->isVisibleEnemyDefender(pLoopUnit))
    								{
    									iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pLoopUnit->noDefensiveBonus()) ? 0 : pFromPlot->defenseModifier(pLoopUnit->getTeam(), false)))));
    
    									if (!(pFromPlot->isCity()))
    									{
    										iCost += PATH_CITY_WEIGHT;
    									}
    
    										if (pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot)))
    									{
    										if (!(pLoopUnit->isRiver()))
    										{
    											iCost += (PATH_RIVER_WEIGHT * -(GC.getRIVER_ATTACK_MODIFIER()));
    											iCost += (PATH_MOVEMENT_WEIGHT * iMovesLeft);
    										}
    									}
    								}
    							}
    						}
    					}
    Am schlimmsten ist pToPlot->isVisibleEnemyDefender(pLoopUnit). Die Abfrage kann sich sehr Extrem auf die Performance auswirken! Eine Alternative dazu gibt es aber auch nicht außer die Abfrage zu entfernen.

    Ich kann dazu nur sagen, dass ich den zusätzlichen Code für die KI auch den Menschen allgemein in veränderter Weiße zur Verfügung gemacht habe.

    iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pLoopUnit->noDefensiveBonus()) ? 0 : pFromPlot->defenseModifier(pLoopUnit->getTeam(), false))))); wird dabei immer raufgerechnet. Das Gleiche mit anderen Wert für pToPlot kommt bei mir nur, wenn iMovesLeft == 0.
    Dabei gibt es auch eine weitere Optimierung, dann man defenseModifier(pLoopUnit->getTeam(), false) für pFromPlot und pToPlot auch vor der Schleife berechnen kann. Das Team ist schließlich durch pSelectionGroup ja unabhängig von den Einheiten bekannt.

    iCost += PATH_CITY_WEIGHT; mit der if Abfrage kann auch nach der Schleife geschehen, dann würde bei einen Menschen eben auch die Routen über Städte bevorteilt, wenn sonst Alternativwege gleich lang wären.

    Code:
    if (pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot)))
    									{
    										if (!(pLoopUnit->isRiver()))
    										{
    											iCost += (PATH_RIVER_WEIGHT * -(GC.getRIVER_ATTACK_MODIFIER()));
    											iCost += (PATH_MOVEMENT_WEIGHT * iMovesLeft);
    										}
    									}
    Besonders der Codeteil kann mit Veränderung allgemein übernommen werden. iCost += (PATH_MOVEMENT_WEIGHT * iMovesLeft); sollte entfernt werden. An sonsten sollte man auch hier wieder vor der Schleife nach isRiverCrossing fragen. Das hängt ja nur von den Plots ab. Der zusatz iCost += (PATH_MOVEMENT_WEIGHT * iMovesLeft); ist auch sowas von Sinnlos. Bei der Kampfentscheidung entscheident man, ob man auf einen Nachbarplot ausweicht und dann angreift, aber nicht in der kürzesten Wegeroutine. Einheiten sind nicht starr und feinliche Einheiten können sich bewegen. Entweder der Stack steht da neben, dann entscheiden man nach Kampfchancen oder der Stack ist so weit weg, dass eine Wegfindung dannach keinen Zweck erfüllt.

    Das soll mal als Optimierungsansatz herleiten. Das dürfte sich mehr wie alles andere auswirken auf die Rundenzeiten. Nur noch ein Hinweis, kopieren die Methode als ganzes und kommentiere das alte aus. Das soltle sich auf die Performance auswirken, aber die Routine nicht allgemein anders Wirken lassen. Sehr häufig wird einfach nur über kurze Entfernungen nach den kürzesten Weg gefragt und dann wirkt sich pToPlot->isVisibleEnemyDefender(pLoopUnit) wirklich aus.

    ps: Sollte irgen wo was nur mit iMoves stehen, ist iMovesLeft gemeint. Ich habe komplett anderen Code wie Original vor mir.
    Geändert von rucivfan (23. April 2014 um 11:13 Uhr)

  3. #468
    Moderator Avatar von Kathy
    Registriert seit
    11.10.07
    Beiträge
    17.012
    Danke, Rucivfan. Ich muss mir das ganze mal in Ruhe an einem Wochenende (oder am 1. Mai) ansehen, damit ich beim Einbauen keinen Mist baue. Einbauen sollte ich es auf jeden Fall, denn dass sich bei den Moves am meisten beeinflussen lässt glaube ich gerne. Aber ich muss es ordentlich machen. Kann also sein, dass hier demnächst noch Rückfragen kommen.

  4. #469
    Moderator Avatar von Kathy
    Registriert seit
    11.10.07
    Beiträge
    17.012
    Also, ich weiß nicht, ob ich alles richtig gemacht habe. Ich glaube eher, es ist viel Murks drin

    1) Wenn ich die Sachen außerhalb der Schleife schreibe, die du meinst, ist entweder (siehe unten) iCost noch nicht initiiert, oder (falls ich es nach der Schleife schreibe) wird iCost gar nicht mehr aufgerufen, sondern nur iWorstCost. iCost kann ich auch gar nicht mir pSelectioGroup initiieren. Soll ich also alles ans Ende stelle und mit iWorstCost statt iCost arbeiten?

    Code:
    //Optimiert durch Rucivfan Beginn
    int pathCost(FAStarNode* parent, FAStarNode* node, int data, const void* pointer, FAStar* finder)
    {
    	PROFILE_FUNC();
    
    	CLLNode<IDInfo>* pUnitNode;
    	CvSelectionGroup* pSelectionGroup;
    	CvUnit* pLoopUnit;
    	CvPlot* pFromPlot;
    	CvPlot* pToPlot;
    	int iWorstCost;
    	int iCost;
    	int iWorstMovesLeft;
    	int iMovesLeft;
    	int iWorstMax;
    	int iMax;
    
    	pFromPlot = GC.getMapINLINE().plotSorenINLINE(parent->m_iX, parent->m_iY);
    	FAssert(pFromPlot != NULL);
    	pToPlot = GC.getMapINLINE().plotSorenINLINE(node->m_iX, node->m_iY);
    	FAssert(pToPlot != NULL);
    
    	pSelectionGroup = ((CvSelectionGroup *)pointer);
    
    	iWorstCost = MAX_INT;
    	iWorstMovesLeft = MAX_INT;
    	iWorstMax = MAX_INT;
    
    	pUnitNode = pSelectionGroup->headUnitNode();
    
    	//Rucivfan3
    	int iDefenseFromPlotModifier;
    	iDefenseFromPlotModifier = pFromPlot->defenseModifier(pSelectionGroup->getTeam(), false);
    	// Rucivfan 3 End
    	//Rucivfan 5
    	int iDefenseToPlotModifier;
    	iDefenseToPlotModifier = pToPlot->defenseModifier(pSelectionGroup->getTeam(), false);
    	// Rucivfan 5 End
    	//rucivfan 6
    	if (pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot)))
    	{
    //	if (!(pLoopUnit->isRiver()))
    	//	{
    		iCost += (PATH_RIVER_WEIGHT * -(GC.getRIVER_ATTACK_MODIFIER()));
    //		iCost += (PATH_MOVEMENT_WEIGHT * iMovesLeft);
    	//	}
    	}
    	//rucivfan 6 End
    	//Rucivfan 1
    	if (pToPlot->getTeam() != pSelectionGroup->getTeam())
    	{
    		iCost += PATH_TERRITORY_WEIGHT;
    	}
    	//Rucivfan 1 End
    	//Rudivfan 2End
    	if (iWorstMovesLeft == 0)
    	{
    		// Damage caused by features (mods)
    		if (0 != GC.getPATH_DAMAGE_WEIGHT())
    		{
    			if (pToPlot->getFeatureType() != NO_FEATURE)
    			{
    				iCost += (GC.getPATH_DAMAGE_WEIGHT() * std::max(0, GC.getFeatureInfo(pToPlot->getFeatureType()).getTurnDamage())) / GC.getMAX_HIT_POINTS();
    			}
    
    //			if (pToPlot->getExtraMovePathCost() > 0)
    	//		{
    		//		iCost += (PATH_MOVEMENT_WEIGHT * pToPlot->getExtraMovePathCost());
    			//}
    		}
    	}
    	//Rudivfan 2End
    	//Rusivfan 4
    	if (!(pFromPlot->isCity()))
    	{
    		iCost += PATH_CITY_WEIGHT;
    	}
    	//Rusivfan 4 End
    	while (pUnitNode != NULL)
    	{
    		pLoopUnit = ::getUnit(pUnitNode->m_data);
    		pUnitNode = pSelectionGroup->nextUnitNode(pUnitNode);
    		FAssertMsg(pLoopUnit->getDomainType() != DOMAIN_AIR, "pLoopUnit->getDomainType() is not expected to be equal with DOMAIN_AIR");
    
    		if (parent->m_iData1 > 0)
    		{
    			iMax = parent->m_iData1;
    		}
    		else
    		{
    			iMax = pLoopUnit->maxMoves();
    		}
    
    		iCost = pToPlot->movementCost(pLoopUnit, pFromPlot);
    
    		iMovesLeft = std::max(0, (iMax - iCost));
    
    		if (iMovesLeft <= iWorstMovesLeft)
    		{
    			if ((iMovesLeft < iWorstMovesLeft) || (iMax <= iWorstMax))
    			{
    				if (iMovesLeft == 0)
    				{
    					iCost = (PATH_MOVEMENT_WEIGHT * iMax);
    
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                      04/03/09                                jdog5000      */
    /*                                                                                              */
    /* General AI                                                                                   */
    /************************************************************************************************/
    					// Add additional cost for ending turn in or adjacent to enemy territory based on flags
    					if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_3)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 3;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 3;
    										iCost /= 2;
    									}
    								}
    							}
    						}
    					}
    					else if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_2)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 2;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    								
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 4;
    										iCost /= 3;
    									}
    								}
    							}
    						}
    					}
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                       END                                                  */
    /************************************************************************************************/
    				}
    				else
    				{
    					iCost = (PATH_MOVEMENT_WEIGHT * iCost);
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                      04/03/09                                jdog5000      */
    /*                                                                                              */
    /* General AI                                                                                   */
    /************************************************************************************************/
    /*					// Add additional cost for movement in or adjacent to enemy territory based on flags
    					if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_3)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 2;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 4;
    										iCost /= 3;
    									}
    								}
    							}
    						}
    					}
    					else if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_2)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 3;
    							iCost /= 2;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    								
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 6;
    										iCost /= 5;
    									}
    								}
    							}
    						}
    					}
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                       END                                                  */
    /************************************************************************************************/
    				}
    
    				if (pLoopUnit->canFight())
    				{
    					if (iMovesLeft == 0)
    					{//Rucivfan 5
    						iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pLoopUnit->noDefensiveBonus()) ? 0 : iDefenseToPlotModifier))));
    					}//Rucivfan 5 End
    					//Rucivfan 3.2
    					iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pLoopUnit->noDefensiveBonus()) ? 0 : iDefenseFromPlotModifier ))));
    					//Rucivfan 3.2 End
    
    					if (pSelectionGroup->AI_isControlled())
    					{
    					//	if (pLoopUnit->canAttack())
    				//		{
    	//						if (gDLL->getFAStarIFace()->IsPathDest(finder, pToPlot->getX_INLINE(), pToPlot->getY_INLINE()))
    		//					{
    //								if (pToPlot->isVisibleEnemyDefender(pLoopUnit))
    			//				}
    						//}
    //					}
    	//			}
    
    				if (iCost < iWorstCost)
    				{
    					iWorstCost = iCost;
    					iWorstMovesLeft = iMovesLeft;
    					iWorstMax = iMax;
    				}
    			}
    		}
    	}
    
    	FAssert(iWorstCost != MAX_INT);
    
    	iWorstCost += PATH_STEP_WEIGHT;
    
    	if ((pFromPlot->getX_INLINE() != pToPlot->getX_INLINE()) && (pFromPlot->getY_INLINE() != pToPlot->getY_INLINE()))
    	{
    		iWorstCost += PATH_STRAIGHT_WEIGHT;
    	}
    
    	FAssert(iWorstCost > 0);
    
    	return iWorstCost;
    }//Optimiert durch Rucivfan End

  5. #470
    Civ4 BASE Coder Avatar von rucivfan
    Registriert seit
    10.07.11
    Ort
    Antarktika
    Beiträge
    19.016
    Die Formatierung stimmt nicht ganz. Vor allem ist schwer zu erkenne, was auskommentiert ist. Wenn du die Kosten außerhalb der Schleife aufrechnest, muss du diese zu iWorstCost rechnen. iWorstCost sind die besten Kosten (nach dem Code, nicht der Bezeichnung).
    Auf diese rechnest du rauf und zwar hinter der Schleife und nicht davor! Sonst musst du die schon errechnetete Kosten vor der Schleife extra in einer Variabel sichern und immer auf iCost raufrechnen, damit iCost und iWorstCost vergleichbar bleiben.

    Code:
    int pathCost(FAStarNode* parent, FAStarNode* node, int data, const void* pointer, FAStar* finder)
    {
    	PROFILE_FUNC();
    
    	CvSelectionGroup* pSelectionGroup;
    
    	int iCost;
    	int iCostMoves;
    	int iWorstCostMoves;
    	int iCostMoveDenominator;
        int iWorstCostMoveDenominator;
    	
    	int iStartMoves;
    	int iStartMoveDenominator;
    	int iStartMovesInverse;
    
    	int iFlatMoves;
    	int iBaseMoves;
    	int iActionMoves;
    	int iPlotCost;
    
    	bool bMaxMoves;
    	bool bDefensiveBonus;
    	bool bAlwaysHostile;
    	bool bIsRiverCrossing;
    
    	CvPlot& kFromPlot = *GC.getMapINLINE().plotSorenINLINE(parent->m_iX, parent->m_iY);
    	FAssert(&kFromPlot != NULL);
    	CvPlot& kToPlot = *GC.getMapINLINE().plotSorenINLINE(node->m_iX, node->m_iY);
    	FAssert(&kToPlot != NULL);
    
    	bMaxMoves = (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_MAX_MOVES);
    
    	pSelectionGroup = ((CvSelectionGroup *)pointer);
    	
    	iCost = MAX_INT;
    	iWorstCostMoves = (bMaxMoves) ? (1) : (0);
    	iWorstCostMoveDenominator = 1;
    
    	bIsRiverCrossing = kToPlot.isRiverCrossing(kFromPlot);
    	bDefensiveBonus = false;
    	bAlwaysHostile = false;
    
    	iPlotCost = kToPlot.plotCost(bIsRiverCrossing);
    
    	iStartMoves = parent->m_iData1;
    	iStartMoveDenominator = GC.getMapINLINE().getPathMoveDenominatorINLINE(node->m_iX, node->m_iY);
    	if (iStartMoves == iStartMoveDenominator)
    	{
    		iStartMoves = 0;
    		iStartMoveDenominator = 1;
    	}
    	iStartMovesInverse = iStartMoveDenominator - iStartMoves;
    
    	for (CLLNode<IDInfo>* pUnitNode = pSelectionGroup->headUnitNode(); pUnitNode != NULL; pUnitNode = pSelectionGroup->nextUnitNode(pUnitNode))
    	{
    		const CvUnit& kLoopUnit = *::getUnit(pUnitNode->m_data);
    
    		if(parent->m_iData2 == 1)
    		{
    			iFlatMoves = kLoopUnit.flatMoves();
    		}
    		else
    		{
    			iFlatMoves = kLoopUnit.getFlatMoves();
    		}
    
    		iBaseMoves = kLoopUnit.baseMoves();
    		iActionMoves = iBaseMoves + iFlatMoves;
    
    		if(isMoveFractionGreaterEqualThanINLINE(iStartMoves, iStartMoveDenominator, iBaseMoves, iActionMoves))
    		{
    			iCostMoves = 1;
    			iCostMoveDenominator = iActionMoves;
    		}
    		else
    		{
    			iCostMoves = kToPlot.plotCostDiscount(kLoopUnit, iPlotCost);
    			iCostMoveDenominator = kToPlot.movementMoveDenominator(kLoopUnit, kFromPlot, iCostMoves, bIsRiverCrossing, iBaseMoves, iFlatMoves);
    		}
    
    		if(bMaxMoves)
    		{
    			if(isMoveFractionGreaterThanINLINE(iWorstCostMoves, iWorstCostMoveDenominator, iCostMoves, iCostMoveDenominator))
    			{
    				iWorstCostMoves = iCostMoves;
    				iWorstCostMoveDenominator = iCostMoveDenominator;
    			}
    				
    			continue;
    		}
    			
    		if(isMoveFractionGreaterThanINLINE(iCostMoves, iCostMoveDenominator, iWorstCostMoves, iWorstCostMoveDenominator))
    		{
    			iWorstCostMoves = iCostMoves;
    			iWorstCostMoveDenominator = iCostMoveDenominator;
    
    			if(!(bDefensiveBonus || kLoopUnit.noDefensiveBonus()))
    			{
    				bDefensiveBonus = true;
    			}
    
    			if(!(bAlwaysHostile || kLoopUnit.isAlwaysHostile()))
    			{
    				bAlwaysHostile = true;
    			}
    		}		
    	}
    
    	if(isMoveFractionGreaterThanINLINE(iCostMoves, iCostMoveDenominator, iStartMovesInverse, iStartMoveDenominator))
    	{
    		iCost = PATH_MOVEMENT_WEIGHT * std::max(1, (GC.getMOVE_DENOMINATOR() * iStartMovesInverse) / iStartMoveDenominator);
    	}
    	else
    	{
    		iCost = PATH_MOVEMENT_WEIGHT * std::max(1, (GC.getMOVE_DENOMINATOR() * iWorstCostMoves) / iWorstCostMoveDenominator);
    	}	
    
    	FAssert(iCost != MAX_INT);
    
    	if(gDLL->getFAStarIFace()->GetInfo(finder) & (MOVE_AVOID_ENEMY_WEIGHT_3 | MOVE_AVOID_ENEMY_WEIGHT_2))
    	{
    		TeamTypes eGroupTeam = pSelectionGroup->getHeadTeam();
    
    		for (TeamTypes eTeam = (TeamTypes)0; eTeam < MAX_TEAMS; eTeam = (TeamTypes)(eTeam + 1))
    		{
    			if(kToPlot.getVisibilityCount(eTeam) > 0 && ((bAlwaysHostile && eTeam != pSelectionGroup->getTeam()) || GET_TEAM(eGroupTeam).isAtWar(eTeam) || GET_TEAM(eGroupTeam).AI_getWarPlan(kToPlot.getTeam())))
    			{
    				bAlwaysHostile = true;
    				iCost *= PATH_MOVE_AVOID_ENEMY_WEIGHT;
    				break;
    			}
    		}
    	}
    
    	if (bAlwaysHostile)
    	{
    		if (kToPlot.isOwned() && kToPlot.getTeam() != pSelectionGroup->getTeam())
    		{
    			iCost += PATH_ALWAYS_HOSTILE_WEIGHT;
    		}
    	}
    
    	if(iWorstCostMoves == iStartMovesInverse)
    	{
    		// Damage caused by features (mods)
    		if (0 != GC.getPATH_DAMAGE_WEIGHT())
    		{
    			if (kToPlot.getFeatureType() != NO_FEATURE)
    			{
    				iCost += (GC.getPATH_DAMAGE_WEIGHT() * std::max(0, GC.getFeatureInfo(kToPlot.getFeatureType()).getTurnDamage())) / GC.getMAX_HIT_POINTS();
    			}
    		}
    
    		iCost += PATH_DEFENSE_WEIGHT;
    		if(bDefensiveBonus)
    		{
    			iCost -= std::min(PATH_DEFENSE_WEIGHT, kToPlot.defenseModifier(pSelectionGroup->getTeam(), false));
    		}
    	}
    
    	iCost += PATH_DEFENSE_WEIGHT;
    	if(bDefensiveBonus)
    	{
    		iCost -= std::min(PATH_DEFENSE_WEIGHT, kFromPlot.defenseModifier(pSelectionGroup->getTeam(), false));
    	}
    
    	if (kFromPlot.getTeam() != pSelectionGroup->getTeam())
    	{
    		iCost += PATH_TERRITORY_WEIGHT;
    	}
    
    	if (bIsRiverCrossing)
    	{
    		iCost += PATH_RIVER_WEIGHT;
    	}
    
    	if (!(kFromPlot.isCity()))
    	{
    		iCost += PATH_CITY_WEIGHT;
    	}
    
    	iCost += PATH_STEP_WEIGHT;
    
    	if ((kFromPlot.getX_INLINE() != kToPlot.getX_INLINE()) && (kFromPlot.getY_INLINE() != kToPlot.getY_INLINE()))
    	{
    		iCost += PATH_STRAIGHT_WEIGHT;
    	}
    
    	FAssert(iCost > 0);
    
    	// rucivfan_test rt[
    //#ifdef _DEBUG
    //	if (GC.getLogging())
    //	{
    //		if (gDLL->getChtLvl() > 0)
    //		{
    //			char szOut[1024];
    //			sprintf(szOut, "Plot: (%d, %d) -> WorstCost = %d, parent: TotalCost = %d, KnownCost = %d, HeuristicCost = %d \n", pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), iCost, parent->m_iTotalCost, parent->m_iKnownCost, parent->m_iHeuristicCost);
    //			gDLL->messageControlLog(szOut);
    //			//OutputDebugString(szOut);
    //		}
    //	}
    //#endif
    	// ]rucivfan_test rt
    
    	return iCost;
    }
    Nur als Beispiel, wie es bei mir aussieht. Ich habe für dich leider schon eine komplette andere Bewegungspunktrechnung die auf Brüchen basiert um genaue Rechnungen der Bewegungspunkte immer möglich zu machen. Deswegen gibt es auch kein iWorstCost mehr. Desweiteren ist zu Berücksichtigen, dass ich hier mit Referenzen(Interne Pointer) arbeite.

    Zitat Zitat von Kathy Beitrag anzeigen
    1) Wenn ich die Sachen außerhalb der Schleife schreibe, die du meinst, ist entweder (siehe unten) iCost noch nicht initiiert, oder (falls ich es nach der Schleife schreibe) wird iCost gar nicht mehr aufgerufen, sondern nur iWorstCost. iCost kann ich auch gar nicht mir pSelectioGroup initiieren. Soll ich also alles ans Ende stelle und mit iWorstCost statt iCost arbeiten?
    iCost sind die Kosten einer Einheit. iWorstCost die besten Kosten (anders wie der Name sagt). iWorstCost ist anfänglich MAX-INT oder symbolisch betrachtet "unendlich". Man sucht die kleinesten Kosten und geht von den höchst möglichen Kosten aus. Auf iWorstCost muss das hinter der Schleife gerechnet werden. Vorher ist iWorstCost einfach zu groß und es kommt zum Überlauf in den negativen Zahlen-Bereich.
    Geändert von rucivfan (01. Mai 2014 um 13:41 Uhr)

  6. #471
    Moderator Avatar von Kathy
    Registriert seit
    11.10.07
    Beiträge
    17.012
    Ich habe nun alle alle Teile, die außerhalb der Schleife liegen sollen, am Ende aufgeführt. Die auskommentierten Teile habe ich gelöscht, den Originalcode habe ich im Spiel als Ganzes noch einmal auskommentiert hinterlassen. (Im Editor sieht man ja gut, was auskommentiert ist und was nicht).
    Code:
    //Optimiert durch Rucivfan Beginn
    int pathCost(FAStarNode* parent, FAStarNode* node, int data, const void* pointer, FAStar* finder)
    {
    	PROFILE_FUNC();
    
    	CLLNode<IDInfo>* pUnitNode;
    	CvSelectionGroup* pSelectionGroup;
    	CvUnit* pLoopUnit;
    	CvPlot* pFromPlot;
    	CvPlot* pToPlot;
    	int iWorstCost;
    	int iCost;
    	int iWorstMovesLeft;
    	int iMovesLeft;
    	int iWorstMax;
    	int iMax;
    
    	pFromPlot = GC.getMapINLINE().plotSorenINLINE(parent->m_iX, parent->m_iY);
    	FAssert(pFromPlot != NULL);
    	pToPlot = GC.getMapINLINE().plotSorenINLINE(node->m_iX, node->m_iY);
    	FAssert(pToPlot != NULL);
    
    	pSelectionGroup = ((CvSelectionGroup *)pointer);
    
    	iWorstCost = MAX_INT;
    	iWorstMovesLeft = MAX_INT;
    	iWorstMax = MAX_INT;
    
    	pUnitNode = pSelectionGroup->headUnitNode();
    
    	//Rucivfan3
    	int iDefenseFromPlotModifier;
    	iDefenseFromPlotModifier = pFromPlot->defenseModifier(pSelectionGroup->getTeam(), false);
    	// Rucivfan 3 End
    	//Rucivfan 5
    	int iDefenseToPlotModifier;
    	iDefenseToPlotModifier = pToPlot->defenseModifier(pSelectionGroup->getTeam(), false);
    	// Rucivfan 5 End
    
    	while (pUnitNode != NULL)
    	{
    		pLoopUnit = ::getUnit(pUnitNode->m_data);
    		pUnitNode = pSelectionGroup->nextUnitNode(pUnitNode);
    		FAssertMsg(pLoopUnit->getDomainType() != DOMAIN_AIR, "pLoopUnit->getDomainType() is not expected to be equal with DOMAIN_AIR");
    
    		if (parent->m_iData1 > 0)
    		{
    			iMax = parent->m_iData1;
    		}
    		else
    		{
    			iMax = pLoopUnit->maxMoves();
    		}
    
    		iCost = pToPlot->movementCost(pLoopUnit, pFromPlot);
    
    		iMovesLeft = std::max(0, (iMax - iCost));
    
    		if (iMovesLeft <= iWorstMovesLeft)
    		{
    			if ((iMovesLeft < iWorstMovesLeft) || (iMax <= iWorstMax))
    			{
    				if (iMovesLeft == 0)
    				{
    					iCost = (PATH_MOVEMENT_WEIGHT * iMax);
    
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                      04/03/09                                jdog5000      */
    /*                                                                                              */
    /* General AI                                                                                   */
    /************************************************************************************************/
    					// Add additional cost for ending turn in or adjacent to enemy territory based on flags
    					if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_3)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 3;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 3;
    										iCost /= 2;
    									}
    								}
    							}
    						}
    					}
    					else if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_2)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 2;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    								
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 4;
    										iCost /= 3;
    									}
    								}
    							}
    						}
    					}
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                       END                                                  */
    /************************************************************************************************/
    				}
    				else
    				{
    					iCost = (PATH_MOVEMENT_WEIGHT * iCost);
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                      04/03/09                                jdog5000      */
    /*                                                                                              */
    /* General AI                                                                                   */
    /************************************************************************************************/
    /*					// Add additional cost for movement in or adjacent to enemy territory based on flags
    					if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_3)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 2;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 4;
    										iCost /= 3;
    									}
    								}
    							}
    						}
    					}
    					else if (gDLL->getFAStarIFace()->GetInfo(finder) & MOVE_AVOID_ENEMY_WEIGHT_2)
    					{
    						if (pToPlot->isOwned() && ((GET_TEAM(pSelectionGroup->getHeadTeam()).AI_getWarPlan(pToPlot->getTeam()) != NO_WARPLAN) || (pToPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pToPlot))))
    						{
    							iCost *= 3;
    							iCost /= 2;
    						}
    						else
    						{
    							CvPlot* pAdjacentPlot;
    							int iI;
    							for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
    							{
    								pAdjacentPlot = plotDirection(pToPlot->getX_INLINE(), pToPlot->getY_INLINE(), ((DirectionTypes)iI));
    								
    								if( pAdjacentPlot != NULL )
    								{
    									if (pAdjacentPlot->isOwned() && (atWar(pAdjacentPlot->getTeam(), pSelectionGroup->getHeadTeam()) || (pAdjacentPlot->getTeam() != pLoopUnit->getTeam() && pLoopUnit->isAlwaysHostile(pAdjacentPlot))))
    									{
    										iCost *= 6;
    										iCost /= 5;
    									}
    								}
    							}
    						}
    					}
    /************************************************************************************************/
    /* BETTER_BTS_AI_MOD                       END                                                  */
    /************************************************************************************************/
    				}
    
    				if (pLoopUnit->canFight())
    				{
    					if (iMovesLeft == 0)
    					{//Rucivfan 5
    						iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pLoopUnit->noDefensiveBonus()) ? 0 : iDefenseToPlotModifier))));
    					}//Rucivfan 5 End
    					//Rucivfan 3.2
    					iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pLoopUnit->noDefensiveBonus()) ? 0 : iDefenseFromPlotModifier ))));
    					//Rucivfan 3.2 End
                                    }
    				if (iCost < iWorstCost)
    				{
    					iWorstCost = iCost;
    					iWorstMovesLeft = iMovesLeft;
    					iWorstMax = iMax;
    				}
    			}
    		}
    	}
    	//rucivfan 6
    	if (pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot)))
    	{
    		iWorstCost += (PATH_RIVER_WEIGHT * -(GC.getRIVER_ATTACK_MODIFIER()));
    	}
    	//rucivfan 6 End
    	//Rucivfan 1
    	if (pToPlot->getTeam() != pSelectionGroup->getTeam())
    	{
    		iWorstCost += PATH_TERRITORY_WEIGHT;
    	}
    	//Rucivfan 1 End
    	//Rudivfan 2End
    	if (iWorstMovesLeft == 0)
    	{
    		// Damage caused by features (mods)
    		if (0 != GC.getPATH_DAMAGE_WEIGHT())
    		{
    			if (pToPlot->getFeatureType() != NO_FEATURE)
    			{
    				iWorstCost += (GC.getPATH_DAMAGE_WEIGHT() * std::max(0, GC.getFeatureInfo(pToPlot->getFeatureType()).getTurnDamage())) / GC.getMAX_HIT_POINTS();
    			}
    		}
    	}
    	//Rudivfan 2End
    	//Rusivfan 4
    	if (!(pFromPlot->isCity()))
    	{
    		iWorstCost += PATH_CITY_WEIGHT;
    	}
    	//Rusivfan 4 End
    	FAssert(iWorstCost != MAX_INT);
    
    	iWorstCost += PATH_STEP_WEIGHT;
    
    	if ((pFromPlot->getX_INLINE() != pToPlot->getX_INLINE()) && (pFromPlot->getY_INLINE() != pToPlot->getY_INLINE()))
    	{
    		iWorstCost += PATH_STRAIGHT_WEIGHT;
    	}
    
    	FAssert(iWorstCost > 0);
    
    	return iWorstCost;
    }//Optimiert durch Rucivfan End
    Habe ich dich so richtig verstanden?
    Geändert von Kathy (01. Mai 2014 um 14:43 Uhr)

  7. #472
    Civ4 BASE Coder Avatar von rucivfan
    Registriert seit
    10.07.11
    Ort
    Antarktika
    Beiträge
    19.016
    Sieht gut aus. Wer ist nur Rudivfan oder Rusivfan ?

    Was die BETTER_BTS_AI_MOD -Dinger angeht, die habe ich beim Basecode entfernt bzw anders gelöst. Die nehmen für wenig Inhalt viel von der Sichts. Ich muss meine Ersetzung im einzelnen noch testen, weil ich sie vor hin erst neu gemacht habe.

    Das Einzige, was es dazu noch zu sagen gibt, du darfst keine Wunder in der Performance erwarten. Der KI-Code ist häufig nicht optimal und ruft extrem einzeln manchmal die kürzeste Wegeroutine auf. Daran muss ich mich aber auch erst wagen um das zu ändern.
    Geändert von rucivfan (01. Mai 2014 um 15:35 Uhr)

  8. #473
    Moderator Avatar von Kathy
    Registriert seit
    11.10.07
    Beiträge
    17.012
    Ich erwarte kein Wunder, aber wenn es etwas hilft, ist es schon nicht schlecht. Also, vielen Dank für deine Anregungen.

Seite 32 von 32 ErsteErste ... 222829303132

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •