Example #1
0
 // St1撃墜を行う(敵艦隊)
 private static int CalcKilledSlot(int slot, AirWarStatus aws)
 {
     return(killedSlot[slot][(int)aws][random.Next(st1Range[(int)aws])]);
 }
Example #2
0
 private static void LostEnemySlotBySt1(FleetData fleet, ref List <List <List <int> > > slotData, AirWarStatus aws)
 {
     // 計算
     for (int ui = 0; ui < fleet.Kammusu.Count; ++ui)
     {
         for (int ki = 0; ki < fleet.Kammusu[ui].Count; ++ki)
         {
             var kammusu = fleet.Kammusu[ui][ki];
             for (int wi = 0; wi < kammusu.Weapon.Count; ++wi)
             {
                 // St1撃墜を計算して書き戻す
                 slotData[ui][ki][wi] = CalcKilledSlot(slotData[ui][ki][wi], aws);
             }
         }
     }
 }
Example #3
0
 // ステージ1撃墜処理(基地航空隊)
 private static void St1LandBaseBreak(LandBase landBase, LandBaseAirsList landBaseAirsList, int ti, AirWarStatus airWarStatus)
 {
     for (int wi = 0; wi < landBase.Team[ti].Weapon.Count; ++wi)
     {
         if (!landBase.Team[ti].Weapon[wi].IsStage1X)
         {
             continue;
         }
         int breakCount = landBaseAirsList[ti][wi] * RandInt(St1FriendBreakMin[(int)airWarStatus], St1FriendBreakMax[(int)airWarStatus]) / 256;
         landBaseAirsList[ti][wi] -= breakCount;
     }
 }
Example #4
0
        // ステージ1撃墜処理(敵軍)
        private static void St1EnemyBreak(Fleet enemy, int unitCount, AirsList enemyAirsList, AirWarStatus airWarStatus)
        {
            int St1EnemyBreakConstantNow = St1EnemyBreakConstant[(int)airWarStatus];

            for (int i = 0; i < unitCount; ++i)
            {
                for (int j = 0; j < enemy.Unit[i].Kammusu.Count; ++j)
                {
                    for (int k = 0; k < enemy.Unit[i].Kammusu[j].Weapon.Count; ++k)
                    {
                        if (!enemy.Unit[i].Kammusu[j].Weapon[k].IsStage1)
                        {
                            continue;
                        }
                        // 例の式で計算
                        // https://docs.google.com/spreadsheets/d/1RTOztxst5pFGCi-Qr8dw6DZwYw0jd8fkymGg44dapAk/edit
                        int breakCount = (int)(enemyAirsList[i][j][k] * (0.35 * RandInt(0, St1EnemyBreakConstantNow) + 0.65 * RandInt(0, St1EnemyBreakConstantNow)) / 10);
                        enemyAirsList[i][j][k] -= breakCount;
                    }
                }
            }
        }
Example #5
0
 // ステージ1撃墜処理(自軍)
 private static void St1FriendBreak(Fleet friend, int unitCount, AirsList friendAirsList, AirWarStatus airWarStatus)
 {
     for (int i = 0; i < unitCount; ++i)
     {
         for (int j = 0; j < friend.Unit[i].Kammusu.Count; ++j)
         {
             for (int k = 0; k < friend.Unit[i].Kammusu[j].Weapon.Count; ++k)
             {
                 if (!friend.Unit[i].Kammusu[j].Weapon[k].IsStage1)
                 {
                     continue;
                 }
                 int breakCount = friendAirsList[i][j][k] * RandInt(St1FriendBreakMin[(int)airWarStatus], St1FriendBreakMax[(int)airWarStatus]) / 256;
                 friendAirsList[i][j][k] -= breakCount;
             }
         }
     }
 }
Example #6
0
        // モンテカルロシミュレーション(基地航空隊がない場合)
        public static string MonteCarloImpl(Fleet friend, Fleet enemy, int simulationSize)
        {
            string output = "【モンテカルロシミュレーション】\n";

            output += $"反復回数:{simulationSize}回\n";
            // 初期状態を記録する
            var firstFriendAirsList = friend.AirsList;
            var firstEnemyAirsList  = enemy.AirsList;

            // 保存用バッファを用意する
            MakeLists(firstFriendAirsList, out friendKammusuList, out friendLeaveAirsList);
            MakeLists(firstEnemyAirsList, out enemyKammusuList, out enemyLeaveAirsList);
            // 反復計算を行う
            var friendAirsList    = DeepCopyHelper.DeepCopy(firstFriendAirsList);
            var enemyAirsList     = DeepCopyHelper.DeepCopy(firstEnemyAirsList);
            var AirWarStatusCount = new List <int> {
                0, 0, 0, 0, 0
            };
            int unitCount = UnitCount(enemy.Unit.Count, friend.Unit.Count);

            for (int i = 0; i < simulationSize; ++i)
            {
                // 状態を初期化する
                CopyAirsList(firstFriendAirsList, friendAirsList);
                CopyAirsList(firstEnemyAirsList, enemyAirsList);
                #region ステージ1:航空戦
                // 制空値を計算する
                int friendAirValue = NowAirValue(friend, unitCount, friendAirsList);
                int enemyAirValue  = NowAirValue(enemy, unitCount, enemyAirsList);
                // 制空状態を判断する
                AirWarStatus airWarStatus = CalcAirWarStatus(friendAirValue, enemyAirValue);
                ++AirWarStatusCount[(int)airWarStatus];
                // 割合撃墜を行う
                St1FriendBreak(friend, unitCount, friendAirsList, airWarStatus);
                St1EnemyBreak(enemy, unitCount, enemyAirsList, airWarStatus);
                #endregion
                #region ステージ2:対空砲火
                var friendCutInType = GetCutInType(friend);
                var enemyCutInType  = GetCutInType(enemy);
                St2FriendBreak(friend, enemy, unitCount, friendAirsList, enemyCutInType);
                St2EnemyBreak(enemy, friend, unitCount, enemyAirsList, friendCutInType);
                #endregion
                // 残数を記録する
                MemoLeaveList(friend, friendAirsList, friendKammusuList, friendLeaveAirsList);
                MemoLeaveList(enemy, enemyAirsList, enemyKammusuList, enemyLeaveAirsList);
            }
            // 結果を書き出す
            output += "【制空状態】\n";
            output += "本隊";
            for (int i = 0; i < (int)AirWarStatus.Size; ++i)
            {
                var i2 = (AirWarStatus)i;
                output += $" {i2.ToStr()}:{Math.Round(100.0 * AirWarStatusCount[i] / simulationSize, 1)}%";
            }
            output += "\n";
            output += "【棒立ち率 [スロット毎の全滅率]】\n";
            output += "自艦隊:\n";
            for (int i = 0; i < friendKammusuList.Count; ++i)
            {
                for (int j = 0; j < friendKammusuList[i].Count; ++j)
                {
                    int sum = firstFriendAirsList[i][j].Sum();
                    if (sum > 0)
                    {
                        output += $"{friend.Unit[i].Kammusu[j].Name}→{Math.Round(100.0 * friendKammusuList[i][j] / simulationSize, 1)}%";
                        for (int k = 0; k < friend.Unit[i].Kammusu[j].SlotCount; ++k)
                        {
                            if (firstFriendAirsList[i][j][k] > 0)
                            {
                                output += $" {k + 1}:[{Math.Round(100.0 * friendLeaveAirsList[i][j][k][0] / simulationSize, 1)}%]";
                            }
                        }
                        output += "\n";
                    }
                }
            }
            output += "敵艦隊:\n";
            for (int i = 0; i < enemyKammusuList.Count; ++i)
            {
                for (int j = 0; j < enemyKammusuList[i].Count; ++j)
                {
                    int sum = firstEnemyAirsList[i][j].Sum();
                    if (sum > 0)
                    {
                        output += $"{enemy.Unit[i].Kammusu[j].Name}→{Math.Round(100.0 * enemyKammusuList[i][j] / simulationSize, 1)}%";
                        for (int k = 0; k < enemy.Unit[i].Kammusu[j].SlotCount; ++k)
                        {
                            if (firstEnemyAirsList[i][j][k] > 0)
                            {
                                output += $" {k + 1}:[{Math.Round(100.0 * enemyLeaveAirsList[i][j][k][0] / simulationSize, 1)}%]";
                            }
                        }
                        output += "\n";
                    }
                }
            }
            return(output);
        }
Example #7
0
        // モンテカルロシミュレーション(基地航空隊がある場合)
        public static string MonteCarloImpl(Fleet friend, Fleet enemy, LandBase landBase, int simulationSize)
        {
            string output = "【モンテカルロシミュレーション】\n";

            output += $"反復回数:{simulationSize}回\n";
            // 初期状態を記録する
            var firstFriendAirsList   = friend.AirsList;
            var firstLandBaseAirsList = landBase.AirsList;
            var firstEnemyAirsList    = enemy.AirsList;

            // 保存用バッファを用意する
            MakeLists(firstFriendAirsList, out friendKammusuList, out friendLeaveAirsList);
            MakeLists(firstLandBaseAirsList, out landBaseList, out landBaseLeaveAirsList);
            MakeLists(firstEnemyAirsList, out enemyKammusuList, out enemyLeaveAirsList);
            // 反復計算を行う
            var friendAirsList    = DeepCopyHelper.DeepCopy(firstFriendAirsList);
            var landBaseAirsList  = DeepCopyHelper.DeepCopy(firstLandBaseAirsList);
            var enemyAirsList     = DeepCopyHelper.DeepCopy(firstEnemyAirsList);
            var AirWarStatusCount = new List <List <int> >();

            for (int ti = 0; ti <= landBase.TeamCount; ++ti)
            {
                AirWarStatusCount.Add(new List <int> {
                    0, 0, 0, 0, 0
                });
            }
            int unitCount = UnitCount(enemy.Unit.Count, friend.Unit.Count);

            for (int i = 0; i < simulationSize; ++i)
            {
                // 状態を初期化する
                CopyAirsList(firstFriendAirsList, friendAirsList);
                CopyAirsList(firstLandBaseAirsList, landBaseAirsList);
                CopyAirsList(firstEnemyAirsList, enemyAirsList);
                // 基地航空隊
                for (int ti = 0; ti < landBase.TeamCount; ++ti)
                {
                    for (int ai = 0; ai < landBase.AttackCount[ti]; ++ai)
                    {
                        #region ステージ1:航空戦
                        // 制空値を計算する
                        int landBaseAirValue = NowAirValueX(landBase, landBaseAirsList, ti);
                        int enemyAirValue_   = NowAirValueX(enemy, enemy.Unit.Count, enemyAirsList);
                        // 制空状態を判断する
                        AirWarStatus airWarStatus_ = CalcAirWarStatus(landBaseAirValue, enemyAirValue_);
                        // 割合撃墜を行う
                        // 基地航空隊を集中運用した際、1回目に来た際撃墜された分は
                        // 2回目発動前に自動回復する(ここでの資源消費はないが熟練度はハゲる)
                        if (landBase.AttackCount[ti] == 1 || ai == 1)
                        {
                            ++AirWarStatusCount[ti][(int)airWarStatus_];
                            St1LandBaseBreak(landBase, landBaseAirsList, ti, airWarStatus_);
                        }
                        St1EnemyBreak(enemy, enemy.Unit.Count, enemyAirsList, airWarStatus_);
                        #endregion
                        if (landBase.AttackCount[ti] == 1 || ai == 1)
                        {
                            #region ステージ2:対空砲火
                            var enemyCutInType_ = GetCutInType(enemy);
                            St2LandBaseBreak(landBase, enemy, landBaseAirsList, ti, enemyCutInType_);
                            #endregion
                        }
                    }
                }
                // 艦隊戦
                #region ステージ1:航空戦
                // 制空値を計算する
                int friendAirValue = NowAirValue(friend, unitCount, friendAirsList);
                int enemyAirValue  = NowAirValue(enemy, unitCount, enemyAirsList);
                // 制空状態を判断する
                AirWarStatus airWarStatus = CalcAirWarStatus(friendAirValue, enemyAirValue);
                ++AirWarStatusCount[landBase.TeamCount][(int)airWarStatus];
                // 割合撃墜を行う
                St1FriendBreak(friend, unitCount, friendAirsList, airWarStatus);
                St1EnemyBreak(enemy, unitCount, enemyAirsList, airWarStatus);
                #endregion
                #region ステージ2:対空砲火
                var friendCutInType = GetCutInType(friend);
                var enemyCutInType  = GetCutInType(enemy);
                St2FriendBreak(friend, enemy, unitCount, friendAirsList, enemyCutInType);
                St2EnemyBreak(enemy, friend, unitCount, enemyAirsList, friendCutInType);
                #endregion
                // 残数を記録する
                MemoLeaveList(friend, friendAirsList, friendKammusuList, friendLeaveAirsList);
                MemoLeaveList(landBase, landBaseAirsList, landBaseList, landBaseLeaveAirsList);
                MemoLeaveList(enemy, enemyAirsList, enemyKammusuList, enemyLeaveAirsList);
            }
            // 結果を書き出す
            output += "【制空状態】\n";
            for (int ti = 0; ti <= landBase.TeamCount; ++ti)
            {
                output += (ti == landBase.TeamCount ? "本隊" : $"基地-{ti + 1}");
                for (int i = 0; i < (int)AirWarStatus.Size; ++i)
                {
                    var i2 = (AirWarStatus)i;
                    output += $" {i2.ToStr()}:{Math.Round(100.0 * AirWarStatusCount[ti][i] / simulationSize, 1)}%";
                }
                output += "\n";
            }
            output += "【棒立ち率 [スロット毎の全滅率]】\n";
            output += "自艦隊:\n";
            for (int i = 0; i < friendKammusuList.Count; ++i)
            {
                for (int j = 0; j < friendKammusuList[i].Count; ++j)
                {
                    int sum = firstFriendAirsList[i][j].Sum();
                    if (sum > 0)
                    {
                        output += $"{friend.Unit[i].Kammusu[j].Name}→{Math.Round(100.0 * friendKammusuList[i][j] / simulationSize, 1)}%";
                        for (int k = 0; k < friend.Unit[i].Kammusu[j].SlotCount; ++k)
                        {
                            if (firstFriendAirsList[i][j][k] > 0)
                            {
                                output += $" {k+1}:[{Math.Round(100.0 * friendLeaveAirsList[i][j][k][0]/ simulationSize, 1)}%]";
                            }
                        }
                        output += "\n";
                    }
                }
            }
            output += "基地航空隊:\n";
            for (int ti = 0; ti < landBase.TeamCount; ++ti)
            {
                output += $"基地-{ti + 1}→{Math.Round(100.0 * landBaseList[ti] / simulationSize, 1)}%";
                for (int wi = 0; wi < landBase.Team[ti].Weapon.Count; ++wi)
                {
                    if (firstLandBaseAirsList[ti][wi] > 0)
                    {
                        output += $" {wi + 1}:[{Math.Round(100.0 * landBaseLeaveAirsList[ti][wi][0] / simulationSize, 1)}%]";
                    }
                }
                output += "\n";
            }
            output += "敵艦隊:\n";
            for (int i = 0; i < enemyKammusuList.Count; ++i)
            {
                for (int j = 0; j < enemyKammusuList[i].Count; ++j)
                {
                    int sum = firstEnemyAirsList[i][j].Sum();
                    if (sum > 0)
                    {
                        output += $"{enemy.Unit[i].Kammusu[j].Name}→{Math.Round(100.0 * enemyKammusuList[i][j] / simulationSize, 1)}%";
                        for (int k = 0; k < enemy.Unit[i].Kammusu[j].SlotCount; ++k)
                        {
                            if (firstEnemyAirsList[i][j][k] > 0)
                            {
                                output += $" {k + 1}:[{Math.Round(100.0 * enemyLeaveAirsList[i][j][k][0] / simulationSize, 1)}%]";
                            }
                        }
                        output += "\n";
                    }
                }
            }
            return(output);
        }
Example #8
0
        /// <summary>
        /// 1スロットに対してSt1撃墜を行う(敵艦隊)
        /// </summary>
        /// <param name="slot">元のスロット数</param>
        /// <param name="aws">制空状態</param>
        /// <returns>撃墜したスロット数(乱数)</returns>
        private int CalcKilledSlot(int slot, AirWarStatus aws)
        {
            var temp = killedSlot[slot][(int)aws];

            return(temp[random.Next(temp.Count)]);
        }
Example #9
0
 // 制空状態を文字列に変換する
 public static string ToStr(this AirWarStatus airWarStatus)
 {
     string[] name = { "確保", "優勢", "均衡", "劣勢", "喪失" };
     return(name[(int)airWarStatus]);
 }