예제 #1
0
        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);
            }
        }
예제 #2
0
        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 => { });
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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 + "\"");
                }
            }
        }