Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 16 bis 30 von 31

Thema: Civ 5 vs. Civ 6

  1. #16
    Registrierter Benutzer
    Registriert seit
    25.02.08
    Beiträge
    3.183
    Zitat Zitat von Haremhab Beitrag anzeigen
    Du lieferst für MICH einen Grund, warum ich mir ein Civ 6 in der Grundversion irgendwann mal nur für maximal 5 € im Sale holen würde. Und ich baue so gerne Weltwunder (möglichst alle noch vor der Konkurrenz auf dem SG eine Stufe vor Gott)!!! ...aber wenn man mir mit so einer Spielmechanik hinterfotzig Steine in den Weg legt, na, so nicht liebes Firaxis-Team.
    Es mach auch alteingesesseben erfahrenen CiV Spielern wie mir nur selten Spass,
    da das ganze Spiel so aufgebaut ist, Mechaniken über mechaniken und keine Erklärungen dazu vorausetzungen usw.
    Die Ki ist auch deshalb noch schwächer als in Civ 5 weil sie damit nicht umgehen kann.

  2. #17
    Registrierter Benutzer
    Registriert seit
    25.05.06
    Beiträge
    430
    Zitat Zitat von L4m3r Beitrag anzeigen
    Es mach auch alteingesesseben erfahrenen CiV Spielern wie mir nur selten Spass,
    da das ganze Spiel so aufgebaut ist, Mechaniken über mechaniken und keine Erklärungen dazu vorausetzungen usw.
    Die Ki ist auch deshalb noch schwächer als in Civ 5 weil sie damit nicht umgehen kann.
    Ich würde Civ 6 als Fan des Franchise, der ich nun mal seit Jahrzehnten bin, echt eine Chance geben, auch wegen der guten, alten Zeiten, aber mit so einer Mechanik kann ich definitiv NICHT mehr den "Pfad der Weltwunder" spielen, wie in Civ 5. Eine absolute Enttäuschung so etwas. Die KI wird auch in der aktuellen Online-Ausgabe der Gamestar als "unterirdisch" klassifiziert, noch viel schlechter als die von Civ 5! L4m3r: kannst du mir erklären, warum es seit Civ 1 (Jahr 1991!) in puncto der KI-Entwicklung nur wenig bis gar keinen echten Fortschritt bis heute gab? Wie ist das möglich? Diese Frage geht übrigens nicht nur an L4m3r...
    Geändert von Haremhab (23. Mai 2020 um 10:53 Uhr)

  3. #18
    CivBot
    Registriert seit
    25.03.06
    Ort
    Göttingen
    Beiträge
    40.442
    Die Entwickler basteln lieber an der Spielmechanik rum, anstatt bei gleichbleibender Spielmechanik an der KI rumzubasteln, um die KI an die gegebene Spielmechanik anzupassen.
    Zitat Zitat von d73070d0 Beitrag anzeigen
    Ach, das darfst Du nicht so eng sehen. Aus justanick kriegt man nur eine konkrete Antwort raus, wenn man Müll erzählt und dann zurechtgewiesen wird. Wenn Du also was von ihm willst, frag' nich, sondern stell' falsche Behauptungen in den Raum - die werden dann umgehend korrigiert. ;)

  4. #19
    Registrierter Benutzer
    Registriert seit
    25.05.06
    Beiträge
    430
    Zitat Zitat von justanick Beitrag anzeigen
    Die Entwickler basteln lieber an der Spielmechanik rum, anstatt bei gleichbleibender Spielmechanik an der KI rumzubasteln, um die KI an die gegebene Spielmechanik anzupassen.
    Wenn sie verdammt noch mal nicht endlich richtig Knete in die Hand nehmen und die entsprechenden Leute einstellen... und beides in die KI-Entwicklung investieren, dann werde ich zukünftig auf ihre Spiele verzichten.

  5. #20
    Registrierter Benutzer Avatar von Walther
    Registriert seit
    04.12.05
    Beiträge
    7.667
    Zitat Zitat von Haremhab Beitrag anzeigen
    L4m3r: kannst du mir erklären, warum es seit Civ 1 (Jahr 1991!) in puncto der KI-Entwicklung nur wenig bis gar keinen echten Fortschritt bis heute gab? Wie ist das möglich? Diese Frage geht übrigens nicht nur an L4m3r...
    Spiele verkaufen sich seit langem über die Grafik und dem Casual-Gamer als Melkkuh fallen die schwerwiegenden Mängel halt nicht auf, nur denjenigen, die Civ von Anbeginn der Serie viel gezockt haben. Dazu kommt natürlich, man glänzt doch lieber mit einer Menge an Mechaniken anstelle von wenigen Mechaniken für die man dann auch Algorihmen basteln kann. Menge macht sich im Marketing einfach besser für die Melkkuh. Und dann kommt halt dazu, KI ist nicht schlau sondern nur statistisch berechnend und der nächste KI-Abgrund steht natürlich auch mal wieder vor der Tür. Schön ein paar Netze trainieren um an Ende fest zu stellen, man hätte auch einen statistischen Entscheidungsbaum nehmen können. In dem man immer wieder den falschen Weg geht, kommt man nicht voran, außer in der Erfindung neuer Wörter für alten Wein in neuen Schläuchen.

  6. #21
    Registrierter Benutzer
    Registriert seit
    21.03.12
    Beiträge
    22.397
    Du meinst einen statischen Entscheidungsbaum Mit KI hat so eine Spiele-KI bis heute wenig zu tun, außer bei AlphaGo und Co. Allerdings geben sich die Entwickler durchaus Mühe, möglichst alles abzudecken. Die KI in Civ 4 zumindest besteht aus absurd vielen Querverweisen und Optimierungsschleifen, alles handgeschrieben, so dass sich mehr als nur ein Baum ergibt.

  7. #22
    Registrierter Benutzer Avatar von Walther
    Registriert seit
    04.12.05
    Beiträge
    7.667
    Ich meinte schon den statistischen Entscheidungsbaum, bei dem die Entscheidungen noch mit entsprechenden Eintrittswahrscheinlichkeiten versehen werden um die Entscheidung zu optimieren.
    In Civ6 fängt die mangelhafte KI schon beim A*-Algorithmus auf Hex-Feldern mit den entsprechenden Randbedingungen an, weswegen Einheiten gerne wild hin und her laufen ohne dem Ziel näher zu kommen. Da braucht nur eine Einheit an einer Engstelle sichtbar zu werden.

  8. #23
    Registrierter Benutzer
    Registriert seit
    13.03.20
    Beiträge
    30
    Ich frag mal ganz vorsichtig und ahnungslos. Gibt es denn überhaupt ein Rundenbasiertes Strategiespiel mit guter KI? Was wenn die Umsetzung für solche Spiele mit schlechterr KI ein hinzunehmender Makel ist? Dass die Civreihe immer und immer wieder daran scheitert macht mich nun doch skeptisch. An welchem Spiel könnten sich die Civ-Entwickler denn hier z.B. was abkucken?

  9. #24
    Registrierter Benutzer
    Registriert seit
    25.05.06
    Beiträge
    430
    Zitat Zitat von Flunky Beitrag anzeigen
    Du meinst einen statischen Entscheidungsbaum Mit KI hat so eine Spiele-KI bis heute wenig zu tun, außer bei AlphaGo und Co. Allerdings geben sich die Entwickler durchaus Mühe, möglichst alles abzudecken. Die KI in Civ 4 zumindest besteht aus absurd vielen Querverweisen und Optimierungsschleifen, alles handgeschrieben, so dass sich mehr als nur ein Baum ergibt.
    Hast du eine Web-Quelle zu deiner Behauptung zu "absurd vielen Querverweisen und Optimierungsschleifen"-Civ4-KI? Ich danke dir!

  10. #25
    Registrierter Benutzer
    Registriert seit
    21.03.12
    Beiträge
    22.397
    Keine Webquelle, aber dem Spiel liegt der Quellcode bei.

    @Waldhausen: für SC2 gibt es eine experimentelle KI aus GAN. Ist natürlich nicht rundenbasiert, aber das Hauptproblem ist ja die unvollständige Information. Deshalb funktioniert Schach so gut. Aber ich glaub für Poker gibt es jetzt auch eine, die funktioniert.

  11. #26
    Registrierter Benutzer Avatar von Walther
    Registriert seit
    04.12.05
    Beiträge
    7.667
    Du meint damit dann die for-if-Kaskaden welche man auf github findet. Teilweise echt gruselig, kann aber nur etwas werden sofern man noch einen klaren Regelsatz hat, wie es in civ4 der Fall war.

  12. #27
    Registrierter Benutzer
    Registriert seit
    25.05.06
    Beiträge
    430
    Zitat Zitat von Flunky Beitrag anzeigen
    Keine Webquelle, aber dem Spiel liegt der Quellcode bei.
    Mit dem Quellcode kann ich als NICHT-Fachmann nichts anfangen, kannst du was konkretes zu den vielen Querverweisen und Optimierungsschleifen sagen?

  13. #28
    Registrierter Benutzer
    Registriert seit
    21.03.12
    Beiträge
    22.397
    Ich hab jetzt keine spezielle Stelle im Kopf, aber als Beispiel unten die Auswahlmethode für ein neues Bauprojekt in einer Stadt:

    PHP-Code:

    void CvCityAI
    ::AI_chooseProduction()
    {
        
    PROFILE_FUNC();

        
    CvAreapWaterArea;
        
    UnitTypes eProductionUnit;
        
    bool bWasFoodProduction;
        
    bool bHasMetHuman;
        
    bool bLandWar;
        
    bool bAssault;
        
    bool bDefenseWar;
        
    bool bPrimaryArea;
        
    bool bFinancialTrouble;
        
    bool bDanger;
        
    bool bChooseUnit;
        
    int iProductionRank;
        
    int iCulturePressure;

        
    bDanger AI_isDanger();
        
        
    CvPlayerAIkPlayer GET_PLAYER(getOwnerINLINE());

        if (
    isProduction())
        {
            if (
    getProduction() > 0)
            {

                if ((
    getProductionUnitAI() == UNITAI_SETTLE) && kPlayer.AI_isFinancialTrouble())
                {
                    
                }
                
    //if we are killing our growth to train this, then finish it.
                
    else if (!bDanger && isFoodProduction())
                {
                    if ((
    area()->getAreaAIType(getTeam()) != AREAAI_DEFENSIVE))
                    {
                        return;
                    }
                }
                
    // if less than 3 turns left, keep building current item
                
    else if (getProductionTurnsLeft() <= 3)
                {
                    return;
                }
                
                
                
    // if building a combat unit, and we have no defenders, keep building it
                
    eProductionUnit getProductionUnit();
                if (
    eProductionUnit != NO_UNIT)
                {
                    if (
    plot()->getNumDefenders(getOwnerINLINE()) == 0)
                    {
                        if (
    GC.getUnitInfo(eProductionUnit).getCombat() > 0)
                        {
                            return;
                        }
                    }
                }
                
                
    // if we are building a wonder, do not cancel, keep building it (if no danger)
                
    BuildingTypes eProductionBuilding getProductionBuilding();
                if (!
    bDanger && eProductionBuilding != NO_BUILDING && 
                    
    isLimitedWonderClass((BuildingClassTypesGC.getBuildingInfo(eProductionBuilding).getBuildingClassType()))
                {
                    return;
                }
            }

            
    clearOrderQueue();
        }
        
        if (
    GET_PLAYER(getOwner()).isAnarchy())
        {
            return;
        }
        
        
    // only clear the dirty bit if we actually do a check, multiple items might be queued
        
    AI_setChooseProductionDirty(false);

        
    // allow python to handle it
        
    CyCitypyCity = new CyCity(this);
        
    CyArgsList argsList;
        
    argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity));    // pass in city class
        
    long lResult=0;
        
    gDLL->getPythonIFace()->callFunction(PYGameModule"AI_chooseProduction"argsList.makeFunctionArgs(), &lResult);
        
    delete pyCity;    // python fxn must not hold on to this pointer
        
    if (lResult == 1)
        {
            return;
        }

        if (
    isHuman() && isProductionAutomated())
        {
            
    AI_buildGovernorChooseProduction();
            return;
        }
        
        
    CvAreapArea area();
        
    pWaterArea waterArea();
        
    bool bMaybeWaterArea false;
        
        if (
    pWaterArea != NULL)
        {
            
    bMaybeWaterArea true;
            if (!
    GET_TEAM(getTeam()).AI_isWaterAreaRelevant(pWaterArea))
            {
                
    pWaterArea NULL;
            }
        }

        
    bWasFoodProduction isFoodProduction();
        
    bHasMetHuman GET_TEAM(getTeam()).hasMetHuman();
        
    bLandWar = ((pArea->getAreaAIType(getTeam()) == AREAAI_OFFENSIVE) || (pArea->getAreaAIType(getTeam()) == AREAAI_DEFENSIVE) || (pArea->getAreaAIType(getTeam()) == AREAAI_MASSING));
        
    bDefenseWar = (pArea->getAreaAIType(getTeam()) == AREAAI_DEFENSIVE);
        
    bool bAssaultAssist = (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_ASSIST);
        
    bAssault bAssaultAssist || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT) || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_MASSING);
        
    bPrimaryArea kPlayer.AI_isPrimaryArea(pArea);
        
    bFinancialTrouble kPlayer.AI_isFinancialTrouble();
        
    iCulturePressure AI_calculateCulturePressure();
        
    int iNumCitiesInArea pArea->getCitiesPerPlayer(getOwnerINLINE());
        
    bool bImportantCity false//be very careful about setting this.
        
    bool bBigCultureCity false;
        
    int iCultureRateRank findCommerceRateRank(COMMERCE_CULTURE);
        
    int iCulturalVictoryNumCultureCities GC.getGameINLINE().culturalVictoryNumCultureCities();
        
        
    bool bGetBetterUnits kPlayer.AI_isDoStrategy(AI_STRATEGY_GET_BETTER_UNITS);
        
    bool bAggressiveAI GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI);
        
    bool bAlwaysPeace GC.getGameINLINE().isOption(GAMEOPTION_ALWAYS_PEACE);

        
    int iUnitCostPercentage = (kPlayer.calculateUnitCost() * 100) / std::max(1kPlayer.calculatePreInflatedCosts());
        
    int iWaterPercent AI_calculateWaterWorldPercent();
        
        
    int iBuildUnitProb AI_buildUnitProb();
        
        
    int iExistingWorkers kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_WORKER);
        
    int iNeededWorkers kPlayer.AI_neededWorkers(pArea);
        
    int iNeededSeaWorkers = (pWaterArea == NULL) ? AI_neededSeaWorkers();
        
        
    int iTargetCulturePerTurn AI_calculateTargetCulturePerTurn();
        
        
    int iAreaBestFoundValue;
        
    int iNumAreaCitySites kPlayer.AI_getNumAreaCitySites(getArea(), iAreaBestFoundValue);
        
        
    int iWaterAreaBestFoundValue 0;
        
    int iNumWaterAreaCitySites = (pWaterArea == NULL) ? kPlayer.AI_getNumAdjacentAreaCitySites(pWaterArea->getID(), getArea(), iWaterAreaBestFoundValue);
        
    int iNumSettlers kPlayer.AI_totalUnitAIs(UNITAI_SETTLE);
        
        
    bool bIsCapitalArea false;
        
    int iNumCapitalAreaCities 0;
        if (
    kPlayer.getCapitalCity() != NULL)
        {
            
    iNumCapitalAreaCities kPlayer.getCapitalCity()->area()->getCitiesPerPlayer(getOwnerINLINE());
            if (
    getArea() == kPlayer.getCapitalCity()->getArea())
            {
                
    bIsCapitalArea true;
            }
        }
            
        
    int iMaxSettlers 0;
        if (!
    bFinancialTrouble)
        {
             
    iMaxSettlersstd::min((kPlayer.getNumCities() + 1) / 2iNumAreaCitySites iNumWaterAreaCitySites);
             if (
    bLandWar || bAssault)
             {
                 
    iMaxSettlers = (iMaxSettlers 2) / 3;
             }
        }
        
        
    bool bChooseWorker false;
        
        
    int iEconomyFlags 0;
        
    iEconomyFlags |= BUILDINGFOCUS_PRODUCTION;
        
    iEconomyFlags |= BUILDINGFOCUS_GOLD;
        
    iEconomyFlags |= BUILDINGFOCUS_RESEARCH;
        
    iEconomyFlags |= BUILDINGFOCUS_MAINTENANCE;
        
    iEconomyFlags |= BUILDINGFOCUS_HAPPY;
        
    iEconomyFlags |= BUILDINGFOCUS_HEALTHY;
        if (
    AI_isEmphasizeGreatPeople())
        {
            
    iEconomyFlags |= BUILDINGFOCUS_SPECIALIST;
        }
        if (!
    GC.getGameINLINE().isOption(GAMEOPTION_NO_ESPIONAGE))
        {
            
    iEconomyFlags |= BUILDINGFOCUS_ESPIONAGE;
        }

        if (
    iNumCitiesInArea 2)
        {    
            if (
    kPlayer.AI_isDoStrategy(AI_STRATEGY_CULTURE2))
            {
                if (
    iCultureRateRank <= iCulturalVictoryNumCultureCities 1)
                {
                    
    bBigCultureCity true;

                    
    // if we do not have enough cities, then the highest culture city will not get special attention
                    
    if (iCultureRateRank || (kPlayer.getNumCities() > (iCulturalVictoryNumCultureCities 1)))
                    {
                        if ((((
    iNumAreaCitySites iNumWaterAreaCitySites) > 0) && (kPlayer.getNumCities() < 6)) && (GC.getGameINLINE().getSorenRandNum(2"AI Less Culture More Expand") == 0))
                        {
                            
    bImportantCity false;
                        }
                        else
                        {
                            
    bImportantCity true;
                        }
                    }
                }
            }
        }

        
    iProductionRank findYieldRateRank(YIELD_PRODUCTION);

        
    clearOrderQueue();

        if (
    bWasFoodProduction)
        {
            
    AI_assignWorkingPlots();
        }
        
        
        
    // if we need to pop borders, then do that immediately if we have drama and can do it
        
    if ((iTargetCulturePerTurn 0) && (getCultureLevel() <= (CultureLevelTypes1))
        {
            if (
    AI_chooseProcess(COMMERCE_CULTURE))
            {
                return;
            }
        }

        
    // if we just captured this city, dont build a unit first
        
    if (isOccupation())
        {
            
    // pick granary or lighthouse, any duration
            
    if (AI_chooseBuilding(BUILDINGFOCUS_FOOD))
            {
                return;
            }

            
    // try picking forge, etc, any duration
            
    if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION))
            {
                return;
            }
            
            
    // just pick any building, any duration
            
    if (AI_chooseBuilding())
            {
                return;
            }
        }

        if (
    plot()->getNumDefenders(getOwnerINLINE()) == 0// XXX check for other team's units?
        
    {
            if (
    AI_chooseUnit(UNITAI_CITY_DEFENSE))
            {
                return;
            }

            if (
    AI_chooseUnit(UNITAI_CITY_COUNTER))
            {
                return;
            }

            if (
    AI_chooseUnit(UNITAI_CITY_SPECIAL))
            {
                return;
            }

            if (
    AI_chooseUnit(UNITAI_ATTACK))
            {
                return;
            }
        }
        
        if (
    isBarbarian())
        {
            if (!
    AI_isDefended(plot()->plotCount(PUF_isUnitAITypeUNITAI_ATTACK, -1getOwnerINLINE()))) // XXX check for other team's units?
            
    {
                if (
    AI_chooseDefender())
                {
                    return;
                }

                if (
    AI_chooseUnit(UNITAI_ATTACK))
                {
                    return;
                }
            }
            
            if (!
    bDanger && (iNeededWorkers 0) && (AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
            {
                if (
    AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }            
            }
            
            if (!
    bDanger && (iNeededSeaWorkers 0))
            {
                if (
    AI_chooseUnit(UNITAI_WORKER_SEA))
                {
                    return;
                }
            }
            
            
    bChooseUnit false;
            if (
    GC.getGameINLINE().getSorenRandNum(100"AI Build Unit Production") > AI_buildUnitProb())
            {
                
                
    int iBarbarianFlags 0;
                
    iBarbarianFlags |= BUILDINGFOCUS_FOOD;
                
    iBarbarianFlags |= BUILDINGFOCUS_PRODUCTION;
                
    iBarbarianFlags |= BUILDINGFOCUS_EXPERIENCE;
                
                if (
    AI_chooseBuilding(iBarbarianFlags))
                {
                    return;
                }
                
                if (
    AI_chooseBuilding())
                {
                    return;
                }
            }
            
            if (
    plot()->plotCount(PUF_isUnitAITypeUNITAI_ASSAULT_SEA, -1getOwnerINLINE()) > 0)
            {
                if (
    AI_chooseUnit(UNITAI_ATTACK_CITY))
                {
                    return;
                }
            }
            
            if ((
    pWaterArea != NULL) && (iWaterPercent 30))
            {
                if (
    GC.getGameINLINE().getSorenRandNum(2"AI Coast Raiders!") == 0)
                {
                    if (
    kPlayer.AI_getNumAIUnits(UNITAI_ASSAULT_SEA) <= (kPlayer.getNumCities() / 2))
                    {
                        if (
    AI_chooseUnit(UNITAI_ASSAULT_SEA))
                        {
                            return;
                        }
                    }
                }
                if (
    GC.getGameINLINE().getSorenRandNum(110"AI arrrr!") < (iWaterPercent 10))
                {
                    if (
    kPlayer.AI_getNumAIUnits(UNITAI_PIRATE_SEA) <= kPlayer.getNumCities())
                    {
                        if (
    AI_chooseUnit(UNITAI_PIRATE_SEA))
                        {
                            return;
                        }
                    }
                    
                    if (
    kPlayer.AI_totalAreaUnitAIs(pWaterAreaUNITAI_ATTACK_SEA) < iNumCitiesInArea)
                    {
                        if (
    AI_chooseUnit(UNITAI_ATTACK_SEA))
                        {
                            return;
                        }
                    }
                }
            }
            
            if (
    AI_chooseUnit())
            {
                return;
            }
            
            return;
        }
        
        if (((
    iTargetCulturePerTurn 0) || (getPopulation() > 5)) && (getCommerceRate(COMMERCE_CULTURE) == 0))
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_CULTURE30))
            {
                return;
            }
        }
          
        if ((
    iExistingWorkers == 0) && (!bDanger) && ((AI_getWorkersNeeded() > 0) || ((isCapital() && (GC.getGame().getElapsedGameTurns() < ((30 GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100))))))
        {
            
    int iLandBonuses AI_countNumBonuses(NO_BONUS/*bIncludeOurs*/ true/*bIncludeNeutral*/ true, -1/*bLand*/ true/*bWater*/ false);
            if ((
    iLandBonuses 1) || (getPopulation() > 3))
            {
                if (!
    bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }
                
    bChooseWorker true;
            }
            if ((
    iNeededSeaWorkers 0) && (getPopulation() < 3))
            {
                if (
    AI_chooseUnit(UNITAI_WORKER_SEA))
                {
                    return;
                }
            }
            if ((
    iLandBonuses == 1) || (AI_getWorkersNeeded() > 0))
            {
                if (!
    bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }
                
    bChooseWorker true;
            }
        }
        
        
    int iPercentOfDomination 0;
        
    int iOurPopPercent 100 GET_TEAM(getTeam()).getTotalPopulation() / std::max(1GC.getGameINLINE().getTotalPopulation());
        
        for (
    int iI 0iI GC.getNumVictoryInfos(); iI++)
        {
            if (
    GC.getVictoryInfo((VictoryTypes)iI).getPopulationPercentLead() > 0)
            {
                
    iPercentOfDomination 100 iOurPopPercent std::max(1GC.getGameINLINE().getAdjustedPopulationPercent((VictoryTypes)iI));
            }
        }

        if (
    iPercentOfDomination >= 90)
        {
            if ((
    goodHealth() - badHealth(true0)) < 1)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_HEALTHY))
                {
                    return;
                }
            }
        }
            
        if (
    bDanger && kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ATTACK) < 2)
        {
            if (
    AI_chooseUnit(UNITAI_ATTACK))
            {
                return;
            }
        }
        
        if (
    bMaybeWaterArea)
        {
            if (
    kPlayer.AI_getNumTrainAIUnits(UNITAI_ATTACK_SEA) + kPlayer.AI_getNumTrainAIUnits(UNITAI_PIRATE_SEA) + kPlayer.AI_getNumTrainAIUnits(UNITAI_RESERVE_SEA) < 3)
            {
                if ((
    bMaybeWaterArea && kPlayer.AI_getWaterDanger(plot(), 4) > 0)
                    || (
    pWaterArea != NULL && bPrimaryArea && kPlayer.AI_countNumAreaHostileUnits(pWaterAreatruefalsefalsefalse) > 0))
                {
                    if (
    AI_chooseUnit(UNITAI_ATTACK_SEA))
                    {
                        return;
                    }
                    if (
    AI_chooseUnit(UNITAI_PIRATE_SEA))
                    {
                        return;
                    }
                    if (
    AI_chooseUnit(UNITAI_RESERVE_SEA))
                    {
                        return;
                    }
                }
            }
            if (
    NULL != pWaterArea)
            {
                if (
    iAreaBestFoundValue == || iWaterAreaBestFoundValue iAreaBestFoundValue
                    
    || (iWaterPercent 60 && GC.getGameINLINE().getSorenRandNum(4"AI Train Early Sea Explore or Settler") == 0))
                {
                    if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_EXPLORE_SEA) == 0)
                    {
                        if (
    AI_chooseUnit(UNITAI_EXPLORE_SEA))
                        {
                            return;
                        }
                    }
                    if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_SETTLER_SEA) == 0)
                    {
                        if (
    AI_chooseUnit(UNITAI_SETTLER_SEA))
                        {
                            return;
                        }
                    }
                }
        }
        }
        
        if ((
    getDomainFreeExperience(DOMAIN_LAND) == 0) && (getYieldRate(YIELD_PRODUCTION) > 4))
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, (kPlayer.getCurrentEra() > 1) ? 733))
            {
                return;
            }
        }
        

        
    int iPlotSettlerCount = (iNumSettlers == 0) ? plot()->plotCount(PUF_isUnitAITypeUNITAI_SETTLE, -1getOwnerINLINE());
        
    int iPlotCityDefenderCount plot()->plotCount(PUF_isUnitAITypeUNITAI_CITY_DEFENSE, -1getOwnerINLINE());
        
    //minimal defense.
        
    if (iPlotCityDefenderCount <= iPlotSettlerCount)
        {
            if (
    AI_chooseUnit(UNITAI_CITY_DEFENSE))
            {
                return;
            }
        }
        
        if (!
    bPrimaryArea)
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_FOOD6010))
            {
                return;
            }
        }
        
        if (!
    bDanger && ((kPlayer.getCurrentEra() > (GC.getGame().getStartEra() + iProductionRank 2))) || (kPlayer.getCurrentEra() > (GC.getNumEraInfos() / 2)))
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION2015))
            {
                return;    
            }
            if ((
    iExistingWorkers < ((iNeededWorkers 1) / 2)))
            {
                if (!
    bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }
                
    bChooseWorker true;
            }
        }
        
        
    bool bCrushStrategy kPlayer.AI_isDoStrategy(AI_STRATEGY_CRUSH);
        
    int iNeededFloatingDefenders = (isBarbarian() || bCrushStrategy) ?  kPlayer.AI_getTotalFloatingDefendersNeeded(pArea);
         
    int iTotalFloatingDefenders = (isBarbarian() ? kPlayer.AI_getTotalFloatingDefenders(pArea));
        
        
    UnitTypeWeightArray floatingDefenderTypes;
        
    floatingDefenderTypes.push_back(std::make_pair(UNITAI_CITY_DEFENSE125));
        
    floatingDefenderTypes.push_back(std::make_pair(UNITAI_CITY_COUNTER100));
        
    //floatingDefenderTypes.push_back(std::make_pair(UNITAI_CITY_SPECIAL, 0));
        
    floatingDefenderTypes.push_back(std::make_pair(UNITAI_RESERVE100));
        
    floatingDefenderTypes.push_back(std::make_pair(UNITAI_COLLATERAL100));
        
        if (
    iTotalFloatingDefenders < ((iNeededFloatingDefenders 1) / (bGetBetterUnits 2)))
        {
            if (
    AI_chooseLeastRepresentedUnit(floatingDefenderTypes))
            {
                return;
            }
        }

        if (!(
    iExistingWorkers == 0))
        {
            if (!
    bDanger && (iExistingWorkers < ((iNeededWorkers 1) / 2)))
            {
                if (!
    bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }
                
    bChooseWorker true;
            }
        }
        
        
    //do a check for one tile island type thing?
        //this can be overridden by "wait and grow more"
        
    if (bDanger && (iExistingWorkers == 0) && (isCapital() || (iNeededWorkers 0) || (iNeededSeaWorkers 0)))
        {
        if ((
    AI_countNumBonuses(NO_BONUS/*bIncludeOurs*/ true/*bIncludeNeutral*/ true, -1/*bLand*/ true/*bWater*/ false) > 0) || 
            (
    isCapital() && (getPopulation() > 3)))
            {
                if (!
    bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }
                
    bChooseWorker true;
            }
            if (
    iNeededSeaWorkers 0)
            {
                if (
    AI_chooseUnit(UNITAI_WORKER_SEA))
                {
                    return;
                }
            }
        }

        if (
    pWaterArea != NULL)
        {
            if (
    iNeededSeaWorkers 0)
            {
                if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_WORKER_SEA) < iNeededSeaWorkers)
                {
                    if (
    AI_chooseUnit(UNITAI_WORKER_SEA))
                    {
                        return;
                    }
                }
            }
        }

        if    (!
    bLandWar && !bAssault && (iTargetCulturePerTurn getCommerceRate(COMMERCE_CULTURE)))
        {
            if (
    GC.getGameINLINE().getSorenRandNum(bAggressiveAI 2"AI Culture Build") == 0)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_CULTUREbAggressiveAI 10 20))
                {
                    return;
                }
            }
        }
        
        
    int iMinFoundValue kPlayer.AI_getMinFoundValue();
        if (
    bDanger)
        {
            
    iMinFoundValue *= 3;
            
    iMinFoundValue /= 2;
        }
        
        if (!
    bGetBetterUnits && (bIsCapitalArea) && (iAreaBestFoundValue < (iMinFoundValue 2)))
        {
            
    //Building an early city hunting stack.
            
    int iAttackCityCount kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ATTACK);
            if (
    iAttackCityCount 0)
            {
                if (
    iAttackCityCount < (iBuildUnitProb 10))
                {
                    if (
    AI_chooseUnit(UNITAI_ATTACK))
                    {
                        return;
                    }
                }
            }
            else
            {
                
    int iStartAttackStackRand 0;
                if (
    pArea->getCitiesPerPlayer(BARBARIAN_PLAYER))
                {
                    
    iStartAttackStackRand += 15;
                }
                if ((
    pArea->getNumCities() - iNumCitiesInArea) > 0)
                {
                    
    iStartAttackStackRand += iBuildUnitProb 2;
                }

                
                if (
    GC.getGame().getSorenRandNum(100"AI start city attack stack") <= iStartAttackStackRand)
                {
                    if (
    AI_chooseUnit(UNITAI_ATTACK))
                    {
                        return;
                    }
                }
            }
        }
            
        
    //oppurunistic wonder build (1)
        
    if (!bDanger && (!hasActiveWorldWonder()) && (kPlayer.getNumCities() <= 3))
        {
            
    int iWonderTime GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
            
    iWonderTime /= 5;
            
    iWonderTime += 7;
            if (
    AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDERiWonderTime))
            {
                return;
            }
        }
        
        if (!
    bDanger && !bIsCapitalArea && area()->getCitiesPerPlayer(getOwnerINLINE()) > iNumCapitalAreaCities)
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_CAPITAL15))
            {
                return;
            }
        }
        
        if (
    AI_chooseBuilding(BUILDINGFOCUS_FOODisCapital() ? 3030))
        {
            return;
        }
        

        
    int iSpreadUnitThreshold 1000;
        
    iSpreadUnitThreshold += bLandWar 1000 0;
        
        
    UnitTypes eBestSpreadUnit NO_UNIT;
        
    int iBestSpreadUnitValue = -1;
        
        {
            
    int iSpreadUnitRoll = (100 iBuildUnitProb) / 3;
            
    iSpreadUnitRoll += bLandWar 10;
            
            if (
    AI_bestSpreadUnit(truetrueiSpreadUnitRoll, &eBestSpreadUnit, &iBestSpreadUnitValue))
            {
                if (
    iBestSpreadUnitValue iSpreadUnitThreshold)
                {
                    if (
    AI_chooseUnit(eBestSpreadUnitUNITAI_MISSIONARY))
                    {
                        return;
                    }
                    
    FAssertMsg(false"AI_bestSpreadUnit should provide a valid unit when it returns true");
                }
            }
        }
        
        if (!
    bDanger && (iProductionRank <= ((kPlayer.getNumCities() / 5) + 1)))
        {
            if (
    AI_chooseProject())
            {
                return;
            }
        }
        
        
    //minimal defense.
        
    if (plot()->plotCount(PUF_isUnitAITypeUNITAI_CITY_DEFENSE, -1getOwnerINLINE()) < (AI_minDefenders() + iPlotSettlerCount))
        {
            if (
    AI_chooseUnit(UNITAI_CITY_DEFENSE))
            {
                return;
            }
        }
        
        
        if ((
    iAreaBestFoundValue iMinFoundValue) || (iWaterAreaBestFoundValue iMinFoundValue))
        {        
            if (
    pWaterArea != NULL)
            {
                
    int iTotalCities kPlayer.getNumCities();
                
    int iSettlerSeaNeeded std::min(iNumWaterAreaCitySites, ((iTotalCities 4) / 8) + 1);
                if (
    kPlayer.getCapitalCity() != NULL)
                {
                    
    int iOverSeasColonies iTotalCities kPlayer.getCapitalCity()->area()->getCitiesPerPlayer(getOwnerINLINE());;
                    
    int iLoop 2;
                    
    int iExtras 0;
                    while (
    iOverSeasColonies >= iLoop)
                    {
                        
    iExtras++;
                        
    iLoop += iLoop 2;
                    }
                    
    iSettlerSeaNeeded += std::min(kPlayer.AI_totalUnitAIs(UNITAI_WORKER) / 4iExtras);
                }
                if (
    bAssault)
                {
                    
    iSettlerSeaNeeded std::min(1iSettlerSeaNeeded);
                }
                
                if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_SETTLER_SEA) < iSettlerSeaNeeded)
                {
                    if (
    AI_chooseUnit(UNITAI_SETTLER_SEA))
                    {
                        return;
                    }
                }
            }
            
            if (
    iPlotSettlerCount == 0)
            {
                if ((
    iNumSettlers iMaxSettlers) && (!bLandWar || (GC.getGameINLINE().getSorenRandNum(2"AI War Settler") == 0)))
                {
                    if (
    iPlotCityDefenderCount == 1)
                    {
                        if (
    AI_chooseUnit(UNITAI_CITY_DEFENSE))
                        {
                            return;
                        }
                    }
                    else if (
    AI_chooseUnit(UNITAI_SETTLE))
                    {
                        return;
                    }
                }
            }
        }
        
        
    //this is needed to build the cathedrals quickly
        //also very good for giving cultural cities first dibs on wonders
        
    if (bImportantCity && (iCultureRateRank <= iCulturalVictoryNumCultureCities))
        {
            if (
    iCultureRateRank == iCulturalVictoryNumCultureCities)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_BIGCULTURE BUILDINGFOCUS_CULTURE BUILDINGFOCUS_WONDEROK40))
                {
                    return;
                }
            }
            
            else if (
    GC.getGameINLINE().getSorenRandNum(((iCultureRateRank == 1) ? 1) + iCulturalVictoryNumCultureCities "AI Build up Culture") < iCultureRateRank)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_BIGCULTURE BUILDINGFOCUS_CULTURE BUILDINGFOCUS_WONDEROK40))
                {
                    return;
                }
            }
        }

        
    // don't build frivolous things if this is an important city unless we at war
        
    if (!bImportantCity || bLandWar || bAssault)
        {
            if (
    bPrimaryArea)
            {
                if (
    kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ATTACK) == 0)
                {
                    if (
    AI_chooseUnit(UNITAI_ATTACK))
                    {
                        return;
                    }
                }
            }

            if (!
    bLandWar && !bDanger)
            {
                if (
    kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_EXPLORE) < (kPlayer.AI_neededExplorers(pArea)))
                {
                    if (
    AI_chooseUnit(UNITAI_EXPLORE))
                    {
                        return;
                    }
                }
            }
            
            if (
    bDefenseWar)
            {
                if (
    GC.getGameINLINE().getSorenRandNum(100"AI Train Defensive Unit (Panic)") > (bGetBetterUnits 60 40))
                {
                    
    UnitTypeWeightArray panicDefenderTypes;
                    
    panicDefenderTypes.push_back(std::make_pair(UNITAI_RESERVE100));
                    
    panicDefenderTypes.push_back(std::make_pair(UNITAI_COUNTER100));
                    
    panicDefenderTypes.push_back(std::make_pair(UNITAI_COLLATERAL100));
                    
    panicDefenderTypes.push_back(std::make_pair(UNITAI_ATTACK100));
                    if (
    AI_chooseLeastRepresentedUnit(panicDefenderTypes))
                    {
                        return;
                    }
                }
            }
        }
            
        if (
    AI_chooseBuilding(BUILDINGFOCUS_FOOD6010))
        {
            return;
        }
        
        
    //oppurunistic wonder build
        
    if (!bDanger && (!hasActiveWorldWonder() || (kPlayer.getNumCities() > 3)))
        {
            
    int iWonderTime GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
            
    iWonderTime /= 5;
            
    iWonderTime += 8;
            if (
    AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDERiWonderTime))
            {
                return;
            }
        }
        
        if (
    iNeededWorkers iExistingWorkers)
        {
            if ((
    AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
            {
                if (!
    bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
                {
                    return;
                }
                
    bChooseWorker true;
            }
        }
        
        
    //essential economic builds
        
    if (AI_chooseBuilding(iEconomyFlags1025))
        {
            return;
        }
        
        if (
    iBestSpreadUnitValue > ((iSpreadUnitThreshold 60) / 100))
        {
            if (
    AI_chooseUnit(eBestSpreadUnitUNITAI_MISSIONARY))
            {
                return;
            }
            
    FAssertMsg(false"AI_bestSpreadUnit should provide a valid unit when it returns true");
        }
        
        
    int iMaxUnitSpending = (bAggressiveAI 3) + iBuildUnitProb 3;
        if (
    bAlwaysPeace)
        {
            
    iMaxUnitSpending = -10;
        }
        else if (
    kPlayer.AI_isDoStrategy(AI_STRATEGY_FINAL_WAR))
        {
            
    iMaxUnitSpending iMaxUnitSpending + (100 iMaxUnitSpending) / 2;
        }
        else
        {
            
    iMaxUnitSpending += bDefenseWar 0;
            switch (
    pArea->getAreaAIType(getTeam()))
            {
                case 
    AREAAI_OFFENSIVE:
                    
    iMaxUnitSpending += 5;
                    break;
                
                case 
    AREAAI_DEFENSIVE:
                    
    iMaxUnitSpending += 10;
                    break;
                
                case 
    AREAAI_MASSING:
                    
    iMaxUnitSpending += 25;
                    break;
                
                case 
    AREAAI_ASSAULT:
                    
    iMaxUnitSpending += 8;
                    break;
                    
                case 
    AREAAI_ASSAULT_MASSING:
                    
    iMaxUnitSpending += 16;
                    break;
                
                case 
    AREAAI_ASSAULT_ASSIST:
                    
    iMaxUnitSpending += 6;
                    break;
                
                case 
    AREAAI_NEUTRAL:
                    break;
                default:
                    
    FAssert(false);
            }
        }
        
        if (
    iUnitCostPercentage < (iMaxUnitSpending 10))
        {
            
    int iBestSeaAssaultCapacity 0;
            if (
    NULL != pWaterArea && (bAssault))
            {
                
    UnitTypes eBestAssaultUnit NO_UNIT;  
                
    kPlayer.AI_bestCityUnitAIValue(UNITAI_ASSAULT_SEAthis, &eBestAssaultUnit);
                if (
    eBestAssaultUnit != NO_UNIT)
                {
                    
    iBestSeaAssaultCapacity GC.getUnitInfo(eBestAssaultUnit).getCargoSpace();
                }
                
                
    int iUnitsToTransport kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ATTACK_CITY);
                
    iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ATTACK);
                
    iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_COUNTER);
                
                
    int iTransports kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ASSAULT_SEA);
                
    iTransports += kPlayer.AI_totalAreaUnitAIs(pWaterAreaUNITAI_ASSAULT_SEA);
                
                
    int iEscorts kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ESCORT_SEA);
                
    iEscorts += kPlayer.AI_totalAreaUnitAIs(pWaterAreaUNITAI_ESCORT_SEA);
                
                
    //The way of calculating numbers is a bit fuzzy since the ships
                //can make return trips. When massing for a war it'll train enough
                //ships to move it's entire army. Once the war is underway it'll stop
                //training so many ships on the assumption that those out at sea
                //will return...
                
                
    if ((iEscorts < ((iTransports) / 3)) && (GC.getGame().getSorenRandNum(2"AI train escort sea") == 0))
                {
                    if (
    AI_chooseUnit(UNITAI_ESCORT_SEA))
                    {
                        
    AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA);
                        return;
                    }
                }
                
                
    UnitTypes eBestAttackSeaUnit NO_UNIT;  
                
    kPlayer.AI_bestCityUnitAIValue(UNITAI_ATTACK_SEAthis, &eBestAttackSeaUnit);
                if (
    eBestAttackSeaUnit != NO_UNIT)
                {
                    if (
    GC.getUnitInfo(eBestAttackSeaUnit).getBombardRate() > 0)
                    {
                        
    int iAttackSea kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_ATTACK_SEA);
                        
    iAttackSea += kPlayer.AI_totalAreaUnitAIs(pWaterAreaUNITAI_ATTACK_SEA);
                            
                        if ((
    iAttackSea < ((iTransports) / 2)) && (GC.getGame().getSorenRandNum(2"AI train attack sea") == 0))
                        {
                            if (
    AI_chooseUnit(UNITAI_ATTACK_SEA))
                            {
                                
    AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA);
                                return;
                            }
                        }
                    }
                }
                
                if (
    iUnitsToTransport > (iTransports iBestSeaAssaultCapacity))
                {
                    if (
    AI_chooseUnit(UNITAI_ASSAULT_SEA))
                    {
                        
    AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA);
                        return;
                    }
                }
                
                
    int iCarriers kPlayer.AI_totalUnitAIs(UNITAI_CARRIER_SEA);
                
                if (
    iCarriers 0)
                {
                    
    UnitTypes eBestCarrierUnit NO_UNIT;  
                    
    kPlayer.AI_bestCityUnitAIValue(UNITAI_CARRIER_SEAthis, &eBestCarrierUnit);
                    if (
    eBestCarrierUnit != NO_UNIT)
                    {
                        
    FAssert(GC.getUnitInfo(eBestCarrierUnit).getDomainCargo() == DOMAIN_AIR);
                        
                        
    int iCarrierAirNeeded iCarriers GC.getUnitInfo(eBestCarrierUnit).getCargoSpace();
                        
                        if (
    kPlayer.AI_totalUnitAIs(UNITAI_CARRIER_AIR) < iCarrierAirNeeded)
                        {
                            if (
    AI_chooseUnit(UNITAI_CARRIER_AIR))
                            {
                                return;
                            }
                        }
                    }
                }
                
                if (
    iCarriers < (kPlayer.AI_totalUnitAIs(UNITAI_ASSAULT_SEA) / 4))
                {
                    if (
    AI_chooseUnit(UNITAI_CARRIER_SEA))
                    {
                        return;
                    }
                }
                
                
    int iMissileCarriers kPlayer.AI_totalUnitAIs(UNITAI_MISSILE_CARRIER_SEA);
                
                if (
    iMissileCarriers 0)
                {
                    
    UnitTypes eBestMissileCarrierUnit NO_UNIT;  
                    
    kPlayer.AI_bestCityUnitAIValue(UNITAI_MISSILE_CARRIER_SEAthis, &eBestMissileCarrierUnit);
                    if (
    eBestMissileCarrierUnit != NO_UNIT)
                    {
                        
    FAssert(GC.getUnitInfo(eBestMissileCarrierUnit).getDomainCargo() == DOMAIN_AIR);
                        
                        
    int iMissileCarrierAirNeeded iMissileCarriers GC.getUnitInfo(eBestMissileCarrierUnit).getCargoSpace();
                        
                        if ((
    kPlayer.AI_totalUnitAIs(UNITAI_MISSILE_AIR) < iMissileCarrierAirNeeded) || 
                            (
    bPrimaryArea && (kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_MISSILE_CARRIER_SEA) * GC.getUnitInfo(eBestMissileCarrierUnit).getCargoSpace() < kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_MISSILE_AIR))))
                        {
                            if (
    AI_chooseUnit(UNITAI_MISSILE_AIR))
                            {
                                return;
                            }
                        }
                    }
                }
            }
        }
        
        
    UnitTypeWeightArray airUnitTypes;

        
    int iAircraftNeed 0;
        
    int iAircraftHave 0;
        
    UnitTypes eBestAttackAircraft NO_UNIT;
        
    UnitTypes eBestMissile NO_UNIT;
        
        if (
    iUnitCostPercentage < (iMaxUnitSpending 4))
        {
            
    int iBestAirValue kPlayer.AI_bestCityUnitAIValue(UNITAI_ATTACK_AIRthis, &eBestAttackAircraft);
            
    int iBestMissileValue kPlayer.AI_bestCityUnitAIValue(UNITAI_MISSILE_AIRthis, &eBestMissile);
            if ((
    iBestAirValue iBestMissileValue) > 0)
            {
                
    iAircraftHave kPlayer.AI_getNumAIUnits(UNITAI_ATTACK_AIR) + kPlayer.AI_getNumAIUnits(UNITAI_DEFENSE_AIR) + kPlayer.AI_getNumAIUnits(UNITAI_MISSILE_AIR);
                if (
    NO_UNIT != eBestAttackAircraft)
                {
                    
    iAircraftNeed = (kPlayer.getNumCities() * (GC.getUnitInfo(eBestAttackAircraft).getAirCombat())) / (std::max(1GC.getGame().getBestLandUnitCombat()));
                    
    int iBestDefenseValue kPlayer.AI_bestCityUnitAIValue(UNITAI_DEFENSE_AIRthis);
                    if ((
    iBestDefenseValue 0) && (iBestAirValue iBestDefenseValue))
                    {
                        
    iAircraftNeed *= 3;
                        
    iAircraftNeed /= 2;
                    }
                }
                if (
    iBestMissileValue 0)
                {
                    
    iAircraftNeed std::max(iAircraftNeedkPlayer.getNumCities() / 2);
                }
                
                
    bool bAirBlitz kPlayer.AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ);
                
    bool bLandBlitz kPlayer.AI_isDoStrategy(AI_STRATEGY_LAND_BLITZ);
                if (
    bAirBlitz)
                {
                    
    iAircraftNeed *= 3;
                    
    iAircraftNeed /= 2;
                }
                else if (
    bLandBlitz)
                {
                    
    iAircraftNeed /= 2;
                    
    iAircraftNeed += 1;
                }
                
                
    airUnitTypes.push_back(std::make_pair(UNITAI_ATTACK_AIRbAirBlitz 125 80));
                
    airUnitTypes.push_back(std::make_pair(UNITAI_DEFENSE_AIRbLandBlitz 100 100));
                if (
    iBestMissileValue 0)
                {
                    
    airUnitTypes.push_back(std::make_pair(UNITAI_MISSILE_AIR50));
                }
                
                
    airUnitTypes.push_back(std::make_pair(UNITAI_ICBM20));
                
                if (
    iAircraftHave iAircraftNeed)
                {
                    if (
    AI_chooseLeastRepresentedUnit(airUnitTypes))
                    {
                        return;
                    }
                }
            }
        }
        
        if (!
    bAlwaysPeace && !(bLandWar || bAssault) && (kPlayer.AI_isDoStrategy(AI_STRATEGY_OWABWNW) || (GC.getGame().getSorenRandNum(12"AI consider Nuke") == 0)))
        {
            
    int iTotalNukes kPlayer.AI_totalUnitAIs(UNITAI_ICBM);
            
    int iNukesWanted std::min(kPlayer.getNumCities(), GC.getGame().getNumCities() - kPlayer.getNumCities());
            if ((
    iTotalNukes iNukesWanted) && (GC.getGame().getSorenRandNum(100"AI train nuke MWAHAHAH") < (90 - (80 iTotalNukes) / iNukesWanted)))
            {
                if ((
    pWaterArea != NULL) && (GC.getGame().getSorenRandNum(4"AI train nuke carrier")))
                {
                    if (
    AI_chooseUnit(UNITAI_MISSILE_CARRIER_SEA))
                    {
                        return;    
                    }
                }
                if (
    AI_chooseUnit(UNITAI_ICBM))
                {
                    return;
                }
            }
        }
        
        if ((!
    bImportantCity || bDefenseWar) && (iUnitCostPercentage iMaxUnitSpending))
        {
            if (!
    bFinancialTrouble && !bGetBetterUnits && (bLandWar || ((bAssault || kPlayer.AI_isDoStrategy(AI_STRATEGY_DAGGER)) && !bAssaultAssist)))
            {
                
    int iTrainInvaderChance iBuildUnitProb 10;
                if (
    bAggressiveAI)
                {
                    
    iTrainInvaderChance += 15;
                }
                if ((
    pArea->getAreaAIType(getTeam()) == AREAAI_MASSING) || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_MASSING))
                {
                    
    iTrainInvaderChance = (100 - ((100 iTrainInvaderChance) / (bCrushStrategy 3)));
                }            
                
                if (
    GC.getGameINLINE().getSorenRandNum(100"AI Dagger Offense Unit") < iTrainInvaderChance )
                {
                    {
                        if (
    AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE20))
                        {
                            return;
                        }

                        
    UnitTypeWeightArray invaderTypes;
                        
    invaderTypes.push_back(std::make_pair(UNITAI_ATTACK_CITY100));
                        
    invaderTypes.push_back(std::make_pair(UNITAI_COUNTER50));
                        
    invaderTypes.push_back(std::make_pair(UNITAI_ATTACK40));
                        
    invaderTypes.push_back(std::make_pair(UNITAI_PARADROP, (kPlayer.AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ) ? 30 20) / (bAssault 1)));
                        if (!
    bAssault)
                        {
                            if (
    kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_PILLAGE) <= ((iNumCitiesInArea 1) / 2))
                            {
                                
    invaderTypes.push_back(std::make_pair(UNITAI_PILLAGE30));
                            }
                        }

                        if (
    AI_chooseLeastRepresentedUnit(invaderTypes))
                        {
                            return;
                        }
                    }
                }
            }
        }
        
        
    //Arr.
        
    if ((pWaterArea != NULL) && !bLandWar && !bAssault)
        {
            
    int iPirateCount kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_PIRATE_SEA);
            
    int iNeededPirates = (+ (pWaterArea->getNumTiles() / std::max(1200 iBuildUnitProb)));
            
    iNeededPirates *= (20 iWaterPercent);
            
    iNeededPirates /= 100;
            
            if (
    kPlayer.isNoForeignTrade())
            {
                
    iNeededPirates *= 3;
                
    iNeededPirates /= 2;
            }
            if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_PIRATE_SEA) < iNeededPirates)
            {
                if (
    kPlayer.AI_calculateUnitAIViability(UNITAI_PIRATE_SEADOMAIN_SEA) > 49)
                {
                    if (
    GC.getGameINLINE().getSorenRandNum(100"AI train pirate") < (iWaterPercent / (iPirateCount)))
                    {
                        if (
    AI_chooseUnit(UNITAI_PIRATE_SEA))
                        {
                            return;
                        }
                    }
                }
            }
        }
        
        if (!
    bLandWar)
        {
            if ((
    pWaterArea != NULL) && (iWaterPercent 40))
            {
                if (
    kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_SPY) > 0)
                {
                    if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_SPY_SEA) == 0)
                    {
                        if (
    AI_chooseUnit(UNITAI_SPY_SEA))
                        {
                            return;
                        }
                    }
                }
            }
        }
        
        if (
    iBestSpreadUnitValue > ((iSpreadUnitThreshold 40) / 100))
        {
            if (
    AI_chooseUnit(eBestSpreadUnitUNITAI_MISSIONARY))
            {
                return;
            }
            
    FAssertMsg(false"AI_bestSpreadUnit should provide a valid unit when it returns true");
        }
            
        if (
    iTotalFloatingDefenders iNeededFloatingDefenders)
        {
            if (
    GC.getGameINLINE().getSorenRandNum(100"AI Build Floating Defender") < 50)
            {
                if (
    AI_chooseLeastRepresentedUnit(floatingDefenderTypes))
                {
                    return;
                }
            }
        }
        
        
    int iNumSpies = (kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_SPY));
        
    int iNeededSpies iNumCitiesInArea 3;
        
    iNeededSpies += isCapital() ? 0;
        if (
    iNumSpies iNeededSpies)
        {
            if (
    GC.getGameINLINE().getSorenRandNum(100"AI Train Spy") < 50 / (iNumSpies))
            {
                if (
    AI_chooseUnit(UNITAI_SPY))
                {
                    return;
                }
            }
        }
        
        if (
    bLandWar)
        {
            if (
    iNumSettlers iMaxSettlers)
            {
                if (!
    bFinancialTrouble)
                {
                    if (
    iAreaBestFoundValue iMinFoundValue)
                    {
                        if (
    AI_chooseUnit(UNITAI_SETTLE))
                        {
                            return;
                        }
                    }
                }
            }
        }
        
        if ((
    iProductionRank <= ((kPlayer.getNumCities() > 8) ? 2))
            && (
    getPopulation() > 3))
        {
            
    int iWonderRand GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
            
            
    // increase chance of going for an early wonder
            
    if (GC.getGameINLINE().getElapsedGameTurns() < (100 GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getConstructPercent() / 100) && iNumCitiesInArea 1)
            {
                
    iWonderRand *= 35;
                
    iWonderRand /= 100;
            }
            else if (
    iNumCitiesInArea >= 3)
            {
                
    iWonderRand *= 30;
                
    iWonderRand /= 100;
            }
            else
            {
                
    iWonderRand *= 25;
                
    iWonderRand /= 100;
            }
            
            if (
    bAggressiveAI)
            {
                
    iWonderRand *= 2;
                
    iWonderRand /= 3;
            }
            
            
    int iWonderRoll GC.getGameINLINE().getSorenRandNum(100"Wonder Build Rand");
            
            if (
    iProductionRank == 1)
            {
                
    iWonderRoll /= 2;
            }
            
            if (
    iWonderRoll iWonderRand)
            {
                
    int iWonderMaxTurns 20 + ((iWonderRand iWonderRoll) * 2);
                if (
    bLandWar)
                {
                    
    iWonderMaxTurns /= 2;
                }
                
                if (
    AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDERiWonderMaxTurns))
                {
                   return;
                }
            }
        }
        
        if (
    iUnitCostPercentage iMaxUnitSpending 4)
        {
            if ((
    iAircraftHave >= iAircraftNeed) && (iAircraftHave iAircraftNeed))
            {
                if (
    AI_chooseLeastRepresentedUnit(airUnitTypes))
                {
                    return;
                }
            }
        }

        if (!
    bLandWar)
        {        
            if ((
    iCulturePressure 90) || kPlayer.AI_isDoStrategy(AI_STRATEGY_CULTURE2))
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_CULTURE20))
                {
                    return;
                }
            }

            if (
    pWaterArea != NULL)
            {
                if (
    kPlayer.AI_totalAreaUnitAIs(pAreaUNITAI_MISSIONARY) > 0)
                {
                    if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_MISSIONARY_SEA) == 0)
                    {
                        if (
    AI_chooseUnit(UNITAI_MISSIONARY_SEA))
                        {
                            return;
                        }
                    }
                }
            }
        }


        if (
    getCommerceRateTimes100(COMMERCE_CULTURE) == 0)
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_CULTURE30))
            {
                return;
            }
        }

    //    if (getPopulation() > 6)
    //    {
    //        if (!AI_isAirDefended())
    //        {
    //            if (AI_chooseUnit(UNITAI_DEFENSE_AIR))
    //            {
    //                return;
    //            }
    //        }
    //    }

        
    if (!bAlwaysPeace && (bDanger || (GC.getGameINLINE().getSorenRandNum(30"AI Build Defense") < getPopulation())))
        {
            if (!
    bDanger)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE20))
                {
                    return;
                }
            }

            if (
    AI_chooseBuilding(BUILDINGFOCUS_DEFENSE20))
            {
                return;
            }
            
            if (
    bDanger)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE20))
                {
                    return;
                }
            }
        }

        if (
    AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION204))
        {
            return;
        }
        
        
    //20 means 5g or ~2 happiness...
        
    if (AI_chooseBuilding(iEconomyFlags1520))
        {
            return;
        }


        if (!
    bLandWar)
        {
            if (
    AI_chooseBuilding(iEconomyFlags408))
            {
                return;
            }

            if (
    iCulturePressure 50)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_CULTURE60))
                {
                    return;
                }
            }

            if (
    pWaterArea != NULL)
            {
                if (
    bPrimaryArea)
                {
                    if (
    kPlayer.AI_totalWaterAreaUnitAIs(pWaterAreaUNITAI_EXPLORE_SEA) < std::min(1kPlayer.AI_neededExplorers(pWaterArea)))
                    {
                        if (
    AI_chooseUnit(UNITAI_EXPLORE_SEA))
                        {
                            return;
                        }
                    }
                }
            }

            if (
    getBaseYieldRate(YIELD_PRODUCTION) >= 8)
            {
                if (
    AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION80))
                {
                    return;
                }
            }
        }

        if (
    plot()->plotCheck(PUF_isUnitAITypeUNITAI_CITY_COUNTER, -1getOwnerINLINE()) == NULL)
        {
            if (
    AI_chooseUnit(UNITAI_CITY_COUNTER))
            {
                return;
            }
        }

        
    // we do a similar check lower, in the landwar case
        
    if (!bLandWar && bFinancialTrouble)
        {
            if (
    AI_chooseBuilding(BUILDINGFOCUS_GOLD))
            {
                return;
            }
        }

        
    bChooseUnit false;
        if (
    iUnitCostPercentage iMaxUnitSpending 5)
        {
            if ((
    bLandWar) ||
                  ((
    kPlayer.getNumCities() <= 3) && (GC.getGameINLINE().getElapsedGameTurns() < 60)) ||
                  (
    GC.getGameINLINE().getSorenRandNum(100"AI Build Unit Production") < AI_buildUnitProb()) ||
                    (
    isHuman() && (getGameTurnFounded() == GC.getGameINLINE().getGameTurn())))
            {
                if (
    AI_chooseUnit())
                {
                    return;
                }

                
    bChooseUnit true;
            }
        }

        if (
    AI_chooseProject())
        {
            return;
        }

        if (
    AI_chooseBuilding())
        {
            return;
        }
        
        if (!
    bChooseUnit && !bFinancialTrouble && kPlayer.AI_isDoStrategy(AI_STRATEGY_FINAL_WAR))
        {
            if (
    AI_chooseUnit())
            {
                return;
            }
        }        

        if (
    AI_chooseProcess())
        {
            return;
        }

    Der erste Funktionsaufruf AI_isDanger() bedeutet

    PHP-Code:
    bool CvCityAI::AI_isDanger()
    {
        return 
    GET_PLAYER(getOwnerINLINE()).AI_getPlotDanger(plot(), 2false);

    was im Umkreis von 2 Plots nach feindlichen Einheiten sucht

    PHP-Code:
    int CvPlayerAI::AI_getPlotDanger(CvPlotpPlotint iRangebool bTestMoves) const
    {
        
    PROFILE_FUNC();

        
    CLLNode<IDInfo>* pUnitNode;
        
    CvUnitpLoopUnit;
        
    CvPlotpLoopPlot;
        
    int iCount;
        
    int iDistance;
        
    int iBorderDanger;
        
    int iDXiDY;
        
    CvArea *pPlotArea pPlot->area();

        
    iCount 0;
        
    iBorderDanger 0;

        if (
    iRange == -1)
        {
            
    iRange DANGER_RANGE;
        }

        for (
    iDX = -(iRange); iDX <= iRangeiDX++)
        {
            for (
    iDY = -(iRange); iDY <= iRangeiDY++)
            {
                
    pLoopPlot    plotXY(pPlot->getX_INLINE(), pPlot->getY_INLINE(), iDXiDY);

                if (
    pLoopPlot != NULL)
                {
                    if (
    pLoopPlot->area() == pPlotArea)
                    {
                        
    iDistance stepDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE());
                        if (
    atWar(pLoopPlot->getTeam(), getTeam()))
                        {
                            if (
    iDistance == 1)
                            {
                                
    iBorderDanger++;
                            }
                            else if ((
    iDistance == 2) && (pLoopPlot->isRoute()))
                            {
                                
    iBorderDanger++;
                            }
                        }


                        
    pUnitNode pLoopPlot->headUnitNode();

                        while (
    pUnitNode != NULL)
                        {
                            
    pLoopUnit = ::getUnit(pUnitNode->m_data);
                            
    pUnitNode pLoopPlot->nextUnitNode(pUnitNode);

                            if (
    pLoopUnit->isEnemy(getTeam()))
                            {
                                if (
    pLoopUnit->canAttack())
                                {
                                    if (!(
    pLoopUnit->isInvisible(getTeam(), false)))
                                    {
                                        if (
    pLoopUnit->canMoveOrAttackInto(pPlot))
                                        {
                                            if (!
    bTestMoves)
                                            {
                                                
    iCount++;
                                            }
                                            else
                                            {
                                                
    int iDangerRange pLoopUnit->baseMoves();
                                                
    iDangerRange += ((pLoopPlot->isValidRoute(pLoopUnit)) ? 0);
                                                if (
    iDangerRange >= iDistance)
                                                {
                                                    
    iCount++;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        if (
    iBorderDanger 0)
        {
            if (!
    isHuman() && !pPlot->isCity())
            {
                
    iCount += iBorderDanger;
            }
        }

        return 
    iCount;


  14. #29
    Registrierter Benutzer
    Registriert seit
    25.05.06
    Beiträge
    430
    Flunky, in der Tat hast du was wirklich konkretes gepostet. Du Flunky, wärst DU in der Lage diesen Code zu verstehen, um aus diesem eine funktionierende KI zu programmieren?

    PS: Gibt es einen User hier im Forum, der diesen Code absolut versteht

  15. #30
    Danke für den Kommentar.
    Registriert seit
    02.01.19
    Ort
    Hamburg.
    Beiträge
    9.086
    Bestimmt. Poste ihn sammt Frage im Programmiererstammtisch.
    Ich bin keine Signatur, ich fälsche nur die Geldscheine.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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