Exemple #1
0
        public static int Execute(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                return(-1);
            }

            var considered = 0;
            var deleted    = 0;
            var map        = new HashSet <string>();

            foreach (var kvp in AITraining.GetTrainingFiles(path))
            {
                considered++;
                if (kvp.Value <= 0)
                {
                    // remove inputs that had no kills
                    Console.WriteLine("Removed {0}", kvp.Key);
                    File.Delete(kvp.Key);
                    deleted++;
                }
            }

            Console.WriteLine("Removed {0} of {1} files", deleted, considered);

            return(deleted);
        }
Exemple #2
0
        public shootMup()
        {
            InitializeComponent();

            try
            {
                SuspendLayout();

                // initial setup
                AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
                AutoScaleMode       = System.Windows.Forms.AutoScaleMode.Font;
                ClientSize          = new System.Drawing.Size(1484, 1075);
                Name           = "shootMup";
                Text           = "shootMup";
                DoubleBuffered = true;

                // generate players
                var human = new ShootMPlayer()
                {
                    Name = "You"
                };
                var players = new Player[100];
                for (int i = 0; i < players.Length; i++)
                {
                    players[i] = new SimpleAI()
                    {
                        Name = string.Format("ai{0}", i)
                    }
                }
                ;

                // generate the world
                World = WorldGenerator.Generate(WorldType.Random, PlayerPlacement.Borders, human, ref players);

                // if we are training for AI, then capture telemetry
                World.OnBeforeAction += AITraining.CaptureBefore;
                World.OnAfterAction  += AITraining.CaptureAfter;
                World.OnDeath        += (elem) =>
                {
                    if (elem is Player)
                    {
                        var winners = new List <string>();

                        // capture the winners
                        foreach (var player in players)
                        {
                            winners.Add(string.Format("{0} [{1}]", player.Name, player.Kills));
                        }

                        AITraining.CaptureWinners(winners);
                    }
                };

                UI = new UIHookup(this, World);
            }
            finally
            {
                ResumeLayout(false);
            }
        }
Exemple #3
0
        private void PlayerDied(Element element)
        {
            // check for winner/death (element may be any element that can take damage)
            if (element is Player)
            {
                // check how many players are still alive
                int    alive     = 0;
                var    toplayers = new Dictionary <string, int>();
                Player lastAlive = null;
                foreach (var player in Players)
                {
                    toplayers.Add(player.Name, player.Kills);
                    if (!player.IsDead)
                    {
                        alive++;
                        lastAlive = player;
                    }
                }
                Alive = alive;

                var winners = toplayers.OrderByDescending(kvp => kvp.Value).Select(kvp => string.Format("{0} [{1}]", kvp.Key, kvp.Value)).ToArray();

                if (element.Id == Human.Id || (alive == 1 && !Human.IsDead))
                {
                    if (Constants.CaptureAITrainingData)
                    {
                        AITraining.CaptureWinners(winners);
                    }

                    PlayerRank = alive;
                    Menu       = new Finish()
                    {
                        Kills      = Human.Kills,
                        Ranking    = PlayerRank,
                        Winner     = (alive == 1) ? Human.Name : "",
                        TopPlayers = winners
                    };
                    ShowMenu();

                    if (OnEnd != null)
                    {
                        OnEnd();
                    }
                }
                else if (alive == 1)
                {
                    if (Constants.CaptureAITrainingData)
                    {
                        AITraining.CaptureWinners(winners);
                    }

                    Menu = new Finish()
                    {
                        Kills      = Human.Kills,
                        Ranking    = PlayerRank,
                        Winner     = lastAlive.Name,
                        TopPlayers = winners
                    };
                    ShowMenu();

                    if (OnEnd != null)
                    {
                        OnEnd();
                    }
                }
            }
        }
Exemple #4
0
        private void AIMove(object state)
        {
            // block usage if a menu is being displayed
            if (Map.IsPaused)
            {
                return;
            }

            // move the AI
            int       index = (int)state;
            Stopwatch timer = new Stopwatch();

            timer.Start();
            if (Players[index] is AI)
            {
                AI    ai     = Players[index] as AI;
                float xdelta = 0;
                float ydelta = 0;
                float angle  = 0;

                // the timer is reentrant, so only allow one instance to run
                if (System.Threading.Interlocked.CompareExchange(ref ai.RunningState, 1, 0) != 0)
                {
                    return;
                }

                if (ai.IsDead)
                {
                    // drop the current players goodies
                    Map.Drop(ai);
                    ai.SwitchWeapon();
                    Map.Drop(ai);

                    // stop the timer
                    AITimers[index].Dispose();
                    return;
                }

                // NOTE: Do not apply the ZoomFactor (as it distorts the AI when debugging) - TODO may want to allow this while parachuting
                // TODO will likely want to translate into a copy of the list with reduced details
                List <Element> elements      = Map.WithinWindow(ai.X, ai.Y, Constants.ProximityViewWidth, Constants.ProximityViewHeight).ToList();
                var            angleToCenter = Collision.CalculateAngleFromPoint(ai.X, ai.Y, Background.X, Background.Y);
                var            inZone        = Background.Damage(ai.X, ai.Y) > 0;

                if (Constants.CaptureAITrainingData)
                {
                    // capture what the ai sees
                    AITraining.CaptureBefore(ai, elements, angleToCenter, inZone);
                }

                // get action from AI

                var action = ai.Action(elements, angleToCenter, inZone, ref xdelta, ref ydelta, ref angle);

                // turn
                ai.Angle = angle;

                // perform action
                bool result = false;
                Type item   = null;
                switch (action)
                {
                case ActionEnum.Drop:
                    item    = Map.Drop(ai);
                    result |= (item != null);
                    ai.Feedback(action, item, result);
                    break;

                case ActionEnum.Pickup:
                    item    = Map.Pickup(ai);
                    result |= (item != null);
                    ai.Feedback(action, item, result);
                    break;

                case ActionEnum.Reload:
                    var reloaded = ai.Reload();
                    result |= (reloaded == AttackStateEnum.Reloaded);
                    ai.Feedback(action, reloaded, result);
                    break;

                case ActionEnum.Attack:
                    var attack = Map.Attack(ai);
                    result |= attack == AttackStateEnum.FiredAndKilled || attack == AttackStateEnum.FiredWithContact ||
                              attack == AttackStateEnum.MeleeAndKilled || attack == AttackStateEnum.MeleeWithContact;
                    ai.Feedback(action, attack, result);
                    break;

                case ActionEnum.SwitchWeapon:
                    var swap = ai.SwitchWeapon();
                    result |= swap;
                    ai.Feedback(action, null, result);
                    break;

                case ActionEnum.Move:
                case ActionEnum.None:
                    break;

                default: throw new Exception("Unknown ai action : " + action);
                }

                // have the AI move
                float oxdelta = xdelta;
                float oydelta = ydelta;
                var   moved   = Map.Move(ai, ref xdelta, ref ydelta);
                ai.Feedback(ActionEnum.Move, null, moved);

                // ensure the player stays within the map
                if (ai.X < 0 || ai.X > Map.Width || ai.Y < 0 || ai.Y > Map.Height)
                {
                    System.Diagnostics.Debug.WriteLine("Out of bounds");
                }

                if (ai.RecordTraining)
                {
                    // capture what the ai sees
                    AITraining.CaptureAfter(ai, action, oxdelta, oydelta, angle,
                                            action == ActionEnum.None || action == ActionEnum.Move
                        ? moved
                        : result);
                }

                // set state back to not running
                System.Threading.Volatile.Write(ref ai.RunningState, 0);
            }
            timer.Stop();

            if (timer.ElapsedMilliseconds > 100)
            {
                System.Diagnostics.Debug.WriteLine("**AIMove Duration {0} ms", timer.ElapsedMilliseconds);
            }
        }
Exemple #5
0
        public void KeyPress(char key)
        {
            // inputs that are accepted while a menu is displaying
            if (Map.IsPaused)
            {
                switch (key)
                {
                // menu
                case Constants.Esc:
                    HideMenu();
                    break;
                }

                return;
            }

            // menu
            if (key == Constants.Esc)
            {
                ShowMenu();
                return;
            }

            // for training we track the human movements (as the supervised set)
            if (Human.RecordTraining)
            {
                // capture what the user sees
                List <Element> elements      = Map.WithinWindow(Human.X, Human.Y, Constants.ProximityViewWidth, Constants.ProximityViewHeight).ToList();
                var            angleToCenter = Collision.CalculateAngleFromPoint(Human.X, Human.Y, Background.X, Background.Y);
                var            inZone        = Background.Damage(Human.X, Human.Y) > 0;
                AITraining.CaptureBefore(Human, elements, angleToCenter, inZone);
            }

            // handle the user input
            ActionEnum action = ActionEnum.None;
            bool       result = false;
            float      xdelta = 0;
            float      ydelta = 0;

            switch (key)
            {
            // move
            case Constants.Down:
            case Constants.Down2:
            case Constants.DownArrow:
                ydelta = 1;
                break;

            case Constants.Left:
            case Constants.Left2:
            case Constants.LeftArrow:
                xdelta = -1;
                break;

            case Constants.Right:
            case Constants.Right2:
            case Constants.RightArrow:
                xdelta = 1;
                break;

            case Constants.Up:
            case Constants.Up2:
            case Constants.UpArrow:
                ydelta = -1;
                break;

            case Constants.Switch:
                action = ActionEnum.SwitchWeapon;
                result = SwitchWeapon(Human);
                break;

            case Constants.Pickup:
            case Constants.Pickup2:
                action = ActionEnum.Pickup;
                result = Pickup(Human);
                break;

            case Constants.Drop3:
            case Constants.Drop2:
            case Constants.Drop4:
            case Constants.Drop:
                action = ActionEnum.Drop;
                result = Drop(Human);
                break;

            case Constants.Reload:
            case Constants.MiddleMouse:
                action = ActionEnum.Reload;
                result = Reload(Human);
                break;

            case Constants.Space:
            case Constants.LeftMouse:
                action = ActionEnum.Attack;
                result = Attack(Human);
                break;

            case Constants.RightMouse:
                // use the mouse to move in the direction of the angle
                float r = (Human.Angle % 90) / 90f;
                xdelta = 1 * r;
                ydelta = 1 * (1 - r);
                if (Human.Angle > 0 && Human.Angle < 90)
                {
                    ydelta *= -1;
                }
                else if (Human.Angle > 180 && Human.Angle <= 270)
                {
                    xdelta *= -1;
                }
                else if (Human.Angle > 270)
                {
                    ydelta *= -1; xdelta *= -1;
                }
                break;
            }

            // if a move command, then move
            if (xdelta != 0 || ydelta != 0)
            {
                action = ActionEnum.Move;
                result = Move(Human, xdelta, ydelta);
            }

            // for training we track the human movements (as the supervised set)
            if (Human.RecordTraining)
            {
                // capture the result
                AITraining.CaptureAfter(Human, action, xdelta, ydelta, Human.Angle, result);
            }
        }
Exemple #6
0
        public static int Serialize(string path, string type, int remaining)
        {
            // validate type
            var action = ActionEnum.None;

            switch (type.ToLower())
            {
            case "angle": action = ActionEnum.Attack; break;

            case "xy": action = ActionEnum.Move; break;
            }
            if (remaining < 0)
            {
                remaining = Int32.MaxValue;
            }

            // load each model and then give a few predictions and check the results
            var duplicates = new HashSet <int>();

            using (var writer = File.CreateText(Path.Combine(path, "data.csv")))
            {
                foreach (var kvp in AITraining.GetTrainingFiles(path))
                {
                    var file  = kvp.Key;
                    var count = kvp.Value;

                    if (remaining <= 0)
                    {
                        break;
                    }

                    if (count > 0)
                    {
                        foreach (var d in AITraining.GetTraingingData(file))
                        {
                            if (remaining <= 0)
                            {
                                break;
                            }

                            if (d.Result && d.Z == 0)
                            {
                                var dm   = d.AsModelDataSet();
                                var hash = dm.ComputeHash();

                                // check type
                                if (action != ActionEnum.None && action != (ActionEnum)d.Action)
                                {
                                    continue;
                                }

                                // void duplicates
                                if (duplicates.Contains(hash))
                                {
                                    continue;
                                }

                                // write to disk
                                for (int i = 0; i < dm.Features(); i++)
                                {
                                    writer.Write("{0},", dm.Feature(i));
                                }
                                var outcome = dm.Action;
                                switch (action)
                                {
                                case ActionEnum.Move: outcome = dm.MoveAngle; break;

                                case ActionEnum.Attack: outcome = dm.FaceAngle; break;
                                }
                                writer.WriteLine("{0}", outcome);

                                // update
                                remaining--;
                                duplicates.Add(hash);
                            }
                        }
                    }
                }
            } // using writer

            return(0);
        }
Exemple #7
0
        public static int Check(string type, string path)
        {
            // load each model and then give a few predictions and check the results
            var rand = new Random();
            var data = new List <TrainingData>();
            var done = false;

            foreach (var kvp in AITraining.GetTrainingFiles(path))
            {
                if (done)
                {
                    break;
                }

                var file  = kvp.Key;
                var count = kvp.Value;

                if (count > 0)
                {
                    foreach (var d in AITraining.GetTraingingData(file))
                    {
                        if (done)
                        {
                            break;
                        }

                        if (d.Result && d.Z == 0)
                        {
                            // sample ~15%
                            if (rand.Next() % 6 == 0)
                            {
                                // test data set
                                data.Add(d);
                            }

                            if (data.Count > 1000)
                            {
                                done = true;
                            }
                        }
                    }
                }
            }

            foreach (var modelType in new ModelValue[]
            {
                ModelValue.Action,
                ModelValue.XY,
                ModelValue.Angle
            }
                     )
            {
                var map = new Dictionary <string, int>();

                var modelPath = "";
                if (modelType == ModelValue.Action)
                {
                    modelPath = string.Format("action.{0}.model", type);
                }
                else if (modelType == ModelValue.XY)
                {
                    modelPath = string.Format("xy.{0}.model", type);
                }
                else if (modelType == ModelValue.Angle)
                {
                    modelPath = string.Format("angle.{0}.model", type);
                }
                else
                {
                    throw new Exception("Unknown model type : " + modelType);
                }

                Model model = null;
                if (type.Equals("ml", StringComparison.OrdinalIgnoreCase))
                {
                    model = new ModelMLNet(Path.Combine(path, modelPath));
                }
                else
                {
                    model = new ModelOpenCV(Path.Combine(path, modelPath));
                }

                var delta = 0d;
                var count = 0;
                var timer = new Stopwatch();
                timer.Start();
                foreach (var d in data)
                {
                    var key = "";
                    if (false && modelType == ModelValue.XY)
                    {
                        float xdelta, ydelta;
                        model.Predict(d.AsModelDataSet(), out xdelta, out ydelta);
                        delta += Math.Abs(xdelta - d.Xdelta);
                        delta += Math.Abs(ydelta - d.Ydelta);
                        count += 2;

                        key = string.Format("{0},{1} {2},{3}", Math.Round(d.Xdelta, 1), Math.Round(d.Ydelta, 1), Math.Round(xdelta, 1), Math.Round(ydelta, 1));
                    }
                    else
                    {
                        var value = model.Predict(d.AsModelDataSet());

                        if (modelType == ModelValue.Action)
                        {
                            delta += Math.Abs(value - (float)d.Action);
                            key    = string.Format("{0},{1}", d.Action, Math.Round(value));
                        }
                        else if (modelType == ModelValue.Angle)
                        {
                            delta += Math.Abs(value - d.Angle);
                            key    = string.Format("{0},{1}", Math.Round(d.Angle), Math.Round(value));
                        }
                        else if (modelType == ModelValue.XY)
                        {
                            var moveAngle = Collision.CalculateAngleFromPoint(0, 0, d.Xdelta, d.Ydelta);

                            delta += Math.Abs(value - moveAngle);
                            key    = string.Format("{0},{1}", Math.Round(moveAngle), Math.Round(value));
                        }
                    }
                    if (!map.ContainsKey(key))
                    {
                        map.Add(key, 0);
                    }
                    map[key]++;
                }
                timer.Stop();

                Console.WriteLine("{0} has an average delta of {1:f2}.  This ran in {2}ms or {3:f2}ms per prediction", modelType, delta / (double)count, timer.ElapsedMilliseconds, (float)timer.ElapsedMilliseconds / (float)data.Count);

                foreach (var kvp in map.OrderByDescending(k => k.Value))
                {
                    Console.WriteLine("\t{0}\t{1}", kvp.Key, kvp.Value);
                }
            }

            return(0);
        }
Exemple #8
0
        public static int TrainAndEvaulate(string type, string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                return(-1);
            }

            // 1 in x of these will be picked up (the smaller the number the more of them
            var takeOnly   = 0;
            var rand       = new Random();
            var actionData = new DataSet()
            {
                TrainingCountMax = 150000
            };
            var xyData = new DataSet()
            {
                TrainingCountMax = 10000
            };
            var angleData = new DataSet()
            {
                TrainingCountMax = 150000
            };
            int trainingCount = 0, testCount = 0;
            var lastFile   = "";
            var duplicates = new HashSet <int>();

            foreach (var kvp in AITraining.GetTrainingFiles(path))
            {
                var file  = kvp.Key;
                var count = kvp.Value;
                lastFile = file;

                if (count > 0)
                {
                    // for debugging
                    if (takeOnly > 0 && --takeOnly == 0)
                    {
                        break;
                    }

                    // once enough data has been gathered, break
                    if (actionData.TrainingCountMax + xyData.TrainingCountMax + angleData.TrainingCountMax == 0)
                    {
                        break;
                    }

                    foreach (var d in AITraining.GetTraingingData(file))
                    {
                        if (d.Result)
                        {
                            var dm   = d.AsModelDataSet();
                            var hash = dm.ComputeHash();

                            // void duplicates
                            if (duplicates.Contains(hash))
                            {
                                continue;
                            }

                            // sample ~15% for test
                            if (rand.Next() % 6 == 0)
                            {
                                // test data set
                                testCount++;
                                if (actionData.TrainingCountMax > 0)
                                {
                                    actionData.Test.Add(dm);
                                }
                                switch ((ActionEnum)d.Action)
                                {
                                case ActionEnum.Attack:
                                    if (angleData.TrainingCountMax > 0)
                                    {
                                        angleData.Test.Add(dm);
                                    }
                                    break;

                                case ActionEnum.Move:
                                    if (xyData.TrainingCountMax > 0)
                                    {
                                        xyData.Test.Add(dm);
                                    }
                                    break;
                                }
                            }
                            else
                            {
                                // training data set
                                trainingCount++;
                                if (actionData.TrainingCountMax > 0)
                                {
                                    actionData.Training.Add(dm);
                                    actionData.TrainingCountMax--;
                                }
                                switch ((ActionEnum)d.Action)
                                {
                                case ActionEnum.Attack:
                                    if (angleData.TrainingCountMax > 0)
                                    {
                                        angleData.Training.Add(dm);
                                        angleData.TrainingCountMax--;
                                    }
                                    break;

                                case ActionEnum.Move:
                                    if (xyData.TrainingCountMax > 0 && !duplicates.Contains(hash))
                                    {
                                        xyData.Training.Add(dm);
                                        xyData.TrainingCountMax--;
                                    }
                                    break;
                                }
                            }

                            // add as a potential collision
                            duplicates.Add(hash);
                        } // is result
                    }     // foreach TrainingData
                }         // if count > 0
            }             // foreach file

            Console.WriteLine("Last file considered {0}", lastFile);

            Console.WriteLine("Training data set ({0} items) and test data set ({1} items)", trainingCount, testCount);
            Console.WriteLine("  Training: Action({0}) XY({1}) Angle({2})", actionData.Training.Count, xyData.Training.Count, angleData.Training.Count);
            Console.WriteLine("      Test: Action({0}) XY({1}) Angle({2})", actionData.Test.Count, xyData.Test.Count, angleData.Test.Count);

            // train
            shootMup.Bots.Model actions = null;
            if (type.Equals("ml", StringComparison.OrdinalIgnoreCase))
            {
                actions = new ModelMLNet(actionData.Training, ModelValue.Action);
            }
            else
            {
                actions = new ModelOpenCV(actionData.Training, ModelValue.Action);
            }
            actions.Save(Path.Combine(path, string.Format("action.{0}.model", type)));
            // evaluate
            var eval = actions.Evaluate(actionData.Test, ModelValue.Action);

            Console.WriteLine("Actions RMS={0} R^2={1}", eval.RMS, eval.RSquared);

            // train
            shootMup.Bots.Model xy = null;
            if (type.Equals("ml", StringComparison.OrdinalIgnoreCase))
            {
                xy = new ModelMLNet(xyData.Training, ModelValue.XY);
            }
            else
            {
                xy = new ModelOpenCV(xyData.Training, ModelValue.XY);
            }
            xy.Save(Path.Combine(path, string.Format("xy.{0}.model", type)));
            // evaluate
            eval = xy.Evaluate(xyData.Test, ModelValue.XY);
            Console.WriteLine("XY RMS={0} R^2={1}", eval.RMS, eval.RSquared);

            // train
            shootMup.Bots.Model angle = null;
            if (type.Equals("ml", StringComparison.OrdinalIgnoreCase))
            {
                angle = new ModelMLNet(angleData.Training, ModelValue.Angle);
            }
            else
            {
                angle = new ModelOpenCV(angleData.Training, ModelValue.Angle);
            }
            angle.Save(Path.Combine(path, string.Format("angle.{0}.model", type)));
            // evaluate
            eval = angle.Evaluate(angleData.Test, ModelValue.Angle);
            Console.WriteLine("Angle RMS={0} R^2={1}", eval.RMS, eval.RSquared);

            return(0);
        }