コード例 #1
0
        // ステージ2撃墜処理(基地航空隊)
        private static void St2LandBaseBreak(LandBase landBase, Fleet enemy, LandBaseAirsList landBaseAirsList, int ti, CutInType cutInType)
        {
            // 迎撃艦を一覧を算出し、それぞれの撃墜量を出す
            var breakPer   = enemy.BreakPer;
            var breakFixed = enemy.BreakFixed(cutInType);

            // 撃墜処理
            for (int wi = 0; wi < landBase.Team[ti].Weapon.Count; ++wi)
            {
                if (!landBase.Team[ti].Weapon[wi].IsStage2X)
                {
                    continue;
                }
                // 迎撃艦を選択する
                int selectKammusuIndex = RandInt(0, breakPer.Count - 1);
                // 割合撃墜
                if (RandInt(0, 1) == 1)
                {
                    int breakCount = (int)(breakPer[selectKammusuIndex] * landBaseAirsList[ti][wi]);
                    landBaseAirsList[ti][wi] -= breakCount;
                }
                // 固定撃墜
                if (RandInt(0, 1) == 1)
                {
                    int breakCount = breakFixed[selectKammusuIndex];
                    breakCount += CutInAddBonus[(int)cutInType];
                    landBaseAirsList[ti][wi] = Math.Max(landBaseAirsList[ti][wi] - breakCount, 0);
                }
            }
        }
コード例 #2
0
        private static int NowAirValueX(LandBase landBase, LandBaseAirsList landBaseAirsList, int ti)
        {
            int airValue   = 0;
            var weaponList = landBase.Team[ti].Weapon;

            for (int wi = 0; wi < landBase.Team[ti].Airs.Count; ++wi)
            {
                airValue += weaponList[wi].AirValueX(landBaseAirsList[ti][wi]);
            }
            return(airValue);
        }
コード例 #3
0
 // モンテカルロシミュレーションを行う
 public static string MonteCarlo(Fleet friend, Fleet enemy, LandBase landBase, int simulationSize)
 {
     if (landBase == null)
     {
         return(MonteCarloImpl(friend, enemy, simulationSize));
     }
     else
     {
         return(MonteCarloImpl(friend, enemy, landBase, simulationSize));
     }
 }
コード例 #4
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;
     }
 }
コード例 #5
0
        /// <summary>
        /// 入力された文字列を大艦隊クラスに変換する
        /// </summary>
        /// <param name="inputAirBaseText">文字列</param>
        /// <returns>大艦隊クラス</returns>
        public static LandBase ToLandBase(string inputAirBaseText)
        {
            var landbase = new LandBase();

            // bas形式と考えて読み込む
            using (var rs = new System.IO.StringReader(inputAirBaseText)) {
                while (rs.Peek() > -1)
                {
                    try {
                        string getLine = rs.ReadLine();
                        var    column  = getLine.Split(',');
                        if (column.Count() < 13)
                        {
                            continue;
                        }
                        var landBaseTeam = new LandBaseTeam();
                        int attackCount  = int.Parse(column[0]);
                        attackCount = (attackCount >= 2 ? 2 : 1);
                        // 装備(データベースから情報を拾う)
                        for (int i = 0; i < 4; ++i)
                        {
                            int id2 = DataBase.WeaponId(column[1 + i * 3]);
                            if (id2 >= 0)
                            {
                                var tempWeapon = new Weapon();
                                tempWeapon.Id          = id2;
                                tempWeapon.Improvement = int.Parse(column[2 + i * 3]);
                                tempWeapon.Proficiency = int.Parse(column[3 + i * 3]);
                                tempWeapon.Complete();
                                landBaseTeam.Weapon[i] = tempWeapon;
                                if (tempWeapon.Type.Contains("偵察機"))
                                {
                                    landBaseTeam.Airs[i] = 4;
                                }
                            }
                        }
                        landBaseTeam.Complete();
                        landbase.Team.Add(landBaseTeam);
                        landbase.AttackCount.Add(attackCount);
                    }
                    catch {
                        continue;
                    }
                }
            }
            if (landbase.TeamCount <= 0)
            {
                throw new Exception();
            }
            return(landbase);
        }
コード例 #6
0
 // 記録する
 private static void MemoLeaveList(LandBase landBase, LandBaseAirsList landBaseAirsList, LandBaseList landBaseList, LeaveLandBaseAirsList landBaseLeaveAirsList)
 {
     for (int ti = 0; ti < landBaseAirsList.Count; ++ti)
     {
         bool allBrokenFlg = true;
         bool hasPAPBWB    = false;
         for (int wi = 0; wi < landBase.Team[ti].Weapon.Count; ++wi)
         {
             if (landBase.Team[ti].Weapon[wi].IsStage2X)
             {
                 hasPAPBWB = true;
                 if (landBaseAirsList[ti][wi] != 0)
                 {
                     allBrokenFlg = false;
                 }
             }
             ++landBaseLeaveAirsList[ti][wi][landBaseAirsList[ti][wi]];
         }
         if (allBrokenFlg && hasPAPBWB)
         {
             ++landBaseList[ti];
         }
     }
 }
コード例 #7
0
 // 結果を出力する
 public static void ResultData(Fleet friendFleet, Fleet enemyFleet, LandBase landBase, int simulationSize, out List <string> nameList, out List <List <List <double> > > perList)
 {
     nameList = new List <string>();
     perList  = new List <List <List <double> > >();
     for (int i = 0; i < friendLeaveAirsList.Count; ++i)
     {
         for (int j = 0; j < friendLeaveAirsList[i].Count; ++j)
         {
             var tempList1 = new List <List <double> >();
             for (int k = 0; k < friendFleet.Unit[i].Kammusu[j].SlotCount; ++k)
             {
                 if (friendLeaveAirsList[i][j][k].Count == 1)
                 {
                     continue;
                 }
                 if (!friendFleet.Unit[i].Kammusu[j].Weapon[k].IsStage1)
                 {
                     continue;
                 }
                 var tempList2 = new List <double>();
                 for (int m = 0; m < friendLeaveAirsList[i][j][k].Count; ++m)
                 {
                     tempList2.Add(100.0 * friendLeaveAirsList[i][j][k][m] / simulationSize);
                 }
                 tempList1.Add(tempList2);
             }
             if (tempList1.Count > 0)
             {
                 nameList.Add($"{i + 1}-{j + 1} {friendFleet.Unit[i].Kammusu[j].Name}");
                 perList.Add(tempList1);
             }
         }
     }
     if (landBase != null)
     {
         for (int ti = 0; ti < landBase.TeamCount; ++ti)
         {
             nameList.Add($"基地-{ti + 1}");
             var tempList1 = new List <List <double> >();
             for (int wi = 0; wi < landBase.Team[ti].Weapon.Count; ++wi)
             {
                 if (landBaseLeaveAirsList[ti][wi].Count == 1)
                 {
                     continue;
                 }
                 if (!landBase.Team[ti].Weapon[wi].IsStage1X)
                 {
                     continue;
                 }
                 var tempList2 = new List <double>();
                 for (int m = 0; m < landBaseLeaveAirsList[ti][wi].Count; ++m)
                 {
                     tempList2.Add(100.0 * landBaseLeaveAirsList[ti][wi][m] / simulationSize);
                 }
                 tempList1.Add(tempList2);
             }
             perList.Add(tempList1);
         }
     }
     for (int i = 0; i < enemyLeaveAirsList.Count; ++i)
     {
         for (int j = 0; j < enemyLeaveAirsList[i].Count; ++j)
         {
             var tempList1 = new List <List <double> >();
             for (int k = 0; k < enemyFleet.Unit[i].Kammusu[j].SlotCount; ++k)
             {
                 if (enemyLeaveAirsList[i][j][k].Count == 1)
                 {
                     continue;
                 }
                 if (!enemyFleet.Unit[i].Kammusu[j].Weapon[k].IsStage1)
                 {
                     continue;
                 }
                 var tempList2 = new List <double>();
                 for (int m = 0; m < enemyLeaveAirsList[i][j][k].Count; ++m)
                 {
                     tempList2.Add(100.0 * enemyLeaveAirsList[i][j][k][m] / simulationSize);
                 }
                 tempList1.Add(tempList2);
             }
             if (tempList1.Count > 0)
             {
                 nameList.Add($"{i + 1}-{j + 1} {enemyFleet.Unit[i].Kammusu[j].Name}");
                 perList.Add(tempList1);
             }
         }
     }
 }
コード例 #8
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);
        }