~ubuntu-branches/ubuntu/precise/triplea/precise

« back to all changes in this revision

Viewing changes to src/games/strategy/triplea/baseAI/AbstractAI.java

  • Committer: Package Import Robot
  • Author(s): Scott Howard
  • Date: 2011-11-11 21:40:11 UTC
  • Revision ID: package-import@ubuntu.com-20111111214011-sehf2rwat36o2xqf
Tags: upstream-1.3.2.2
ImportĀ upstreamĀ versionĀ 1.3.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package games.strategy.triplea.baseAI;
 
2
 
 
3
import java.util.*;
 
4
import java.util.logging.*;
 
5
 
 
6
import games.strategy.engine.data.*;
 
7
import games.strategy.engine.gamePlayer.IPlayerBridge;
 
8
import games.strategy.net.GUID;
 
9
import games.strategy.triplea.Constants;
 
10
import games.strategy.triplea.Properties;
 
11
import games.strategy.triplea.delegate.DiceRoll;
 
12
import games.strategy.triplea.delegate.dataObjects.BattleListing;
 
13
import games.strategy.triplea.delegate.remote.*;
 
14
import games.strategy.triplea.player.ITripleaPlayer;
 
15
import games.strategy.triplea.ui.UIContext;
 
16
 
 
17
/**
 
18
 * Base class for ais.<p>
 
19
 * 
 
20
 *  Control pausing with the AI pause menu option
 
21
 * 
 
22
 * AI's should note that any data that is stored in the ai instance, will be lost when
 
23
 * the game is restarted.  We cannot save data with an AI, since the player
 
24
 * may choose to restart the game with a different ai, or with a human player.<p>
 
25
 * 
 
26
 * If an ai finds itself starting in the middle of a move phase, or the middle of a purchase phase,
 
27
 * (as would happen if a player saved the game during the middle of an AI's move phase)
 
28
 * it is acceptable for the ai to play badly for a turn, but the ai should recover, and play
 
29
 * correctly when the next phase of the game starts.<p>
 
30
 * 
 
31
 * 
 
32
 * @author sgb
 
33
 */
 
34
public abstract class AbstractAI implements ITripleaPlayer
 
35
{
 
36
    private final static Logger s_logger = Logger.getLogger(AbstractAI.class.getName());
 
37
    
 
38
    /**
 
39
     * Pause the game to allow the human player to see what is going on.
 
40
     *
 
41
     */
 
42
    protected void pause()
 
43
    {
 
44
    
 
45
        try
 
46
        {
 
47
            Thread.sleep(UIContext.getAIPauseDuration());
 
48
        } catch (InterruptedException e)
 
49
        {
 
50
            e.printStackTrace();
 
51
        }
 
52
        catch(Exception ex){}
 
53
 
 
54
    }
 
55
    
 
56
    
 
57
    private final String m_name;
 
58
    private IPlayerBridge m_bridge;
 
59
    private PlayerID m_id;
 
60
    
 
61
    
 
62
    /** 
 
63
     * @param name - the name of the player.
 
64
     */
 
65
    public AbstractAI(String name)
 
66
    {
 
67
        m_name = name;
 
68
    }
 
69
 
 
70
    
 
71
    public final void initialize(IPlayerBridge bridge, PlayerID id)
 
72
    {
 
73
        m_bridge = bridge;
 
74
        m_id = id;
 
75
    }
 
76
    
 
77
    /************************
 
78
     * Allow the AI to get game data, playerID
 
79
     *************************/
 
80
    
 
81
    /**
 
82
     * Get the GameData for the game.
 
83
     */
 
84
    protected final GameData getGameData()
 
85
    {
 
86
        return m_bridge.getGameData();
 
87
    }
 
88
    
 
89
    /**
 
90
     * Get the IPlayerBridge for this game player.
 
91
     */
 
92
    protected final IPlayerBridge getPlayerBridge()
 
93
    {
 
94
        return m_bridge;
 
95
    }
 
96
    
 
97
    /**
 
98
     * What player are we playing.
 
99
     */
 
100
    protected final PlayerID getWhoAmI()
 
101
    {
 
102
        return m_id;
 
103
    }
 
104
    
 
105
    /************************
 
106
     * The following methods are called when the AI starts a phase.
 
107
     *************************/
 
108
    
 
109
    /**
 
110
     * It is the AI's turn to purchase units.
 
111
     * 
 
112
     * @param purcahseForBid - is this a bid purchase, or a normal purchase
 
113
     * @param PUsToSpend - how many PUs we have to spend
 
114
     * @param purchaseDelegate - the purchase delgate to buy things with
 
115
     * @param data - the GameData
 
116
     * @param player - the player to buy for
 
117
     */
 
118
    protected abstract void purchase(boolean purcahseForBid, int PUsToSpend, IPurchaseDelegate purchaseDelegate, GameData data, PlayerID player);
 
119
 
 
120
    /**
 
121
     * It is the AI's turn to roll for technology.
 
122
     * 
 
123
     * @param techDelegate - the tech delegate to roll for
 
124
     * @param data - the game data
 
125
     * @param player - the player to roll tech for
 
126
     */
 
127
    protected abstract void tech(ITechDelegate techDelegate, GameData data, PlayerID player);
 
128
    
 
129
    /**
 
130
     * It is the AI's turn to move.  Make all moves before returning from this method.
 
131
     *  
 
132
     * @param nonCombat - are we moving in combat, or non combat
 
133
     * @param moveDel - the move delegate to make moves with
 
134
     * @param data - the current game data
 
135
     * @param player - the player to move with
 
136
     */
 
137
    protected abstract void move(boolean nonCombat, IMoveDelegate moveDel, GameData data, PlayerID player);
 
138
    
 
139
    /**
 
140
     * It is the AI's turn to place units.  get the units available to place with player.getUnits()
 
141
     * 
 
142
     * @param placeForBid - is this a placement for bid
 
143
     * @param placeDelegate - the place delegate to place with
 
144
     * @param data - the current Game Data
 
145
     * @param player - the player to place for
 
146
     */
 
147
    protected abstract void place(boolean placeForBid, IAbstractPlaceDelegate placeDelegate, GameData data, PlayerID player);
 
148
 
 
149
    
 
150
    /**
 
151
     * It is the AI's turn to fight. Subclasses may override this if they want, but
 
152
     * generally the AI does not need to worry about the order of fighting battles.
 
153
     * 
 
154
     * @param battleDelegate the battle delegate to query for battles not fought and the 
 
155
     * @param data - the current GameData
 
156
     * @param player - the player to fight for
 
157
     */
 
158
    protected void battle(IBattleDelegate battleDelegate, GameData data, PlayerID player)
 
159
    {
 
160
        //generally all AI's will follow the same logic.  
 
161
        
 
162
        //loop until all battles are fought.
 
163
        //rather than try to analyze battles to figure out which must be fought before others
 
164
        //as in the case of a naval battle preceding an amphibious attack,
 
165
        //keep trying to fight every battle
 
166
        while (true)
 
167
        {
 
168
    
 
169
            BattleListing listing = battleDelegate.getBattles();
 
170
 
 
171
            //all fought
 
172
            if(listing.getBattles().isEmpty() && listing.getStrategicRaids().isEmpty())
 
173
                return;
 
174
            
 
175
            Iterator<Territory> raidBattles = listing.getStrategicRaids().iterator();
 
176
 
 
177
            //fight strategic bombing raids
 
178
            while(raidBattles.hasNext())
 
179
            {
 
180
                Territory current = raidBattles.next();
 
181
                String error = battleDelegate.fightBattle(current, true);
 
182
                if(error != null)
 
183
                    s_logger.fine(error);
 
184
            }
 
185
            
 
186
            
 
187
            Iterator<Territory> nonRaidBattles = listing.getBattles().iterator();
 
188
 
 
189
            //fight normal battles
 
190
            while(nonRaidBattles.hasNext())
 
191
            {
 
192
                Territory current = nonRaidBattles.next();
 
193
                String error = battleDelegate.fightBattle(current, false);
 
194
                if(error != null)
 
195
                    s_logger.fine(error);
 
196
            }
 
197
        }
 
198
    }
 
199
    
 
200
    /******************************************
 
201
     * The following methods the AI may choose to implemenmt,
 
202
     * but in general won't
 
203
     * 
 
204
     *******************************************/
 
205
    
 
206
    public Territory selectBombardingTerritory(Unit unit, Territory unitTerritory, Collection<Territory> territories, boolean noneAvailable)
 
207
    {       
 
208
        //return the first one
 
209
        return (Territory) territories.iterator().next();
 
210
    }
 
211
    
 
212
    public boolean selectAttackSubs(Territory unitTerritory)
 
213
    {
 
214
        return true;
 
215
    }
 
216
 
 
217
    public boolean selectAttackTransports(Territory unitTerritory)
 
218
    {
 
219
        return true;
 
220
    }
 
221
 
 
222
    public boolean selectAttackUnits(Territory unitTerritory)
 
223
    {
 
224
        return true;
 
225
    }
 
226
 
 
227
    public boolean selectShoreBombard(Territory unitTerritory)
 
228
    {
 
229
        return true;
 
230
    }
 
231
    
 
232
    public Territory whereShouldRocketsAttack(Collection<Territory> candidates, Territory from)
 
233
    {   
 
234
        //just use the first one
 
235
        return candidates.iterator().next();
 
236
    }
 
237
    
 
238
    public boolean confirmMoveKamikaze()
 
239
    {
 
240
        return false;
 
241
    }
 
242
 
 
243
    public boolean confirmMoveHariKari()
 
244
    {
 
245
        return false;
 
246
    }
 
247
 
 
248
    
 
249
    /*****************************************
 
250
     * The following methods are more for the ui, and the 
 
251
     * ai will generally not care
 
252
     * 
 
253
     *****************************************/
 
254
 
 
255
    public void battleInfoMessage(String shortMessage, DiceRoll dice)
 
256
    {}
 
257
 
 
258
    public void confirmEnemyCasualties(GUID battleId, String message, PlayerID hitPlayer)
 
259
    {}
 
260
 
 
261
    public void retreatNotificationMessage(Collection<Unit> units)
 
262
    {}
 
263
 
 
264
    public void reportError(String error)
 
265
    {}
 
266
 
 
267
    public void reportMessage(String message)
 
268
    {}
 
269
 
 
270
 
 
271
    public void confirmOwnCasualties(GUID battleId, String message)
 
272
    {
 
273
        pause();
 
274
    }
 
275
 
 
276
    
 
277
    /*****************************************
 
278
     * Game Player Methods
 
279
     * 
 
280
     *****************************************/
 
281
    
 
282
    /**
 
283
     * The given phase has started.  We parse the phase name and call the apropiate method.
 
284
     */
 
285
    public final void start(String name)
 
286
    {
 
287
        if (name.endsWith("Bid"))
 
288
        {
 
289
            String propertyName = m_id.getName() + " bid";
 
290
            int bidAmount = Integer.parseInt(m_bridge.getGameData().getProperties().get(propertyName).toString());
 
291
            
 
292
            purchase(true,bidAmount, (IPurchaseDelegate) m_bridge.getRemote(), m_bridge.getGameData(), m_id);
 
293
        }
 
294
        else if (name.endsWith("Tech")) {
 
295
                if(!Properties.getTechDevelopment(getGameData())) {
 
296
                        return;
 
297
                }
 
298
            tech((ITechDelegate) m_bridge.getRemote() , m_bridge.getGameData(), m_id);
 
299
        }
 
300
        else if (name.endsWith("Purchase"))
 
301
        {
 
302
            
 
303
            Resource PUs = m_bridge.getGameData().getResourceList().getResource(Constants.PUS);
 
304
            int leftToSpend = m_id.getResources().getQuantity(PUs );
 
305
            
 
306
            purchase(false,leftToSpend, (IPurchaseDelegate) m_bridge.getRemote(), m_bridge.getGameData(), m_id);
 
307
        }
 
308
        else if (name.endsWith("Move"))
 
309
            move(name.endsWith("NonCombatMove"), (IMoveDelegate) m_bridge.getRemote(), m_bridge.getGameData(), m_id);
 
310
        else if (name.endsWith("Battle"))
 
311
            battle((IBattleDelegate) m_bridge.getRemote(), m_bridge.getGameData(), m_id);
 
312
        else if (name.endsWith("Place"))
 
313
            place(name.indexOf("Bid") != -1, (IAbstractPlaceDelegate) m_bridge.getRemote(), m_bridge.getGameData(), m_id );
 
314
        else if (name.endsWith("EndTurn"))
 
315
        {}
 
316
    }
 
317
    
 
318
    public final Class<ITripleaPlayer> getRemotePlayerType()
 
319
    {
 
320
        return ITripleaPlayer.class;
 
321
    }
 
322
    
 
323
    public final String getName()
 
324
    {
 
325
        return m_name;
 
326
    }
 
327
 
 
328
    public final PlayerID getID()
 
329
    {
 
330
        return m_id;
 
331
    }
 
332
    
 
333
}