package admin; import java.io.File; import java.io.IOException; import config.AdminConfig; import config.GlobalConfig; import edu.neu.ccs.demeterf.demfgen.lib.List; import edu.neu.ccs.demeterf.demfgen.lib.List.Pred; import gen.*; import tournament.Result; import tournament.Tournament; import admin.utils.*; import admin.utils.Game.GameType; import utils.comparator.LargerBalance; public class TournAdmin extends Administrator { public TournAdmin(Output o) { super(o, GlobalConfig.DEFAULT_MAX_STACK); } /** Run a match between white and black. */ @SuppressWarnings("unchecked") public Result runMatch(Player white, Player black, GameType gt) { Config config = AdminDocumentHandler.getConfig(); Store store = AdminDocumentHandler.getStore(); Pair<PlayerID, Double> whiteAcct = new Pair<PlayerID, Double>(white.id, config.Money); Pair<PlayerID, Double> blackAcct = new Pair<PlayerID, Double>(black.id, config.Money); List<Pair<PlayerID, Double>> accts = List.<Pair<PlayerID, Double>>create(); accts = accts.append(whiteAcct); accts = accts.append(blackAcct); Accounts accounts = new Accounts(accts); AdminDocumentHandler.commitAccounts(accounts); for(int roundNum = 1; roundNum <= 2 + config.Rounds; roundNum++) { if(overtime(roundNum)) { System.out.println("OVERTIME ROUND: " + (roundNum - config.Rounds)); } else { System.out.println("ROUND: " + roundNum); } List<PlayerTransaction> pTransactions = List.create(); Round round = new Round(roundNum, pTransactions); if(!passTurn(white, config)) { return Result.black("White time violation or jar not found."); } PlayerTransaction whitePTrans = AdminDocumentHandler.getPlayerTrans(white); if(overtime(roundNum)) { whitePTrans.transactions = whitePTrans.transactions.filter(new Pred<Transaction>(){ public boolean huh(Transaction arg0) { return arg0.ttype instanceof Deliver || arg0.ttype instanceof Finish; } }); } if(whitePTrans == null) { return Result.black("No white PlayerTrans."); } else { Pair<Boolean, String> result; if(overtime(roundNum)) { result = RuleChecker.overtimeRulesFollowed(whitePTrans, store, accounts, gt, config); } else { result = RuleChecker.rulesFollowed(whitePTrans, store, accounts, gt, config); } if(!result.a) { return Result.black(result.b); } else{ whitePTrans = Util.computeQualities(whitePTrans); whitePTrans = Util.truncateRMs(whitePTrans, config.MaxRawMaterialLen); store = this.updateStore(whitePTrans, store); accounts = this.updateAccounts(whitePTrans, accounts); } } if(!passTurn(black, config)) { return Result.white("Black time violation or jar not found."); } PlayerTransaction blackPTrans = AdminDocumentHandler.getPlayerTrans(black); if(overtime(roundNum)){ blackPTrans.transactions = blackPTrans.transactions.filter(new Pred<Transaction>(){ public boolean huh(Transaction arg0) { return arg0.ttype instanceof Deliver || arg0.ttype instanceof Finish; } }); } if(blackPTrans == null){ return Result.white("No black PlayerTrans."); } else{ Pair<Boolean, String> result; if(overtime(roundNum)) { result = RuleChecker.overtimeRulesFollowed(blackPTrans, store, accounts, gt, config); } else { result = RuleChecker.rulesFollowed(blackPTrans, store, accounts, gt, config); } if(!result.a) { return Result.white(result.b); } else{ blackPTrans = Util.computeQualities(blackPTrans); blackPTrans = Util.truncateRMs(blackPTrans, config.MaxRawMaterialLen); store = this.updateStore(blackPTrans, store); accounts = this.updateAccounts(blackPTrans, accounts); } } AdminDocumentHandler.updateHistory(round); } Accounts finalAccts = AdminDocumentHandler.getAccounts(); List<Pair<PlayerID, Double>> sortedAccts = finalAccts.accounts.sort(new LargerBalance()); PlayerID winner = sortedAccts.top().a; if(winner.id == white.id.id) { return Result.white("Larger balance: " + sortedAccts.top().b); } else { return Result.black("Larger balance: " + sortedAccts.top().b); } } /** Updates the store with the player transaction */ private Store updateStore(PlayerTransaction trans, Store existingStore) { existingStore = StoreUpdater.updateStore(existingStore, trans); AdminDocumentHandler.commitStore(existingStore); return existingStore; } /** Updates the accounts with the player transaction */ private Accounts updateAccounts(PlayerTransaction pTrans, Accounts accounts) { accounts = AccountUpdater.updateAccounts(accounts, pTrans); AdminDocumentHandler.commitAccounts(accounts); return accounts; } /** Passes the turn to player */ private boolean passTurn(Player player, Config config) { File playerDir = new File(AdminConfig.BLACKBOARD_PATH + AdminConfig.PLAYERS_PATH); System.out.println("Player " + player.id.id + " of team " + player.name + "'s turn."); // Determine if the player is C# or Java String cmdline; String fName = AdminConfig.BLACKBOARD_PATH + AdminConfig.PLAYERS_PATH + "/" + player.name; String jcmdline = "java -Xss" + GlobalConfig.DEFAULT_MAX_STACK + " -jar " + player.name + ".jar " + player.id.id + " " + player.name; String ccmdline = fName+ ".exe " + player.id.id + " " + player.name; File file; file = new File(fName + ".jar"); if (file.exists()){ cmdline = jcmdline; } else{ file = new File(fName + ".exe"); if (file.exists()){ cmdline = ccmdline; } else { return false; } } Process p; Runtime r = Runtime.getRuntime(); long sTime = 0, eTime = 0; try{ sTime = System.currentTimeMillis(); p = r.exec(cmdline, null, playerDir); StreamWatcher outWatch = new StreamWatcher(p.getInputStream(), Output.htmlOutput()); StreamWatcher errWatch = new StreamWatcher(p.getErrorStream(), Output.htmlOutput()); ProcessWatcher pWatch = new ProcessWatcher(p); Thread out = new Thread(outWatch); Thread err = new Thread(errWatch); Thread timer = new Thread(pWatch); out.start(); err.start(); timer.start(); pWatch.waitForTimeLimit(config.Time); Thread.sleep(2000); System.out.flush(); System.err.flush(); eTime = System.currentTimeMillis(); outWatch.kill(); errWatch.kill(); System.out.println("Player " + player.id.id + " of team " + player.name + " finished in " + (eTime - sTime) + " milliseconds."); if ((eTime - sTime) > config.Time){ p.destroy(); System.out.println("Player " + player.id.id + " kicked for time violation."); return false; } } // Catch for p = r.exec(cmdline); catch(IOException e) { e.printStackTrace(); } // Catch for pWatch.waitForTimeLimit(config.Time); catch (InterruptedException e) { e.printStackTrace(); } return true; } public static void main(String[] args) { AdminCmdLineParser cmds = new AdminCmdLineParser(args); Players p = AdminDocumentHandler.getPlayers(); Tournament t = new Tournament(p.players, cmds.outputFile, cmds.gt); tournament.TournHTMLOutput o = tournament.TournHTMLOutput.tournhtmlOutput(cmds.resultsFile); o.header(); t.runTournament(); o.finishTable(t.getResults()); o.footer(); } }