Example #1
0
        private static void RunBot(string[] args)
        {
            if (args.Length != 1)
            {
                PrintUsage();
                return;
            }

            var outputPath = GetOutputPathFromArguments(args);

            var bot = new CharonBot(outputPath);
            bot.Execute();
        }
Example #2
0
        private static void RunBot(string[] args)
        {
            if (args.Length != 1)
            {
                PrintUsage();
                return;
            }

            var outputPath = GetOutputPathFromArguments(args);

            var bot = new CharonBot(outputPath);

            bot.Execute();
        }
Example #3
0
        private Wave CalculateShot(int waitingPeriod)
        {
            Alienmanager manager = new Alienmanager()
            {
                DeltaX         = this.otherGuy.AlienManager.DeltaX,
                Disabled       = this.otherGuy.AlienManager.Disabled,
                PlayerNumber   = this.otherGuy.PlayerNumber,
                ShotEnergy     = this.otherGuy.AlienManager.ShotEnergy,
                ShotEnergyCost = this.otherGuy.AlienManager.ShotEnergyCost,
                Waves          = CharonBot.WaveArrayDeepCopy(this.otherGuy.AlienManager.Waves)
            };
            List <Wave[]> orderedWaves = new List <Wave[]>(manager.Waves.OrderByDescending(w => w.First().Y).ToList());

            foreach (Wave[] waves in orderedWaves)
            {
                // For each row of aliens
                var wavesAndDelta = this.PredictAlienPositions(CharonBot.WaveListDeepCopy(orderedWaves), this.Deity.Ship.Y - waves[0].Y + waitingPeriod);

                List <Wave[]> predictedWaves = wavesAndDelta.Item1;
                int           leftOrRight    = wavesAndDelta.Item2 < 0 ? -1 : 1;

                // For each alien in the row, was it hit?
                foreach (Wave[] goatWave in predictedWaves)
                {
                    foreach (Wave alien in goatWave)
                    {
                        if (((alien.X == this.Deity.Ship.X + 1) || (alien.X == this.Deity.Ship.X + 1 + leftOrRight)) && waves.Any(a => a.Id == alien.Id))
                        {
                            if (this.CanShoot() && this.FindBlockage(this.Deity.Ship.Y, alien.Y, this.Deity.Ship.X + 1) == null)
                            {
                                return(alien);
                            }
                        }
                    }
                }
            }

            return(null);
        }
Example #4
0
        // The waitingPeriod is used to update the aliens for n extra turns, as if you were not going to shoot this round but rather wait n turns and want to see if it would be successful
        private Tuple <List <Wave[]>, int> PredictAlienPositions(List <Wave[]> waves, int roundsToCalculate)
        {
            waves = new List <Wave[]>(waves);

            Alienmanager manager = new Alienmanager()
            {
                DeltaX         = this.otherGuy.AlienManager.DeltaX,
                Disabled       = this.otherGuy.AlienManager.Disabled,
                PlayerNumber   = this.otherGuy.PlayerNumber,
                ShotEnergy     = this.otherGuy.AlienManager.ShotEnergy,
                ShotEnergyCost = this.otherGuy.AlienManager.ShotEnergyCost,
                Waves          = CharonBot.WaveArrayDeepCopy(this.otherGuy.AlienManager.Waves)
            };



            for (int x = 0; x < roundsToCalculate; x++) // Count through the moves that it would take to hit the alien
            {
                // The offset takes into account the  fact that the aliens are in a different row (due to moving down) and would be in a different horizontal position.
                // We check at the last predicted round in what position is the alien? But due to moving down we must check one row before..
                // Instead, look at the last row, but take into account the fact that we should check one row before (so basically just roll back the alien by one move per move down)

                bool topRowMySideContainsAlien       = this.gameMap.Rows[this.mapMiddleIndex].Any(r => r != null && r.Type.Equals("Alien"));
                bool secondTopRowMySideContainsAlien = this.gameMap.Rows[this.mapMiddleIndex + 1].Any(r => r != null && r.Type.Equals("Alien"));

                Wave[] possibleLefts  = new Wave[waves.Count];
                Wave[] possibleRights = new Wave[waves.Count];

                for (int i = 0; i < waves.Count; i++)
                {
                    possibleLefts[i] = waves[i].Aggregate((w1, w2) => w1.X < w2.X ? w1 : w2);
                }

                for (int i = 0; i < waves.Count; i++)
                {
                    possibleRights[i] = waves[i].Aggregate((w1, w2) => w1.X > w2.X ? w1 : w2);
                }

                Wave leftMost  = possibleLefts.Aggregate((w1, w2) => w1.X < w2.X ? w1 : w2);
                Wave rightMost = possibleRights.Aggregate((w1, w2) => w1.X > w2.X ? w1 : w2);

                Row atLeft  = leftMost.X > 0 && leftMost.Y < this.gameMap.Height ? this.gameMap.Rows[leftMost.Y][leftMost.X - 1] : null;
                Row atRight = rightMost.X < this.gameMap.Width - 1 && rightMost.Y < this.gameMap.Height ? this.gameMap.Rows[rightMost.Y][rightMost.X + 1] : null;

                // Aliens moving right
                if (manager.DeltaX > 0)
                {
                    // We spawn aliens after we have moved down, and when we are about to move in a new direction
                    if (atLeft != null && atLeft.Type.Equals("Wall") && !topRowMySideContainsAlien && !secondTopRowMySideContainsAlien)
                    {
                        waves = this.SpawnAliens(waves, true);
                    }

                    if (atRight != null && atRight.Type.Equals("Wall"))
                    {
                        foreach (Wave[] alienWave in waves)
                        {
                            foreach (Wave alien in alienWave)
                            {
                                alien.Y++;
                            }
                        }

                        roundsToCalculate--;
                        manager.DeltaX = -1;
                    }
                    else
                    {
                        foreach (Wave[] alienWave in waves)
                        {
                            foreach (Wave alien in alienWave)
                            {
                                alien.X++;
                            }
                        }
                    }
                }
                else     // Aliens moving left
                {
                    if (atRight != null && atRight.Type.Equals("Wall") && !topRowMySideContainsAlien && !secondTopRowMySideContainsAlien)
                    {
                        waves = this.SpawnAliens(waves, false);
                    }

                    if (atLeft != null && atLeft.Type.Equals("Wall"))
                    {
                        foreach (Wave[] alienWave in waves)
                        {
                            foreach (Wave alien in alienWave)
                            {
                                alien.Y++;
                            }
                        }

                        roundsToCalculate--;
                        manager.DeltaX = 1;
                    }
                    else
                    {
                        foreach (Wave[] alienWave in waves)
                        {
                            foreach (Wave alien in alienWave)
                            {
                                alien.X--;
                            }
                        }
                    }
                }
            }

            return(new Tuple <List <Wave[]>, int>(new List <Wave[]>(waves), manager.DeltaX));
        }
Example #5
0
        public string TryShift()
        {
            bool tooClose =
                (this.gameMap.Rows[this.Deity.Ship.Y].Any(
                     r => r != null && r.Type == "Alien" && (r.X > this.Deity.Ship.X - 2 || r.X < this.Deity.Ship.X + 5))) ||
                (this.gameMap.Rows[this.Deity.Ship.Y - 1].Any(
                     r => r != null && r.Type == "Alien" && (r.X > this.Deity.Ship.X - 2 || r.X < this.Deity.Ship.X + 5))) ||
                (this.gameMap.Rows[this.Deity.Ship.Y - 2].Any(
                     r => r != null && r.Type == "Alien" && (r.X > this.Deity.Ship.X - 2 || r.X < this.Deity.Ship.X + 5)));

            if (tooClose)
            {
                return(null);
            }

            Alienmanager manager = new Alienmanager()
            {
                DeltaX         = this.otherGuy.AlienManager.DeltaX,
                Disabled       = this.otherGuy.AlienManager.Disabled,
                PlayerNumber   = this.otherGuy.PlayerNumber,
                ShotEnergy     = this.otherGuy.AlienManager.ShotEnergy,
                ShotEnergyCost = this.otherGuy.AlienManager.ShotEnergyCost,
                Waves          =
                    CharonBot.WaveArrayDeepCopy(this.otherGuy.AlienManager.Waves)
            };
            List <Wave[]> orderedWaves = new List <Wave[]>(manager.Waves.OrderByDescending(w => w.First().Y).ToList());

            // For each row of aliens
            for (int wait = 1; wait < 5; wait++)
            {
                foreach (Wave[] waves in orderedWaves)
                {
                    var wavesAndDelta = this.PredictAlienPositions(
                        orderedWaves,
                        this.Deity.Ship.Y - waves[0].Y + wait);

                    List <Wave[]> predictedWaves = wavesAndDelta.Item1;

                    int leftOrRight = wavesAndDelta.Item2 < 0 ? -1 : 1;

                    foreach (Wave[] goatWave in predictedWaves)
                    {
                        foreach (Wave alien in goatWave)
                        {
                            // Use wait to check if the alien would be by left/right of me. Move in that direction to meet it in due time
                            if (waves.Any(a => a.Id == alien.Id))
                            {
                                if (((alien.X == this.Deity.Ship.X + 1 + wait) || (alien.X == this.Deity.Ship.X + 1 + leftOrRight + wait)))
                                {
                                    if (this.waveAndWait == null ||
                                        (this.waveAndWait != null && alien.Y < this.waveAndWait.Item1.Y &&
                                         wait < this.waveAndWait.Item2))
                                    {
                                        if (this.FindBlockage(this.Deity.Ship.Y, alien.Y, alien.X) == null &&
                                            this.CanMoveRight(this.Deity.Ship.X) &&
                                            !this.CheckDangerDeep(this.Deity.Ship.Y - 3, this.Deity.Ship.X + 2) &&
                                            !this.CheckDangerDeep(this.Deity.Ship.Y - 2, this.Deity.Ship.X + 3) &&
                                            alien.Y < this.Deity.Ship.Y - 2)
                                        {
                                            this.waveAndWait = null;
                                            return(CharonBot.Moves.MoveRight.ToString());
                                        }
                                    }
                                }

                                if (((alien.X == this.Deity.Ship.X + 1 - wait) || (alien.X == this.Deity.Ship.X + 1 + leftOrRight - wait)))
                                {
                                    if (this.waveAndWait == null ||
                                        (this.waveAndWait != null && alien.Y < this.waveAndWait.Item1.Y &&
                                         wait < this.waveAndWait.Item2))
                                    {
                                        if (this.FindBlockage(this.Deity.Ship.Y, alien.Y, alien.X) == null &&
                                            this.CanMoveLeft(this.Deity.Ship.X) &&
                                            !this.CheckDangerDeep(this.Deity.Ship.Y - 3, this.Deity.Ship.X) &&
                                            !this.CheckDangerDeep(this.Deity.Ship.Y - 2, this.Deity.Ship.X - 1) &&
                                            alien.Y < this.Deity.Ship.Y - 2)
                                        {
                                            this.waveAndWait = null;
                                            return(CharonBot.Moves.MoveLeft.ToString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            this.waveAndWait = null;
            return(null);
        }