private string EnumerateSolutionIssues(int waveIndex, WaveSolution solution)
        {
            bool      issuesFound  = false;
            string    issuesString = "";
            WaveStats stats        = WaveStatList[waveIndex];

            //
            // Is it possible to afford this solution?
            //

            if (stats.CoinAvail < stats.CoinNeeded)
            {
                issuesFound   = true;
                issuesString += "Can't afford at start of wave  ";
            }

            //
            // Are all the enemies killed in simulation?
            //

            if (LevelDesc.Waves[waveIndex].Count > stats.FullSimulation.EnemiesKilled)
            {
                issuesFound   = true;
                issuesString += "Enemies survived simulation  ";
            }

            if (!issuesFound)
            {
                return("<span foreground='green'>None</span>");
            }

            return("<span foreground='red'>" + issuesString + "</span>");
        }
Exemple #2
0
        public bool Same(WaveSolution s)
        {
            if (s.Turrets.Count != Turrets.Count)
            {
                return(false);
            }

            for (int i = 0; i < Turrets.Count; i++)
            {
                if (Turrets[i].Name != s.Turrets[i].Name)
                {
                    return(false);
                }
                if (Turrets[i].pos.x != s.Turrets[i].pos.x)
                {
                    return(false);
                }
                if (Turrets[i].pos.z != s.Turrets[i].pos.z)
                {
                    return(false);
                }
            }

            return(true);
        }
        private WaveSolution GenerateWaveSolution()
        {
            WaveSolution sol = new WaveSolution();


            for (int i = 0; i < LevelDesc.Map.Count; i++)
            {
                if (LevelDesc.Map[i] == 'T')
                {
                    int turretIndex = 0;

                    if (TurretSelections.TryGetValue(i, out turretIndex))
                    {
                        WaveSolutionTurret t = new WaveSolutionTurret();

                        t.pos.x = (i % LevelDesc.FieldWidth);
                        t.pos.z = (i / LevelDesc.FieldDepth);
                        t.Name  = LevelDesc.AllowedTurrets[turretIndex];

                        sol.Turrets.Add(t);
                    }
                }
            }

            return(sol);
        }
        private void SaveSolutionClicked(TreeIter iter)
        {
            int    row    = (int)WavesModel.GetValue(iter, 0);
            string action = (string)WavesModel.GetValue(iter, 9);

            if (action != "Save")
            {
                return;
            }

            WaveSolution sol = GenerateWaveSolution();

            sol.WaveIndex = row;

            for (int i = 0; i < Solution.WaveSolutions.Count; i++)
            {
                if (Solution.WaveSolutions[i].WaveIndex == row)
                {
                    Solution.WaveSolutions.RemoveAt(i);
                    break;
                }
            }

            Solution.WaveSolutions.Add(sol);
            WriteSolution();

            RecalculateAllStats();
            PopulateTreeWithWaves(LevelDesc);
        }
Exemple #5
0
        public WaveSimulatorDamageStats SimulateDamageToEnemies(
            EnemyDescription enemy,
            WaveSolution solution,
            float HandMissileFreqency,
            float HandMissileDamantPctAverage,
            int enemyCount,
            bool invincible)
        {
            DamageStats       = new WaveSimulatorDamageStats();
            InvincibleEnemies = invincible;

            float waveTime  = 0.0F;
            float timeDelta = 1.0F / 72.0F;
            float previousHandMissileTime = 0.0f;

            EnemyWave waveDesc = new EnemyWave();

            waveDesc.Count = enemyCount;
            waveDesc.Enemy = enemy.Name;
            waveDesc.DifficultyMultiplier = 1.0F;

            ResetLevelDescState(LevelDesc);
            TurretManager     turrets     = new TurretManager(LevelDesc);
            ProjectileManager projectiles = new ProjectileManager(LevelDesc, LevelManager.LookupProjectile);
            WaveInstance      wave        = new WaveInstance(LevelDesc, waveDesc, enemy, 0.0F, SimulatorDamageCallback);

            for (int i = 0; i < solution.Turrets.Count; i++)
            {
                turrets.AddTurret(LevelManager.LookupTurret(solution.Turrets[i].Name), solution.Turrets[i].pos, projectiles);
            }

            Debug.Log("----------------------------------------");
            Debug.Log("   Wave of " + enemyCount + " " + enemy.Name + "s");
            Debug.Log("----------------------------------------");

            do
            {
                wave.Advance(waveTime);
                projectiles.AdvanceAll(waveTime);
                turrets.Fire(waveTime);

                float timeSinceLastHandMissile = waveTime - previousHandMissileTime;

                if (timeSinceLastHandMissile >= HandMissileFreqency)
                {
                    // Real projectiles have to incur flight time but we'll simulate
                    // the damage as instanntaneous to keep it simple.  Also real projectiles
                    // have blast radius that should hit multiple enemies. We'll just hit one.
                }

                waveTime += timeDelta;
            } while (!wave.IsCompleted);

            DamageStats.DamagePerEnemy = DamageStats.DamageDealt / enemyCount;

            return(DamageStats);
        }
        private void SetSolution(WaveSolution sol)
        {
            TurretSelections.Clear();
            int turretCount = 0;

            for (int i = 0; i < LevelDesc.Map.Count; i++)
            {
                if (LevelDesc.Map[i] == 'T')
                {
                    int    x = i % LevelDesc.FieldWidth;
                    int    z = i / LevelDesc.FieldDepth;
                    Button b = MapButtons[i];

                    bool turretMatch = false;
                    for (int j = 0; j < sol.Turrets.Count; j++)
                    {
                        if ((sol.Turrets[j].pos.x == x) &&
                            (sol.Turrets[j].pos.z == z))
                        {
                            TurretSelections.Add(i, AllowedTurretIndexFromName(sol.Turrets[j].Name));

                            // Update location on map
                            UpdateFieldTurretButton(b, sol.Turrets[j].Name);
                            turretCount++;
                            turretMatch = true;
                        }
                    }
                    if (!turretMatch)
                    {
                        UpdateFieldTurretButton(b, "None");
                    }
                }
            }

            if (turretCount != sol.Turrets.Count)
            {
                MessageDialog md = new MessageDialog(null,
                                                     DialogFlags.Modal, MessageType.Warning,
                                                     ButtonsType.OkCancel, "Some turret positions do not match turret slots - did the map change?  Dropped the turrets that don't match.");
                int result = md.Run();
                md.Destroy();
            }

            RecalculateAllStats();
            PopulateTreeWithWaves(LevelDesc);
        }
        private void CalculateStatsForWaves(List <TurretStats> Turrets)
        {
            WaveStatList = new List <WaveStats>();

            float maxDPSOverall = 0.0F;
            int   coinNeeded    = 0;

            for (int j = 0; j < Turrets.Count; j++)
            {
                maxDPSOverall += Turrets[j].MaxDPSOverall;
                coinNeeded    += Turrets[j].t.Cost;
            }

            int maxCoinEarned = LevelDesc.StartingCoins;

            for (int i = 0; i < LevelDesc.Waves.Count; i++)
            {
                EnemyWave        wave      = LevelDesc.Waves[i];
                EnemyDescription enemyDesc = LevelManager.LookupEnemy(wave.Enemy);
                WaveSolution     solution  = GenerateWaveSolution();
                WaveStats        stats     = new WaveStats();

                WaveSimulatorDamageStats singleEnemyStats = SimulateWave(enemyDesc, solution, 1, true);
                WaveSimulatorDamageStats fullWaveStats    = SimulateWave(enemyDesc, solution, wave.Count, false);

                EnemyDescription enemy = LevelManager.LookupEnemy(wave.Enemy);
                stats.MaxDmgDealtSingleEnemy = singleEnemyStats.DamageDealt;
                stats.MaxDPSOverall          = maxDPSOverall;
                stats.MaxHPPSProducted       = EnemyEditLayout.CalculateDPSforWave(enemy);
                stats.FullSimulation         = fullWaveStats;
                stats.CoinNeeded             = coinNeeded;
                stats.CoinAvail = maxCoinEarned;

                maxCoinEarned += (enemy.Coins * wave.Count);

                WaveStatList.Add(stats);
            }
        }
        private void PopulateTreeWithWaves(LevelDescription desc)
        {
            WavesModel.Clear();
            WaveSolution currentSolution = GenerateWaveSolution();
            Dictionary <int, WaveSolution> waveSolves = new Dictionary <int, WaveSolution>();

            for (int i = 0; i < Solution.WaveSolutions.Count; i++)
            {
                waveSolves.Add(Solution.WaveSolutions[i].WaveIndex, Solution.WaveSolutions[i]);
            }

            for (int i = 0; i < desc.Waves.Count; i++)
            {
                string       saveString = "Save";
                string       loadString = "n/a";
                WaveSolution solution   = null;
                if (waveSolves.TryGetValue(i, out solution))
                {
                    if (solution.Same(currentSolution))
                    {
                        saveString = "n/a";
                        loadString = "n/a";
                    }
                    else
                    {
                        saveString = "Save";
                        loadString = "Load";
                    }
                }

                string   simDamageKills = WaveStatList[i].FullSimulation.DamagePerEnemy.ToString() + "/" + WaveStatList[i].FullSimulation.EnemiesKilled;
                string   coinString     = WaveStatList[i].CoinNeeded.ToString() + "/" + WaveStatList[i].CoinAvail.ToString();
                string   issues         = EnumerateSolutionIssues(i, currentSolution);
                object[] values         = { i, desc.Waves[i].Enemy, desc.Waves[i].Count, desc.Waves[i].DifficultyMultiplier, WaveStatList[i].MaxDmgDealtSingleEnemy, WaveStatList[i].MaxHPPSProducted, WaveStatList[i].MaxDPSOverall, simDamageKills, coinString, saveString, loadString, issues };
                WavesModel.AppendValues(values);
            }
        }
        private WaveSimulatorDamageStats SimulateWave(EnemyDescription enemy, WaveSolution solution, int enemyCount, bool invincible)
        {
            WaveSimulator sim = new WaveSimulator(LevelDesc);

            return(sim.SimulateDamageToEnemies(enemy, solution, HandMissileFreqency, HandMissileDamantPctAverage, enemyCount, invincible));
        }