public virtual bool 復習判定_2(Chumon chumon, EPuzzleUserInfo userInfo)
 {
     var mondaiResult = chumon.最低の結果を取得(userInfo, 復習判定期間);
     if (null == mondaiResult) return false;
     var grade = chumon.GetGrade(mondaiResult.所要時間, userInfo);
     var d = 復習までの猶予期間を取得(grade);
     //			var t = userInfo.MondaiResults.GetLast(chumon.Id).EndTime;
     var t = userInfo.MondaiResults.GetNewest(chumon.Id).EndTime;
     return t + d < EPuzzleTime.Now;
 }
 public override TimeSpan? 復習までの猶予期間を取得(Chumon chumon, EPuzzleUserInfo userInfo)
 {
     var mondaiResults = 復習判定期間のMondaiResultを取得する(chumon.Id, userInfo);
     if (!mondaiResults.Any()) return null;
     var newest = userInfo.MondaiResults.GetNewest(chumon.Id);
     var duration = GetAverageOfMondaiResults(newest.StartTime - 復習判定期間, mondaiResults);
     var grade = chumon.GetGrade(duration, userInfo);
     return 復習までの猶予期間を取得(chumon, userInfo, grade);
 }
        // GetPoint()は強制的に期間を限定するが、GetPoints2()は最古の結果からの全期間
        public static IEnumerable<PointF> GetPoints2(Chumon chumon, double minGrade, double maxGrade, RectangleF rectangle, MondaiResult[] mondaiResults, EPuzzleUserInfo userInfo)
        {
            if (!mondaiResults.Any()) return Enumerable.Empty<PointF>();
            var items = mondaiResults.OrderByDescending(x => x.StartTime).ToArray();
            var t0 = items.Last().StartTime;
            var duration = EPuzzleTime.Now - t0;
            var points = items.Select(mondaiResult =>
            {
                var grade = chumon.GetGrade(mondaiResult, userInfo);
                if (grade < minGrade)
                {
                    grade = minGrade;
                }
                else if (grade > maxGrade)
                {
                    grade = maxGrade;
                }
                grade -= minGrade;
                grade /= maxGrade - minGrade;

                var t = (mondaiResult.StartTime - t0).Ticks / (double)duration.Ticks;

                return new PointF((float)(t * rectangle.Width + rectangle.Left), (float)(grade * rectangle.Height + rectangle.Top));
            });
            return points;
        }