Beispiel #1
0
        //--- Methods ---
        public async Task StartAsync(int botCount)
        {
            // reset game state
            GameSession.LastStatusUpdate = _provider.UtcNow;
            GameSession.CurrentGameTurn  = 0;
            GameSession.Missiles.Clear();
            GameSession.Messages.Clear();
            GameSession.Bots.Clear();
            for (var i = 0; i < botCount; ++i)
            {
                GameSession.Bots.Add(BotBuild.GetDefaultBotBuild(GameSession.Id, i));
            }

            // get configuration for all bots
            var messages = (await Task.WhenAll(GameSession.Bots.Select(bot => InitializeBotAsync(bot)))).ToList();

            foreach (var message in messages)
            {
                AddMessage(message);
            }

            // place bots on playfield
            var marginWidth  = GameSession.BoardWidth * 0.1f;
            var marginHeight = GameSession.BoardHeight * 0.1f;
            var attempts     = 0;

again:
            if (attempts >= 100)
            {
                throw new ApplicationException($"unable to place all bots with minimum separation of {GameSession.MinBotStartDistance:N2}");
            }

            // assign random locations to all bots
            foreach (var bot in GameSession.Bots.Where(bot => bot.Status == BotStatus.Alive))
            {
                bot.X = marginWidth + _provider.NextRandomFloat() * (GameSession.BoardWidth - 2.0f * marginWidth);
                bot.Y = marginHeight + _provider.NextRandomFloat() * (GameSession.BoardHeight - 2.0f * marginHeight);
            }

            // verify that none of the bots are too close to each other
            for (var i = 0; i < GameSession.Bots.Count; ++i)
            {
                for (var j = i + 1; j < GameSession.Bots.Count; ++j)
                {
                    if ((GameSession.Bots[i].Status == BotStatus.Alive) && (GameSession.Bots[j].Status == BotStatus.Alive))
                    {
                        var distance = GameMath.Distance(GameSession.Bots[i].X, GameSession.Bots[i].Y, GameSession.Bots[j].X, GameSession.Bots[j].Y);
                        if (distance < GameSession.MinBotStartDistance)
                        {
                            ++attempts;
                            goto again;
                        }
                    }
                }
            }
        }
Beispiel #2
0
        private async Task <string> InitializeBotAsync(BotInfo bot)
        {
            var config = await _provider.GetBotBuild(bot);

            bot.Name = config?.Name ?? $"#{bot.Index}";
            if (config is null)
            {
                // missing config information, consider bot dead
                bot.Status = BotStatus.Dead;
                bot.TimeOfDeathGameTurn = 0;
                return($"{bot.Name} (R{bot.Index}) was disqualified due to failure to initialize");
            }

            // read bot configuration
            var success          = true;
            var buildPoints      = 0;
            var buildDescription = new StringBuilder();

            // read radar configuration
            buildPoints += (int)config.Radar;
            buildDescription.Append($"{config.Radar} Radar");
            success &= BotBuild.TrySetRadar(config.Radar, bot);

            // read engine configuration
            buildPoints += (int)config.Engine;
            buildDescription.Append($", {config.Engine} Engine");
            success &= BotBuild.TrySetEngine(config.Engine, bot);

            // read armor configuration
            buildPoints += (int)config.Armor;
            buildDescription.Append($", {config.Armor} Armor");
            success &= BotBuild.TrySetArmor(config.Armor, bot);

            // read missile configuration
            buildPoints += (int)config.Missile;
            buildDescription.Append($", {config.Missile} Missile");
            success &= BotBuild.TrySetMissile(config.Missile, bot);

            // check if bot respected the max build points
            if (buildPoints > GameSession.MaxBuildPoints)
            {
                success = false;
            }

            // check if bot is disqualified due to a bad build
            if (!success)
            {
                bot.Status = BotStatus.Dead;
                bot.TimeOfDeathGameTurn = GameSession.CurrentGameTurn;
                return($"{bot.Name} (R{bot.Index}) was disqualified due to bad configuration ({buildDescription}: {buildPoints} points)");
            }
            bot.InternalState    = config.InternalStartState;
            bot.LastStatusUpdate = _provider.UtcNow;
            return($"{bot.Name} (R{bot.Index}) has joined the battle ({buildDescription}: {buildPoints} points)");
        }