/* ********************************** * AccountUpdater.java * AccountUpdater * **********************************/ package sdg.admin.utils; import edu.neu.ccs.demeterf.*; import edu.neu.ccs.demeterf.demfgen.lib.List; import gen.*; import sdg.local.utils.ComputeQuality; import sdg.local.utils.DerivativesFinder; import sdg.local.utils.ListTUCombiner; /** Class for updating the accounts */ public class AccountUpdater{ /** Returns a list of new accounts that are updated after a round */ public static Accounts updateAccounts(Accounts old, Store store, PlayerTransaction trans){ List> change = changes(trans.transactions, store, trans.player); return change.fold(new List.Fold, Accounts>(){ public Accounts fold(Pair ch, Accounts accs){ return accs.update(ch); } }, old); } /** Simple helper method... */ static List> changes(List trans, Store s, Player p){ return TUCombiner.traverse(trans, new AccountChanges(s, p), Control.builtins(Transaction.class,Derivative.class)); } /** Create a Pair for the Store/Accounts */ static Pair pair(PlayerID pid, Double d){ return new Pair(pid,d); } /** Calculate the Account changes for each Transaction */ static class AccountChanges extends ListTUCombiner>{ Player player; Store store; AccountChanges(Store s, Player p){ player = p; store = s; } List> combines(Transaction trans) { return combine(); } @SuppressWarnings("unchecked") List> combine(BuyTrans trans) { //deduct from account of buyer, add to the account of seller Derivative d = DerivativesFinder.derByName(store, trans.derivName); return List.create( pair(player.id, -d.price.val), pair(d.seller, d.price.val)); } @SuppressWarnings("unchecked") List> combine(FinishTrans trans){ Derivative d = DerivativesFinder.derByName(store, trans.derivName); if(new Classic().equals(d.type.kind)) { //add to the account of buyer, deduct from the account of seller return List.create( pair(player.id, trans.finish.quality.val), pair(d.seller, -trans.finish.quality.val)); } else if(new Secret().equals(d.type.kind)) { double sq = ComputeQuality.quality(d.optraw.inner(), d.optraw.inner().instance.secret.inner().assign.inner()).val; double win = d.optfinished.inner().quality.val - sq * d.price.val; double payout = 0; if(win >= 0) { payout = d.price.val + win; } return List.create( pair(player.id, payout), pair(d.seller, -payout)); } return List.create(); } } }