private async Task RunOneRoundAsync()

in #U5b9e#U8df5#U9879#U76ee/2019_MSC_#U9ec4#U91d1#U70b9/#U5fae#U8f6f#U9ec4#U91d1#U70b9#U7a0b#U5e8f#U5de5#U5177/OfflineGame/GameMaster/LocalManager/LocalManager/MainForm.cs [214:309]


        private async Task RunOneRoundAsync()
        {
            if (botList.Count == 0)
            {
                return;
            }

            // 当前回合编号
            int curRoundNum = ++roundNum;

            // 从比赛数据中按约定格式生成输入数据
            var historyString = FormatBotInput(dtHistory);

            // Bot执行结果列表
            ConcurrentBag<BotRunResult> botRunResultList = new ConcurrentBag<BotRunResult>();

            List<Task> tasks = new List<Task>();
            nextBotIndex = 0;
            for (int i = 0; i < Environment.ProcessorCount; i++)
            {
                tasks.Add(RunBotsAsync(historyString, curRoundNum, botRunResultList));
            }

            // 等待所有Bot执行完成
            await Task.WhenAll(tasks);

            // Bot输出的预测值列表
            var numberList = new List<double>();
            foreach (var result in botRunResultList.OrderBy(result => result.Bot.Index))
            {
                numberList.Add(result.MasterValue);
                numberList.Add(result.SlaveValue);
            }

            // 排除无效值,然后再计算本回合黄金点值
            var validNumberList = numberList.Where(value => value > 0).ToList();
            var average = validNumberList.Average();
            var goldenNumber = average * 0.618;

            // 当前回合提交有效数据的Bot个数
            int validBotCount = validNumberList.Count / 2;

            // 将数据写入比赛数据表中
            List<object> data = new List<object>();
            data.Add(curRoundNum);
            data.Add(goldenNumber);
            data.AddRange(numberList.OfType<object>());
            DataRow dr = dtHistory.NewRow();
            dr.ItemArray = data.ToArray();
            dtHistory.Rows.Add(dr);
            historyView.FirstDisplayedScrollingRowIndex = historyView.RowCount - 1;

            Log($"第{curRoundNum}回合黄金点为 {goldenNumber} ,各Bot输出: " + String.Join(" ", numberList));

            // 计算得分

            // 将有效预测值按照到黄金点的距离分组并按距离排序
            var scoreResult = botRunResultList.Where(result => result.MasterValue != 0)
                .Select(result => new KeyValuePair<double, Bot>(Math.Abs((double)result.MasterValue - goldenNumber), result.Bot))
                .ToList();
            scoreResult.AddRange(botRunResultList.Where(result => result.SlaveValue != 0)
                .Select(result => new KeyValuePair<double, Bot>(Math.Abs((double)result.SlaveValue - goldenNumber), result.Bot))
                .ToList());
            var scoreResultGroup = scoreResult.GroupBy(item => item.Key)
                .OrderBy(item => item.Key)
                .ToList();

            if (scoreResultGroup.Count != 0)
            {
                // 找到最近的和最远的,分别计分
                var winnerGroup = scoreResultGroup.First().Select(item => item.Value).Distinct().ToList();
                var loserGroup = scoreResultGroup.Last().Select(item => item.Value).Distinct().ToList();

                foreach (var bot in botList)
                {
                    int score = 0;
                    if (winnerGroup.Contains(bot))
                    {
                        score += validBotCount;
                    }
                    if (loserGroup.Contains(bot))
                    {
                        score -= 2;
                    }
                    bot.ScoreHistory.Add(score);

                    dtScoreHistory.Rows[bot.Index - 1]["得分"] = bot.ScoreHistory.Sum();
                }
            }

            chartScore.DataBind();
            chartGoldenNumber.DataBind();

            // 等待UI刷新
            await Task.Delay(1);
        }