Program: 173789
Project: 173789
Buggy source:
/** 
 * Get a list of buyable trains for the currently operating company. Omit trains that the company has no money for. If there is no cash to buy any train from the Bank, prepare for emergency train buying.
 */
public void setBuyableTrains(){
  if (operatingCompany == null)   return;
  TrainManager trainMgr=gameManager.getTrainManager();
  int cash=operatingCompany.getCash();
  int cost;
  List<TrainI> trains;
  boolean hasTrains=operatingCompany.getPortfolio().getNumberOfTrains() > 0;
  boolean atTrainLimit=operatingCompany.getNumberOfTrains() >= operatingCompany.getCurrentTrainLimit();
  boolean canBuyTrainNow=canBuyTrain();
  boolean presidentMayHelp=!hasTrains && operatingCompany.mustOwnATrain();
  TrainI cheapestTrain=null;
  int costOfCheapestTrain=0;
  if (currentPhase.canBuyMoreTrainsPerTurn() || trainsBoughtThisTurn.isEmpty()) {
    boolean mayBuyMoreOfEachType=currentPhase.canBuyMoreTrainsPerTypePerTurn();
    trains=trainMgr.getAvailableNewTrains();
    for (    TrainI train : trains) {
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getType())) {
        continue;
      }
      cost=train.getCost();
      if (cost <= cash) {
        if (canBuyTrainNow)         possibleActions.add(new BuyTrain(train,ipo,cost));
      }
 else       if (costOfCheapestTrain == 0 || cost < costOfCheapestTrain) {
        cheapestTrain=train;
        costOfCheapestTrain=cost;
      }
      if (train.canBeExchanged() && hasTrains) {
        cost=train.getType().getFirstExchangeCost();
        if (cost <= cash) {
          List<TrainI> exchangeableTrains=operatingCompany.getPortfolio().getUniqueTrains();
          BuyTrain action=new BuyTrain(train,ipo,cost);
          action.setTrainsForExchange(exchangeableTrains);
          if (atTrainLimit)           action.setForcedExchange(true);
          possibleActions.add(action);
        }
      }
      if (!canBuyTrainNow)       return;
      for (      SpecialTrainBuy stb : getSpecialProperties(SpecialTrainBuy.class)) {
        int reducedPrice=stb.getPrice(cost);
        if (reducedPrice > cash)         continue;
        BuyTrain bt=new BuyTrain(train,ipo,reducedPrice);
        bt.setSpecialProperty(stb);
        possibleActions.add(bt);
      }
    }
    if (!canBuyTrainNow)     return;
    trains=pool.getUniqueTrains();
    for (    TrainI train : trains) {
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getType())) {
        continue;
      }
      cost=train.getCost();
      if (cost <= cash) {
        possibleActions.add(new BuyTrain(train,pool,cost));
      }
 else       if (costOfCheapestTrain == 0 || cost < costOfCheapestTrain) {
        cheapestTrain=train;
        costOfCheapestTrain=cost;
      }
    }
    if (!hasTrains && possibleActions.getType(BuyTrain.class).isEmpty() && cheapestTrain != null && presidentMayHelp) {
      possibleActions.add(new BuyTrain(cheapestTrain,cheapestTrain.getHolder(),costOfCheapestTrain).setPresidentMustAddCash(costOfCheapestTrain - cash));
    }
  }
  if (!canBuyTrainNow)   return;
  if (currentPhase.isTrainTradingAllowed()) {
    PublicCompanyI c;
    BuyTrain bt;
    Player p;
    Portfolio pf;
    int index;
    List<List<PublicCompanyI>> companiesPerPlayer=new ArrayList<List<PublicCompanyI>>(numberOfPlayers);
    for (int i=0; i < numberOfPlayers; i++)     companiesPerPlayer.add(new ArrayList<PublicCompanyI>(4));
    List<PublicCompanyI> companies;
    for (int j=0; j < operatingCompanyArray.length; j++) {
      c=operatingCompanyArray[j];
      if (c.isClosed() || c == operatingCompany)       continue;
      p=c.getPresident();
      index=p.getIndex();
      companiesPerPlayer.get(index).add(c);
    }
    int currentPlayerIndex=operatingCompany.getPresident().getIndex();
    for (int i=currentPlayerIndex; i < currentPlayerIndex + numberOfPlayers; i++) {
      companies=companiesPerPlayer.get(i % numberOfPlayers);
      for (      PublicCompanyI company : companies) {
        pf=company.getPortfolio();
        trains=pf.getUniqueTrains();
        for (        TrainI train : trains) {
          if (train.isObsolete())           continue;
          if (i != currentPlayerIndex && trainMgr.buyAtFaceValueBetweenDifferentPresidents() || operatingCompany.mustTradeTrainsAtFixedPrice() || company.mustTradeTrainsAtFixedPrice()) {
            if (cash >= train.getCost()) {
              bt=new BuyTrain(train,pf,train.getCost());
            }
 else {
              continue;
            }
          }
 else {
            bt=new BuyTrain(train,pf,0);
          }
          if (presidentMayHelp && cash < train.getCost()) {
            bt.setPresidentMayAddCash(train.getCost() - cash);
          }
          possibleActions.add(bt);
        }
      }
    }
  }
  if (!operatingCompany.mustOwnATrain() || operatingCompany.getPortfolio().getNumberOfTrains() > 0) {
    doneAllowed=true;
  }
}

Fixed version (ground truth):
/** 
 * Get a list of buyable trains for the currently operating company. Omit trains that the company has no money for. If there is no cash to buy any train from the Bank, prepare for emergency train buying.
 */
public void setBuyableTrains(){
  if (operatingCompany == null)   return;
  TrainManager trainMgr=gameManager.getTrainManager();
  int cash=operatingCompany.getCash();
  int cost;
  List<TrainI> trains;
  boolean hasTrains=operatingCompany.getPortfolio().getNumberOfTrains() > 0;
  boolean atTrainLimit=operatingCompany.getNumberOfTrains() >= operatingCompany.getCurrentTrainLimit();
  boolean canBuyTrainNow=isBelowTrainLimit();
  boolean presidentMayHelp=!hasTrains && operatingCompany.mustOwnATrain();
  TrainI cheapestTrain=null;
  int costOfCheapestTrain=0;
  if (currentPhase.canBuyMoreTrainsPerTurn() || trainsBoughtThisTurn.isEmpty()) {
    boolean mayBuyMoreOfEachType=currentPhase.canBuyMoreTrainsPerTypePerTurn();
    trains=trainMgr.getAvailableNewTrains();
    for (    TrainI train : trains) {
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getType())) {
        continue;
      }
      cost=train.getCost();
      if (cost <= cash) {
        if (canBuyTrainNow)         possibleActions.add(new BuyTrain(train,ipo,cost));
      }
 else       if (costOfCheapestTrain == 0 || cost < costOfCheapestTrain) {
        cheapestTrain=train;
        costOfCheapestTrain=cost;
      }
      if (train.canBeExchanged() && hasTrains) {
        cost=train.getType().getFirstExchangeCost();
        if (cost <= cash) {
          List<TrainI> exchangeableTrains=operatingCompany.getPortfolio().getUniqueTrains();
          BuyTrain action=new BuyTrain(train,ipo,cost);
          action.setTrainsForExchange(exchangeableTrains);
          if (atTrainLimit)           action.setForcedExchange(true);
          possibleActions.add(action);
          canBuyTrainNow=true;
        }
      }
      if (!canBuyTrainNow)       continue;
      for (      SpecialTrainBuy stb : getSpecialProperties(SpecialTrainBuy.class)) {
        int reducedPrice=stb.getPrice(cost);
        if (reducedPrice > cash)         continue;
        BuyTrain bt=new BuyTrain(train,ipo,reducedPrice);
        bt.setSpecialProperty(stb);
        possibleActions.add(bt);
      }
    }
    if (!canBuyTrainNow)     return;
    trains=pool.getUniqueTrains();
    for (    TrainI train : trains) {
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getType())) {
        continue;
      }
      cost=train.getCost();
      if (cost <= cash) {
        possibleActions.add(new BuyTrain(train,pool,cost));
      }
 else       if (costOfCheapestTrain == 0 || cost < costOfCheapestTrain) {
        cheapestTrain=train;
        costOfCheapestTrain=cost;
      }
    }
    if (!hasTrains && possibleActions.getType(BuyTrain.class).isEmpty() && cheapestTrain != null && presidentMayHelp) {
      possibleActions.add(new BuyTrain(cheapestTrain,cheapestTrain.getHolder(),costOfCheapestTrain).setPresidentMustAddCash(costOfCheapestTrain - cash));
    }
  }
  if (!canBuyTrainNow)   return;
  if (currentPhase.isTrainTradingAllowed()) {
    PublicCompanyI c;
    BuyTrain bt;
    Player p;
    Portfolio pf;
    int index;
    List<List<PublicCompanyI>> companiesPerPlayer=new ArrayList<List<PublicCompanyI>>(numberOfPlayers);
    for (int i=0; i < numberOfPlayers; i++)     companiesPerPlayer.add(new ArrayList<PublicCompanyI>(4));
    List<PublicCompanyI> companies;
    for (int j=0; j < operatingCompanyArray.length; j++) {
      c=operatingCompanyArray[j];
      if (c.isClosed() || c == operatingCompany)       continue;
      p=c.getPresident();
      index=p.getIndex();
      companiesPerPlayer.get(index).add(c);
    }
    int currentPlayerIndex=operatingCompany.getPresident().getIndex();
    for (int i=currentPlayerIndex; i < currentPlayerIndex + numberOfPlayers; i++) {
      companies=companiesPerPlayer.get(i % numberOfPlayers);
      for (      PublicCompanyI company : companies) {
        pf=company.getPortfolio();
        trains=pf.getUniqueTrains();
        for (        TrainI train : trains) {
          if (train.isObsolete())           continue;
          if (i != currentPlayerIndex && trainMgr.buyAtFaceValueBetweenDifferentPresidents() || operatingCompany.mustTradeTrainsAtFixedPrice() || company.mustTradeTrainsAtFixedPrice()) {
            if (cash >= train.getCost()) {
              bt=new BuyTrain(train,pf,train.getCost());
            }
 else {
              continue;
            }
          }
 else {
            bt=new BuyTrain(train,pf,0);
          }
          if (presidentMayHelp && cash < train.getCost()) {
            bt.setPresidentMayAddCash(train.getCost() - cash);
          }
          possibleActions.add(bt);
        }
      }
    }
  }
  if (!operatingCompany.mustOwnATrain() || operatingCompany.getPortfolio().getNumberOfTrains() > 0) {
    doneAllowed=true;
  }
}