private static void PlayGame(string[] args) { var bots = args; AILog.Log("Creating game..."); var gameID = BotGameAPI.CreateGame(Enumerable.Range(10, bots.Length).Select(o => PlayerInvite.Create((PlayerIDType)o, PlayerInvite.NoTeam, null)), "PlayBots", null, gameSettings => { gameSettings["Fog"] = "NoFog"; //turn off fog so we can see what the AI is doing gameSettings["MaxCardsHold"] = 999; gameSettings["ReinforcementCard"] = "none"; }); AILog.Log("Created game " + gameID); var settings = BotGameAPI.GetGameSettings(gameID); var game = BotGameAPI.GetGameInfo(gameID, null); var botsDict = game.Players.Values.Zip(bots, (gp, bot) => new { Player = gp, Bot = bot }).ToDictionary(o => o.Player.ID, o => o.Bot); try { while (true) { game = BotGameAPI.GetGameInfo(gameID, null); if (game.State == GameState.Finished) { var winnerStr = game.Players.Values.Where(o => o.State == GamePlayerState.Won).Select(o => botsDict[o.ID]).JoinStrings(","); _totals.AddOrUpdate(winnerStr, 1, (_, i) => i + 1); Console.WriteLine("Game " + gameID + " finished. Winner=" + winnerStr + ", totals: " + _totals.OrderByDescending(o => o.Value).Select(o => o.Key + "=" + o.Value).JoinStrings(", ")); break; } var players = game.Players.Values.Where(o => o.State == GamePlayerState.Playing).ToList(); Action <GamePlayer> play = player => { var pg = BotGameAPI.GetGameInfo(gameID, player.ID); EntryPoint.PlayGame(botsDict[player.ID], pg, player.ID, settings.Item1, settings.Item2, picks => BotGameAPI.SendPicks(pg.ID, player.ID, picks), orders => BotGameAPI.SendOrders(pg.ID, player.ID, orders, pg.NumberOfTurns + 1)); }; if (args.Any(o => o.ToLower() == "parallel")) //note: Parallel won't work when teammates, cards, and limited holding cards are involved. { players.AsParallel().ForAll(play); } else { players.ForEach(play); } Thread.Sleep(100); } } finally { GameFinished(gameID); } }
public static void PlayForTurn(string botName, GameIDType gameID, int playForTurn) { AILog.Log("Generating orders for game " + gameID + " turn " + playForTurn); var settings = HumanGameAPI.GetGameSettings(gameID); var game = HumanGameAPI.GetGameInfo(gameID, playForTurn); EntryPoint.PlayGame(botName, game, MeID, settings.Item1, settings.Item2, picks => { }, orders => { }); }
private static void PlayGame(string[] args) { var botName = args[0]; AILog.Log("Creating game..."); var gameID = BotGameAPI.CreateGame(Enumerable.Range(10, 6).Select(o => PlayerInvite.Create((PlayerIDType)o, PlayerInvite.NoTeam, null)), "PlayFFA", null, gameSettings => //var gameID = BotGameAPI.CreateGame(Enumerable.Range(10, 6).Select(o => PlayerInvite.Create((PlayerIDType)o, (TeamIDType)(o == 0 ? 0 : 1), (SlotType)o)), "PlayFFA", 17, gameSettings => { //gameSettings["DistributionMode"] = 0; //full distribution, so we have plenty of starting territories //gameSettings["InitialNeutralsInDistribution"] = 2; //since we're full distribution, most territories an in-distribution one so we want them to start with 2s not 4s gameSettings["MaxCardsHold"] = 999; //gameSettings["AutomaticTerritoryDistribution"] = "Automatic"; }); AILog.Log("Created game " + gameID); var settings = BotGameAPI.GetGameSettings(gameID); try { while (true) { var game = BotGameAPI.GetGameInfo(gameID, null); if (game.State == GameState.Finished) { AILog.Log("Game finished: " + gameID); break; } var players = game.Players.Values.Where(o => o.State == GamePlayerState.Playing).ToList(); Action <GamePlayer> play = player => { var pg = BotGameAPI.GetGameInfo(gameID, player.ID); EntryPoint.PlayGame(botName, pg, player.ID, settings.Item1, settings.Item2, picks => BotGameAPI.SendPicks(pg.ID, player.ID, picks), orders => BotGameAPI.SendOrders(pg.ID, player.ID, orders, pg.NumberOfTurns + 1)); }; if (args.Any(o => o.ToLower() == "parallel")) //note: Parallel won't work when teammates, cards, and limited holding cards are involved. { players.AsParallel().ForAll(play); } else { players.ForEach(play); } Thread.Sleep(100); } } finally { GameFinished(gameID); } }
public static void PlayLoop(string botName, GameIDType gameID, PlayerIDType playerID) { var settings = HumanGameAPI.GetGameSettings(gameID); int turnNumber = int.MinValue; bool checkedAccept = false; while (true) { var status = HumanGameAPI.GetGameStatus(gameID); if (status.Item2 == GameState.WaitingForPlayers) { if (!checkedAccept) { var game = HumanGameAPI.GetGameInfo(gameID, null); if (game.Players[playerID].State == GamePlayerState.Invited) { AILog.Log("Accepting invite..."); HumanGameAPI.AcceptGame(gameID); AILog.Log("Accepted invite"); } checkedAccept = true; } } else if (status.Item2 == GameState.Finished) { AILog.Log("Game finished"); break; } else if (status.Item1 > turnNumber) { var game = HumanGameAPI.GetGameInfo(gameID, null); if (!EntryPoint.PlayGame(botName, game, MeID, settings.Item1, settings.Item2, picks => { HumanGameAPI.SendPicks(game.ID, picks); AILog.Log("Sent picks"); }, orders => { HumanGameAPI.SendOrders(game.ID, orders, game.NumberOfTurns + 1); AILog.Log("Sent orders"); })) { AILog.Log("We're no longer alive"); break; } turnNumber = status.Item1; } Thread.Sleep(10000); } }
public static void Create(string botName, string opponent, string gameName) { AILog.Log("Creating game..."); var gameID = HumanGameAPI.CreateGame(new[] { PlayerInvite.Create("me", (TeamIDType)0, null), PlayerInvite.Create("*****@*****.**", (TeamIDType)0, null), PlayerInvite.Create(opponent, (TeamIDType)1, null) }, gameName, null, settings => { settings["Fog"] = "NoFog"; //turn off fog so we can see what the AI is doing settings["MaxCardsHold"] = 999; //so AI doesn't have to discard //settings["OrderPriorityCard"] = "none"; //settings["OrderDelayCard"] = "none"; //settings["BlockadeCard"] = "none"; //settings["NumberOfCardsToReceiveEachTurn"] = 1; }); AILog.Log("Created game " + gameID); PlayLoop(botName, gameID, MeID); }
public static CardInstance ReadCardInstance(JToken jToken) { AILog.Log(jToken.ToString()); CardInstance ret; if (jToken["armies"] != null) { ret = new ReinforcementCardInstance(); ret.As <ReinforcementCardInstance>().Armies = (int)jToken["armies"]; } // ID 4 --> Order prio card else { ret = new CardInstance(); } ret.CardID = (CardIDType)(int)jToken["cardID"]; ret.ID = (CardInstanceIDType)Guid.Parse((string)jToken["cardInstanceID"]); return(ret); }
private static void PlayGame(string botName, int numOpponents) { var players = new[] { PlayerInvite.Create(MeID, (TeamIDType)1, null) }.Concat(Enumerable.Range(0, numOpponents).Select(o => PlayerInvite.Create("*****@*****.**", (TeamIDType)2, null))); AILog.Log("Creating game..."); var gameID = BotGameAPI.CreateGame(players, "AI Competition", null, gameSettings => gameSettings["MaxCardsHold"] = 999); AILog.Log("Created game " + gameID); var settings = BotGameAPI.GetGameSettings(gameID); try { while (true) { var game = BotGameAPI.GetGameInfo(gameID, MeID); if (game.State == GameState.Finished) { GameFinished(game); break; } if (!EntryPoint.PlayGame(botName, game, MeID, settings.Item1, settings.Item2, picks => BotGameAPI.SendPicks(game.ID, MeID, picks), orders => BotGameAPI.SendOrders(game.ID, MeID, orders, game.NumberOfTurns + 1))) { GameFinished(game); break; } Thread.Sleep(100); } } finally { ExportGame(gameID); BotGameAPI.DeleteGame(gameID); } }
public static bool PlayGame(string botName, GameObject game, PlayerIDType playerID, GameSettings settings, MapDetails map, Action <List <TerritoryIDType> > sendPicks, Action <List <GameOrder> > sendOrders) { if (game.State == GameState.WaitingForPlayers) { return(true); } if (!game.Players.ContainsKey(playerID)) { return(false); //not in game } if (game.Players[playerID].State == GamePlayerState.Invited) { throw new NotImplementedException("TODO: Accept the invite"); } if (game.Players[playerID].State != GamePlayerState.Playing) { return(false); //not alive anymore } var bot = BotFactory.Construct(botName); bot.Init(playerID, game.Players, map, game.LatestInfo.DistributionStanding, settings, game.NumberOfTurns, game.LatestInfo.Income, game.LatestInfo.LatestTurn == null ? null : game.LatestInfo.LatestTurn.Orders, game.LatestInfo.LatestStanding, game.LatestInfo.PreviousTurnStanding, game.LatestInfo.TeammatesOrders, game.LatestInfo.Cards, game.LatestInfo.CardsMustUse); AILog.Log("PlayGame. State=" + game.State + ", numTurns=" + game.NumberOfTurns + ", income=" + game.LatestInfo.Income[playerID] + ", cardsMustUse=" + game.LatestInfo.CardsMustUse); if (game.State == GameState.DistributingTerritories) { sendPicks(bot.GetPicks()); } else if (game.State == GameState.Playing) { sendOrders(bot.GetOrders()); } return(true); }
public static void Go(string[] args) { while (true) { var line = Console.ReadLine(); if (line == null) { break; } line = line.Trim(); if (line.Length == 0) { continue; } var parts = line.Split(' '); if (parts[0] == "pick_starting_region") { if (PickedTerritories == null) { InitBot(); PickedTerritories = Bot.GetPicks(); AILog.Log("Bot picked " + PickedTerritories.JoinToStrings(" ")); } var timeout = long.Parse(parts[1]); // pick which territories you want to start with var pickableStartingTerritories = parts.Skip(2).Select(o => (TerritoryIDType)int.Parse(o)).ToHashSet(false); var pick = PickedTerritories.Where(o => pickableStartingTerritories.Contains(o)).ToList(); if (pick.Count > 0) { Console.Out.WriteLine(pick[0]); } else { AILog.Log("None of bot's picks are still available, picking random"); Console.Out.WriteLine(pickableStartingTerritories.Random()); } } else if (parts[0] == "go") { var timeout = long.Parse(parts[2]); Assert.Fatal(parts.Length == 3); NumberOfTurns++; // we need to do a move var output = new StringBuilder(); if (parts[1] == "place_armies") { //Re-create the bot before every turn. This is done to simulate how the bot will run in production -- it can't be active and maintaining state for the entirety of a multi-day game, since those can take months or years. Instead, it will be created before each turn, ran once, then thrown away. InitBot(); CompletedOrders = Bot.GetOrders(); // place armies foreach (var move in CompletedOrders.OfType <GameOrderDeploy>()) { output.Append(GetDeployString(move) + ","); } } else if (parts[1] == "attack/transfer") { foreach (var move in CompletedOrders.OfType <GameOrderAttackTransfer>()) { output.Append(GetAttackString(move) + ","); } } else { throw new Exception("Unexpected " + parts[1]); } if (output.Length > 0) { Console.Out.WriteLine(output); } else { Console.Out.WriteLine("No moves"); } } else if (parts[0] == "settings" && parts[1] == "starting_regions") { foreach (var terrID in parts.Skip(2).Select(o => (TerritoryIDType)int.Parse(o))) { DistributionStanding.Territories[terrID].OwnerPlayerID = TerritoryStanding.AvailableForDistribution; } } else if (parts.Length == 3 && parts[0] == "settings") { UpdateSettings(parts[1], parts[2]); // update settings } else if (parts[0] == "setup_map") { SetupMap(parts); // initial full map is given } else if (parts[0] == "update_map") { PreviousTurnStanding = LatestTurnStanding; LatestTurnStanding = ReadMap(parts); } else if (parts[0] == "opponent_moves") { ReadOpponentMoves(parts); // all visible opponent moves are given } else { throw new Exception("Unable to parse line \"" + line + "\""); } } }