package games.strategy.triplea.delegate; import java.io.Serializable; import games.strategy.engine.data.Change; import games.strategy.engine.data.CompositeChange; import games.strategy.engine.data.GameData; import games.strategy.engine.data.PlayerID; import games.strategy.engine.data.ProductionRule; import games.strategy.engine.data.RepairRule; import games.strategy.engine.data.Resource; import games.strategy.engine.data.ResourceCollection; import games.strategy.engine.data.changefactory.ChangeFactory; import games.strategy.triplea.Constants; import games.strategy.triplea.MapSupport; import games.strategy.util.IntegerMap; @MapSupport public class BidPurchaseDelegate extends PurchaseDelegate { private int m_bid; private int m_spent; private boolean m_hasBid = false; private static int getBidAmount(final GameData data, final PlayerID currentPlayer) { final String propertyName = currentPlayer.getName() + " bid"; final int bid = data.getProperties().get(propertyName, 0); return bid; } public static boolean doesPlayerHaveBid(final GameData data, final PlayerID player) { return getBidAmount(data, player) != 0; } @Override public boolean delegateCurrentlyRequiresUserInput() { if (!doesPlayerHaveBid(getData(), m_player)) { return false; } if ((m_player.getProductionFrontier() == null || m_player.getProductionFrontier().getRules().isEmpty()) && (m_player.getRepairFrontier() == null || m_player.getRepairFrontier().getRules().isEmpty())) { return false; } return canWePurchaseOrRepair(); } @Override protected boolean canWePurchaseOrRepair() { final ResourceCollection bidCollection = new ResourceCollection(getData()); // TODO: allow bids to have more than just PUs bidCollection.addResource(getData().getResourceList().getResource(Constants.PUS), m_bid); if (m_player.getProductionFrontier() != null && m_player.getProductionFrontier().getRules() != null) { for (final ProductionRule rule : m_player.getProductionFrontier().getRules()) { if (bidCollection.has(rule.getCosts())) { return true; } } } if (m_player.getRepairFrontier() != null && m_player.getRepairFrontier().getRules() != null) { for (final RepairRule rule : m_player.getRepairFrontier().getRules()) { if (bidCollection.has(rule.getCosts())) { return true; } } } return false; } /** * subclasses can over ride this method to use different restrictions as to what a player can buy. */ @Override protected boolean canAfford(final IntegerMap<Resource> costs, final PlayerID player) { final ResourceCollection bidCollection = new ResourceCollection(getData()); // TODO: allow bids to have more than just PUs bidCollection.addResource(getData().getResourceList().getResource(Constants.PUS), m_bid); return bidCollection.has(costs); } @Override public void start() { super.start(); if (m_hasBid) { return; } m_bid = getBidAmount(m_bridge.getData(), m_bridge.getPlayerID()); m_spent = 0; } @Override protected String removeFromPlayer(final PlayerID player, final IntegerMap<Resource> resources, final CompositeChange change) { m_spent = resources.getInt(super.getData().getResourceList().getResource(Constants.PUS)); return (m_bid - m_spent) + " PU unused"; } /** * Called before the delegate will stop running. */ @Override public void end() { super.end(); final int unspent = m_bid - m_spent; if (unspent == 0) { return; } m_bridge.getHistoryWriter() .startEvent(m_bridge.getPlayerID().getName() + " retains " + unspent + " PUS not spent in bid phase"); final Change unspentChange = ChangeFactory.changeResourcesChange(m_bridge.getPlayerID(), super.getData().getResourceList().getResource(Constants.PUS), unspent); m_bridge.addChange(unspentChange); m_hasBid = false; } @Override public Serializable saveState() { final BidPurchaseExtendedDelegateState state = new BidPurchaseExtendedDelegateState(); state.superState = super.saveState(); state.m_bid = m_bid; state.m_hasBid = m_hasBid; state.m_spent = this.m_spent; return state; } @Override public void loadState(final Serializable state) { final BidPurchaseExtendedDelegateState s = (BidPurchaseExtendedDelegateState) state; super.loadState(s.superState); m_bid = s.m_bid; m_spent = s.m_spent; m_hasBid = s.m_hasBid; } } class BidPurchaseExtendedDelegateState implements Serializable { private static final long serialVersionUID = 6896164200767186673L; Serializable superState; int m_bid; int m_spent; boolean m_hasBid; }