archon
Version:
A helper to test battle code bots (battlecode.org)
201 lines (172 loc) • 5.7 kB
JavaScript
var MAP = 0;
var TEAM_A = 1;
var TEAM_B = 2;
var runGame = require('./game').runGame;
var DataCollector = require('./data').DataCollector;
var request = require('request');
var path = require('path');
var winston = require('winston');
var writeCleanUI = require('./writeUI').writeCleanUI;
var writeCleanConf = require('./writeConf').writeCleanConf;
function _generateRoundRobinGames(maps, teams, series) {
var i, j, k;
var games = [];
if (!series) {
for (i = 0; i < maps.length; i++) {
for (j = 0; j < teams.length; j++) {
for (k = j + 1; k < teams.length; k++) {
games.push([maps[i], teams[j], teams[k]])
}
}
}
} else {
var map = maps.join(',');
for (j = 0; j < teams.length; j++) {
for (k = j + 1; k < teams.length; k++) {
games.push([map, teams[j], teams[k]])
}
}
}
return games;
}
function _generateVsWorldGames(maps, teams, host, series) {
var i, j;
var games = [];
if (!series) {
for (i = 0; i < maps.length; i++) {
for (j = 0; j < teams.length; j++) {
games.push([maps[i], host, teams[j]]);
}
}
} else {
var map = maps.join(',');
for (j = 0; j < teams.length; j++) {
games.push([map, host, teams[j]]);
}
}
return games;
}
/**
* Doubles the number of games by swapping every game with a and b
* @param games
*/
function mirrorGames(games) {
var newArr = [];
var game;
for (var i = 0; i < games.length; i++) {
game = games[i];
newArr.push(game);
newArr.push([game[MAP], game[TEAM_B], game[TEAM_A]]);
}
return newArr;
}
function runMatches(maps, teams, host, series, replayFolder, csv, elo, mirror, noReplays, statsCache, doReport) {
var games, gamesLength;
if (host) {
games = _generateVsWorldGames(maps, teams, host, series);
} else {
games = _generateRoundRobinGames(maps, teams, series);
}
if (mirror) {
games = mirrorGames(games);
}
gamesLength = games.length;
console.log('Running', gamesLength, 'matches on', maps.length, 'maps between', teams.length, 'teams');
var gamesEnded = 0;
var dataCollector = new DataCollector();
function endGame(round, winner, map, teamA, teamB) {
if (!series) {
console.log(map, '[' + teamA +'/'+ teamB + ']', winner, round);
dataCollector.addGame(map, teamA, teamB, winner, round);
}
if (statsCache && doReport) {
request.post({
uri: 'http://' + path.join(statsCache, '/game/'),
qs: {
round: round,
winner: winner,
map: map,
teamA: teamA,
teamB: teamB
}
}, function(error, response, body) {
if (error) {
winston.error(error);
}
})
}
gamesEnded += 1;
startNextGame();
}
function endMatch() {
if (gamesEnded === gamesLength) {
if(host) {
dataCollector.printPlayerMapSummary(host, maps, series);
dataCollector.printHostSummary(host, teams);
} else {
dataCollector.printPlayersSummary(teams);
}
//writeCleanConf();
//writeCleanUI();
} else {
setTimeout(endMatch, 2000);
}
}
var calledEndMatch = false;
function startNextGame() {
if (games.length === 0) {
if (!calledEndMatch) {
calledEndMatch = true;
endMatch();
}
if (csv) {
dataCollector.saveAsCSV(series);
}
if (elo) {
if (host) {
teams.push(host);
}
dataCollector.computeELOs(teams, series);
}
return;
}
var game = games.shift();
// if we don't have a stats cache just start the game
if (!statsCache) {
computeNextGame();
} else {
// else check to see if we've computed it already first
request.get({
uri: 'http://' + path.join(statsCache, '/game/'),
qs: {
teamA: game[TEAM_A],
teamB: game[TEAM_B],
map: game[MAP]
}
}, function(error, response, body) {
if (error) {
winston.error(error);
}
if (body.indexOf('404') != -1) {
winston.info("not found, computing");
computeNextGame();
} else {
winston.info("Found!");
body = JSON.parse(body);
endGame(body.round, body.winner, body.map, body.teamA, body.teamB);
}
})
}
function computeNextGame() {
if (series) {
var seriesData = dataCollector.startSeries(game[MAP], game[TEAM_A], game[TEAM_B]);
runGame(game[MAP], game[TEAM_A], game[TEAM_B], seriesData, replayFolder, noReplays, endGame);
} else {
runGame(game[MAP], game[TEAM_A], game[TEAM_B], series, replayFolder, noReplays, endGame);
}
}
}
// tried starting multiple games at once but that had weird consequences
startNextGame();
}
module.exports.runMatches = runMatches;