Beispiel #1
0
        private static List <string> GetOrders(bool useTimeout, ManagedAI ai, Map map, int playerNumber)
        {
            if (playerNumber != 1 && playerNumber != 2)
            {
                throw new Exception("Invalid player number.");
            }

            List <string> orders   = null;
            List <string> mapState = playerNumber == 1 ? map.GetPlayerOneState() : map.GetPlayerTwoState();

            if (useTimeout)
            {
                var task = Task.Run(() => ai.GetOrders(mapState));
                if (task.Wait(TimeSpan.FromSeconds(1)))
                {
                    orders = task.Result;
                }
                else
                {
                    SetError(map, playerNumber, "Timed out");
                    return(null);
                }
            }
            else
            {
                orders = ai.GetOrders(mapState);
            }

            if (orders == null)
            {
                SetError(map, playerNumber, "AI Crashed");
            }

            return(orders);
        }
Beispiel #2
0
        // Will wait at most one second to get the error data - I've seen this just sit and do nothing.  Not sure why.
        private static void AppendCrashData(Map map, List <string> replayData, ManagedAI first, ManagedAI second)
        {
            if (map.PlayerOneError == "AI Crashed" || map.PlayerOneError == "Timed out")
            {
                var task = Task.Run(() => first.GetAllErrorLines().Select(x => $"1error# {x}"));
                if (task.Wait(TimeSpan.FromSeconds(1)))
                {
                    replayData.AddRange(task.Result);
                }
            }

            if (map.PlayerTwoError == "AI Crashed" || map.PlayerTwoError == "Timed out")
            {
                var task = Task.Run(() => second.GetAllErrorLines().Select(x => $"2error# {x}"));
                if (task.Wait(TimeSpan.FromSeconds(1)))
                {
                    replayData.AddRange(task.Result);
                }
            }
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            string mapPath      = "";
            string firstAIPath  = "";
            string secondAIPath = "";
            string replayPath   = "";
            bool   useTimeout   = true;

            var p = new OptionSet()
            {
                { "m|map=", "(required) the path to the map", v => mapPath = v },
                { "ai1|firstAI=", "(required) path to the first AI", v => firstAIPath = v },
                { "ai2|secondAI=", "(required) path to the first AI", v => secondAIPath = v },
                { "r|replayPath=", "(optional) path to where replay should be written.", v => replayPath = v },
                { "notimeout", "(optional) set if no timeout should be used (usually to attach debugger).", v => useTimeout = false }
            };

            try
            {
                p.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("planetwars: ");
                Console.WriteLine(e.Message);
                return;
            }

            if (mapPath == "" || firstAIPath == "" || secondAIPath == "")
            {
                WriteUsage(p);
                return;
            }

            string[] lines = File.ReadAllLines(mapPath);
            Map      map   = new Map(lines.ToList());

            List <string> replayData = new List <string>();

            replayData.Add(map.ToString());
            replayData.Add("go\n");
            ManagedAI first = new ManagedAI(firstAIPath);

            // There's probably a less stupid language construct like some try-with-resources thing that could make
            // sure we kill these processes, but I don't want to look it up.
            try
            {
                ManagedAI second = new ManagedAI(secondAIPath);

                try
                {
                    while (map.GetWinner() == -1)
                    {
                        // Get the orders.
                        List <string> playerOneOrders = GetOrders(useTimeout, first, map, 1);
                        List <string> playerTwoOrders = GetOrders(useTimeout, second, map, 2);
                        if (map.PlayerOneError != "" || map.PlayerTwoError != "")
                        {
                            // At least one AI timed out or crashed.
                            break;
                        }

                        // Filter out debug statements.
                        List <string> playerOneDebug          = new List <string>();
                        List <string> playerOneFilteredOrders = FilterOrders(playerOneOrders, playerOneDebug, 1);
                        List <string> playerTwoDebug          = new List <string>();
                        List <string> playerTwoFilteredOrders = FilterOrders(playerTwoOrders, playerTwoDebug, 2);

                        // Apply the orders.
                        map.ApplyOrders(playerOneFilteredOrders, playerTwoFilteredOrders);

                        // Update the replay.
                        replayData.Add(map.ToString());
                        replayData.AddRange(playerOneDebug);
                        replayData.AddRange(playerTwoDebug);
                        replayData.Add("go\n");
                    }

                    replayData.Add("GAME OVER");
                    replayData.Add($"LENGTH: {map.TurnNumber}");
                    replayData.Add($"P1ERROR: {map.PlayerOneError}");
                    replayData.Add($"P2ERROR: {map.PlayerTwoError}");
                    replayData.Add($"WINNER: {map.GetWinner()}");
                    replayData.Add("");
                    AppendCrashData(map, replayData, first, second);

                    replayData.ForEach(x => Console.WriteLine(x));

                    if (replayPath != "")
                    {
                        try
                        {
                            File.WriteAllLines(replayPath, replayData);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"Couldn't write replay at {replayPath}");
                            Console.WriteLine(e.Message);
                        }
                    }
                }
                catch (Exception e)
                {
                    second.EndProcess();
                    throw e;
                }

                second.EndProcess();
            }
            catch (Exception e)
            {
                first.EndProcess();
                throw e;
            }

            first.EndProcess();
        }