~ubuntu-branches/ubuntu/natty/spring/natty

« back to all changes in this revision

Viewing changes to AI/Skirmish/E323AI/CIntel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Ritchie
  • Date: 2010-09-23 18:56:03 UTC
  • mfrom: (3.1.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100923185603-st97s5chplo42y7w
Tags: 0.82.5.1+dfsg1-1ubuntu1
* Latest upstream version for online play
* debian/control: Replace (rather than conflict) spring-engine
  - spring-engine will be a dummy package (LP: #612905)
  - also set maintainer to MOTU

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#include "CAI.h"
4
4
#include "CUnitTable.h"
5
5
#include "CUnit.h"
6
 
#include "CMilitary.h"
 
6
#include "GameMap.hpp"
 
7
#include <ctime>
7
8
 
8
9
CIntel::CIntel(AIClasses *ai) {
9
10
        this->ai = ai;
16
17
        selector.push_back(ARTILLERY);
17
18
        selector.push_back(ANTIAIR);
18
19
        selector.push_back(AIR);
 
20
        
19
21
        for (size_t i = 0; i < selector.size(); i++)
20
22
                counts[selector[i]] = 1;
21
 
        numUnits = 1;
 
23
        
 
24
        enemyvector = float3(1.0f, 1.0f, 1.0f);
 
25
        
 
26
        targets[ENGAGE].push_back(&commanders);
 
27
        targets[ENGAGE].push_back(&attackers);
 
28
        targets[ENGAGE].push_back(&energyMakers);
 
29
        targets[ENGAGE].push_back(&metalMakers);
 
30
        targets[ENGAGE].push_back(&defenseAntiAir);
 
31
        targets[ENGAGE].push_back(&defenseGround);
 
32
        targets[ENGAGE].push_back(&mobileBuilders);
 
33
        targets[ENGAGE].push_back(&factories);
 
34
        targets[ENGAGE].push_back(&restUnarmedUnits);
 
35
        
 
36
        targets[SCOUT].push_back(&mobileBuilders);
 
37
        targets[SCOUT].push_back(&metalMakers);
 
38
        targets[SCOUT].push_back(&energyMakers);
 
39
        targets[SCOUT].push_back(&restUnarmedUnits);
 
40
 
 
41
        targets[BOMBER].push_back(&defenseAntiAir);
 
42
        targets[BOMBER].push_back(&defenseGround);
 
43
        targets[BOMBER].push_back(&commanders);
 
44
        targets[BOMBER].push_back(&factories);
 
45
        targets[BOMBER].push_back(&energyMakers);
 
46
        targets[BOMBER].push_back(&metalMakers);
 
47
        
 
48
        initialized = false;
 
49
        strategyTechUp = false;
22
50
}
23
51
 
24
52
float3 CIntel::getEnemyVector() {
26
54
}
27
55
 
28
56
void CIntel::init() {
29
 
        numUnits = ai->cbc->GetEnemyUnits(units, MAX_UNITS);
30
 
        assert(numUnits > 0);
31
 
        enemyvector = float3(0.0f, 0.0f, 0.0f);
32
 
        for (int i = 0; i < numUnits; i++) {
33
 
                enemyvector += ai->cbc->GetUnitPos(units[i]);
34
 
        }
35
 
        enemyvector /= numUnits;
36
 
        LOG_II("Number of enemies: " << numUnits)
 
57
        if (initialized) return;
 
58
        
 
59
        int numUnits = ai->cbc->GetEnemyUnits(units, MAX_UNITS);
 
60
        // FIXME: when commanders are spawned with wrap gate option enabled then assert raises
 
61
        if (numUnits > 0) {
 
62
                enemyvector = ZeroVector;
 
63
                for (int i = 0; i < numUnits; i++) {
 
64
                        enemyvector += ai->cbc->GetUnitPos(units[i]);
 
65
                }
 
66
                enemyvector /= numUnits;
 
67
        }
 
68
 
 
69
        LOG_II("CIntel::init Number of enemy units: " << numUnits)
 
70
        
 
71
        /* FIXME:
 
72
                I faced situation that on maps with less land there is a direct
 
73
                path to enemy unit, but algo below starts to play a non-land game. 
 
74
                I could not think up an apporpiate algo to avoid this. I though tracing
 
75
                a path in the beginning of the game from my commander to enemy would 
 
76
                be ok, but commander is an amphibious unit. It is not trivial stuff 
 
77
                without external helpers in config files.
 
78
        */
 
79
        if(ai->gamemap->IsWaterMap()) {
 
80
                allowedFactories.push_back(NAVAL);
 
81
                allowedFactories.push_back(HOVER);
 
82
        } 
 
83
        else {
 
84
                unitCategory nextFactory;
 
85
                if (ai->gamemap->IsKbotMap()) {
 
86
                        allowedFactories.push_back(KBOT);
 
87
                        nextFactory = VEHICLE;
 
88
                } 
 
89
                else {
 
90
                        allowedFactories.push_back(VEHICLE);
 
91
                        nextFactory = KBOT;
 
92
                }
 
93
                
 
94
                if (ai->gamemap->IsHooverMap()) {
 
95
                        if (ai->gamemap->GetAmountOfWater() > 0.5) {
 
96
                                allowedFactories.push_back(HOVER);
 
97
                        }
 
98
                        else {
 
99
                                allowedFactories.push_back(nextFactory);
 
100
                                nextFactory = HOVER;
 
101
                        }
 
102
                }
 
103
                
 
104
                allowedFactories.push_back(nextFactory);
 
105
        }
 
106
        // TODO: do not build air on too small maps?
 
107
        allowedFactories.push_back(AIRCRAFT);
 
108
 
 
109
        // vary first factory among allied AIs...
 
110
        int i = ai->allyAITeam;
 
111
        while (i > 1) {
 
112
                allowedFactories.push_back(allowedFactories.front());
 
113
                allowedFactories.pop_front();
 
114
                i--;
 
115
        }
 
116
        
 
117
        // FIXME: engineer better decision algo
 
118
        if (ai->gamemap->IsMetalMap())
 
119
                strategyTechUp = true;
 
120
        else
 
121
                // NOTE: clock() gives much better results than rng.RndFloat() (at least under MSVC)
 
122
                strategyTechUp = ((clock() % 3) == 0);
 
123
 
 
124
        LOG_II("CIntel::init Tech-up strategy: " << strategyTechUp)
 
125
 
 
126
        initialized = true;
37
127
}
38
128
 
39
129
void CIntel::update(int frame) {
42
132
        attackers.clear();
43
133
        metalMakers.clear();
44
134
        energyMakers.clear();
 
135
        navalUnits.clear();
 
136
        underwaterUnits.clear();
45
137
        restUnarmedUnits.clear();
46
138
        rest.clear();
 
139
        defenseGround.clear();
 
140
        defenseAntiAir.clear();
 
141
        commanders.clear();
 
142
        
47
143
        resetCounters();
48
144
 
49
 
        numUnits = ai->cbc->GetEnemyUnits(units, MAX_UNITS);
 
145
        int numUnits = ai->cbc->GetEnemyUnits(units, MAX_UNITS);
50
146
        
51
147
        for (int i = 0; i < numUnits; i++) {
52
 
                const UnitDef *ud = ai->cbc->GetUnitDef(units[i]);
 
148
                const int uid = units[i];
 
149
                const UnitDef *ud = ai->cbc->GetUnitDef(uid);
53
150
                UnitType      *ut = UT(ud->id);
54
151
                unsigned int    c = ut->cats;
55
152
                bool armed = !ud->weapons.empty();
56
153
 
57
154
                /* Ignore units being built and cloaked units */
58
 
                if ((ai->cbc->UnitBeingBuilt(units[i]) && (armed || !(c&STATIC)))
59
 
                ||      ai->cbc->IsUnitCloaked(units[i]))
 
155
                if ((ai->cbc->UnitBeingBuilt(uid) && (armed || !(c&STATIC)))
 
156
                ||      ai->cbc->IsUnitCloaked(uid))
60
157
                        continue;
61
158
                
62
 
                if (c&ATTACKER && !(c&AIR)) {
63
 
                        attackers.push_back(units[i]);
 
159
                if (c&COMMANDER) {
 
160
                        commanders.push_back(uid);
 
161
                }
 
162
                else if (c&SEA && ai->cbc->GetUnitPos(uid).y < 0.0f) {
 
163
                        underwaterUnits.push_back(uid);
 
164
                }
 
165
                else if (!(c&(LAND|AIR)) && c&SEA) {
 
166
                        navalUnits.push_back(uid);
 
167
                }
 
168
                else if ((c&STATIC) && (c&ANTIAIR)) {
 
169
                        defenseAntiAir.push_back(uid);
 
170
                }
 
171
                else if ((c&STATIC) && (c&DEFENSE)) {
 
172
                        defenseGround.push_back(uid);
 
173
                }
 
174
                else if ((c&ATTACKER) && !(c&AIR)) {
 
175
                        attackers.push_back(uid);
64
176
                }
65
177
                else if (c&FACTORY) {
66
 
                        factories.push_back(units[i]);
 
178
                        factories.push_back(uid);
67
179
                }
68
180
                else if (c&BUILDER && c&MOBILE && !(c&AIR)) {
69
 
                        mobileBuilders.push_back(units[i]);
 
181
                        mobileBuilders.push_back(uid);
70
182
                }
71
 
                else if (c&MEXTRACTOR || c&MMAKER) {
72
 
                        metalMakers.push_back(units[i]);
 
183
                else if (c&(MEXTRACTOR|MMAKER)) {
 
184
                        metalMakers.push_back(uid);
73
185
                }
74
186
                else if (c&EMAKER) {
75
 
                        energyMakers.push_back(units[i]);
 
187
                        energyMakers.push_back(uid);
76
188
                }
77
189
                else if (!armed)
78
 
                        restUnarmedUnits.push_back(units[i]);
 
190
                        restUnarmedUnits.push_back(uid);
79
191
                else {
80
 
                        rest.push_back(units[i]);
 
192
                        rest.push_back(uid);
81
193
                }
82
194
 
83
 
                if (c&ATTACKER && c&MOBILE)
 
195
                if ((c&ATTACKER) && (c&MOBILE))
84
196
                        updateCounts(c);
85
197
        }
86
198
}
120
232
        counts[AIR] = 0;
121
233
        counts[ASSAULT] = 3;
122
234
        
123
 
        if(ai->military->idleScoutGroupsNum() >= MAX_IDLE_SCOUT_GROUPS)
 
235
        if (ai->difficulty == DIFFICULTY_EASY || ai->military->idleScoutGroupsNum() >= MAX_IDLE_SCOUT_GROUPS)
124
236
                counts[SCOUTER] = 0;
125
237
        else
126
238
                counts[SCOUTER] = 1; // default value