include "scg-csp-game.beh"; Transaction{{ }} OfferTrans{{ }} AcceptTrans{{ }} ProvideTrans{{ }} SolveTrans{{ }} ReofferTrans{{}} PlayerSpec{{ /** Get the Name of this Player */ public String getName(){ return name; } /** Get the Address of this Player's Server */ public String getAddress(){ return address; } /** Get the Port of this Player's Server */ public int getPort(){ return port; } /** Returns a Predicate that compares another PlayerSpec by name */ public List.Pred sameNamePred(){ return new SameName(); } /** Predicate for PlayerSpecs that compares Names */ private class SameName extends List.Pred{ public boolean huh(PlayerSpec that) { return name.equals(that.name); } } }} PlayersFile{{ /** Get the List of PlayerSpecs */ public List getPlayerSpecs(){ return players; } }} PasswordEntry{{ /** Add to the given Map */ public Map addTo(Map m){ return m.put(name,passhash); } }} PasswordFile{{ /** Get a Map of Player-Name / Password-Hash */ public Map getPasswordMap(){ return passwds.fold(new List.Fold>(){ public Map fold(PasswordEntry e, Map m){ return e.addTo(m); } }, Map.create()); } }} PlayerTrans{{ }} PlayerStore{{ }} Round{{ /** Create a new Round from the given Number and Player Transactions */ public static Round create(int n, List ts) { return new Round(n, ts); } /** Create the Initial Round (0) */ public static Round initial(){ return forNumber(0); } /** Create an empty Round for the given Number */ public static Round forNumber(int i) { return create(i, List.create()); } /** Add a new Transaction to this Round */ public Round addTrans(PlayerTrans t) { return create(num, trans.push(t)); } }} AdminState{{ /** Create an AdminState from the given Maps... */ public static AdminState create(Map specs, Map strs, Map acc, Round curr){ return new AdminState(specs,strs,acc,curr); } /** Create the initial (empty) AdminState */ public static AdminState initial(){ return initial(Map.create()); } /** Create the initial (empty) AdminState With players drawn from the given File */ public static AdminState initial(String playerFile) throws ParseException,java.io.IOException{ List plyrs = PlayersFile.parse(new java.io.FileInputStream(playerFile)).getPlayerSpecs(); Map specs = plyrs.fold(new List.Fold>(){ int start = (int)(Math.random()*100); public Map fold(PlayerSpec s, Map m){ return m.put(new PlayerID(start++), s); } }, Map.create()); return initial(specs); } /** Create the initial (empty) AdminState With the given players */ public static AdminState initial(Map plyrs){ return create(plyrs, Map.create(), Map.create(), Round.initial()); } }} PlayerContext{{ public static String CONFIG_KEY = "config", BALANCE_KEY = "balance", PLAYERID_KEY = "playerid", OUROFFERED_KEY = "yourOffered", OTHERESOFFERED_KEY = "othersOffered", ACCEPTED_KEY = "accepted", PROVIDED_KEY = "provided"; /** */ public static PlayerContext create(Map> heads) throws Exception{ Config cfg = Config.parse(onlyOne(heads, PlayerContext.CONFIG_KEY)); PlayerID pid = PlayerID.parse(onlyOne(heads, PlayerContext.PLAYERID_KEY)); double bal = Double.parseDouble(onlyOne(heads, PlayerContext.BALANCE_KEY)); List ouroff = allfor(heads, PlayerContext.OUROFFERED_KEY).map(new OfferParse()); List othoff = allfor(heads, PlayerContext.OTHERESOFFERED_KEY).map(new OfferParse()); List acc = allfor(heads, PlayerContext.OTHERESOFFERED_KEY).map(new AcceptParse()); List prov = allfor(heads, PlayerContext.OTHERESOFFERED_KEY).map(new ProvideParse()); return new PlayerContext(cfg,pid,bal,ouroff,othoff,acc,prov); } /** */ public static PlayerContext create(java.util.Map> heads) throws Exception{ Map> fmap = Map.create(); for(java.util.Map.Entry> e:heads.entrySet()){ fmap = fmap.put(e.getKey(), List.create((Iterable)e.getValue())); } return create(fmap); } /** */ private static String onlyOne(Map> hs, String key){ if(hs.containsKey(key)){ List val = hs.get(key); if(val.length() == 1)return val.top(); throw new RuntimeException(" Found "+val.length()+" Values for Context key '"+key+"'"); } throw new RuntimeException("Empty Context key '"+key+"'"); } /** */ private static List allfor(Map> hs, String key){ return hs.containsKey(key) ? hs.get(key) : List.create(); } /** */ static class OfferParse extends List.Map{ public OfferedChallenge map(String s){ try{ return OfferedChallenge.parse(s); } catch(gen.ParseException e){ throw new RuntimeException(e); } } } /** */ static class AcceptParse extends List.Map{ public AcceptedChallenge map(String s){ try{ return AcceptedChallenge.parse(s); } catch(gen.ParseException e){ throw new RuntimeException(e); } } } /** */ static class ProvideParse extends List.Map{ public ProvidedChallenge map(String s){ try{ return ProvidedChallenge.parse(s); } catch(gen.ParseException e){ throw new RuntimeException(e); } } } /** */ public String forHTTP(){ return (PlayerContext.CONFIG_KEY+": "+getConfig()+"\n"+ PlayerContext.PLAYERID_KEY+": "+getPlayerID()+"\n"+ PlayerContext.BALANCE_KEY+": "+getBalance()+"\n"+ PlayerContext.OUROFFERED_KEY+": "+getOurOfferedChallenges()+"\n"+ PlayerContext.OTHERESOFFERED_KEY+": "+getOthersOfferedChallenges()+"\n"+ PlayerContext.ACCEPTED_KEY+": "+getAcceptedChallenges()+"\n"+ PlayerContext.PROVIDED_KEY+": "+getProvidedChallenges()); } /** */ public Config getConfig(){ return config; } /** */ public PlayerID getPlayerID(){ return id; } /** */ public double getBalance(){ return balance; } /** */ public List getAllOfferedChallenges(){ return ourOffered.append(theirOffered); } /** */ public List getOurOfferedChallenges(){ return ourOffered; } /** */ public List getOthersOfferedChallenges(){ return theirOffered; } /** */ public List getAcceptedChallenges(){ return accepted; } /** */ public List getProvidedChallenges(){ return provided; } }}