コード例 #1
0
    private TimelineLiveElement getBaseDiff(LiveElementBase curr)
    {
        var diff = new TimelineLiveElement()
        {
            id = curr.id
        };

        var diffExplains = new List <Explain>();

        foreach (var explain in curr.explain)
        {
            var diffExplain = new Explain()
            {
                fixture = explain.fixture
            };
            diff.explain.Add(diffExplain);
            var diffStats = new List <ExplainElement>();
            foreach (var stat in explain.stats)
            {
                if (stat.points != 0 || stat.value != 0)
                {
                    diffStats.Add(stat);
                }
            }
            if (diffStats.Count > 0)
            {
                diffExplain.stats = diffStats;
            }
        }
        diff.CalcScore();
        var anyStats = diff.explain.Any(ex => ex.stats.Count > 0);

        return(anyStats ? diff : null);
    }
コード例 #2
0
    public async Task <TimelineLiveElement> Predict(TimelineLiveElement current)
    {
        var prediction = new TimelineLiveElement(current);

        foreach (var fixturePrediction in prediction.explain)
        {
            var fixtureId = fixturePrediction.fixture;
            var fixtures  = await _client.GetFixtures(_gameweek);

            var fixture = fixtures.FirstOrDefault(f => f.id == fixtureId);
            if (fixture != null)
            {
                MakePrediction(current, fixture, fixturePrediction);
            }

            // Ideas:

            /*
             *  If fixture is on:
             *      If player is playing: +1 (don't bother adding? since it gets added anyway)
             *      If player is playing, <60min and could possibly get to 60min, +1
             *      If gk/def still has CS (note: goals scored while player is out don't count... check CS rules): +4
             *      If mid still has CS: +1
             *      Mid/striker +avg, scale down based on time left in fixture, floor it on actual score
             *
             *      Potential subs???? Add sub pts (if sub is valid)
             *  "High" prediction:
             */
        }
        prediction.CalcScore();
        return(prediction);
    }
コード例 #3
0
    private TimelineLiveElement Compare(LiveElementBase prev, LiveElementBase curr)
    {
        var diff = new TimelineLiveElement()
        {
            id = curr.id
        };

        for (var i = 0; i < curr.explain.Count; i++)
        {
            var allExplainIdentifiers = new HashSet <string>(curr.explain[i].stats.Select(s => s.identifier).ToHashSet());
            if (prev != null && prev.explain != null && prev.explain.Count > i)
            {
                foreach (var stat in prev.explain[i].stats)
                {
                    allExplainIdentifiers.Add(stat.identifier);
                }
            }

            var currFixtureExplain = curr.explain[i];
            var prevFixtureExplain = prev != null && prev.explain != null && prev.explain.Count > i ? prev.explain[i] : null;
            var diffExplain        = new Explain()
            {
                fixture = currFixtureExplain.fixture,
                stats   = new List <ExplainElement>()
            };
            diff.explain.Add(diffExplain);

            foreach (var explainIdentifier in allExplainIdentifiers)
            {
                var currStat = currFixtureExplain.stats.FirstOrDefault(e => e.identifier.Equals(explainIdentifier));
                var prevStat = prevFixtureExplain != null?prevFixtureExplain.stats.FirstOrDefault(s => s.identifier.Equals(explainIdentifier)) : null;

                if (prevStat == null)
                {
                    prevStat = new ExplainElement()
                    {
                        identifier = explainIdentifier
                    };
                }
                if (currStat == null)
                {
                    currStat = new ExplainElement()
                    {
                        identifier = explainIdentifier
                    };
                }
                var statDiff = GetExplainDiff(currStat, prevStat);
                if (statDiff != null)
                {
                    diffExplain.stats.Add(statDiff);
                }
            }
        }

        var saveDiff = diff.explain.Any(ex => ex.stats.Count > 0);

        if (saveDiff)
        {
            diff.CalcScore();
            return(diff);
        }

        return(null);
    }
コード例 #4
0
    private void AddPotential(TimelineLiveElement current, Fixture fixture, Explain explain)
    {
        var fixtureMinutes = GetEstimatedFixtureMinutes(fixture);
        var minutesExplain = GetMinutes(explain);
        var bonusExplain   = GetBonus(explain);
        var element        = GetElement(current.id);

        if (minutesExplain == null)
        {
            explain.stats.Add(new ExplainElement()
            {
                identifier = "minutes",
                value      = 0,
                points     = 0
            });
        }

        // Add minutes (assume > 60min if it is still possible)
        if (minutesExplain.value > 0 && minutesExplain.value < 60)
        {
            var maxMinutes = (90 - fixtureMinutes) + minutesExplain.value;
            if (maxMinutes > 60)
            {
                minutesExplain.value  = 61;
                minutesExplain.points = 2;
            }
        }
        else if (minutesExplain.value == 0)
        {
            // No minutes yet
            if (fixture.started && !fixture.finished_provisional)
            {
                // Fixture is on, how many can we get?
                var maxMinutes = (90 - fixtureMinutes) + minutesExplain.value;
                minutesExplain.value  = (int)Math.Round(maxMinutes);
                minutesExplain.points = maxMinutes >= 60 ? 2 : 1;
            }
            else if (!fixture.started)
            {
                // Fixture hasn't started, assume start
                minutesExplain.value  = 90;
                minutesExplain.points = 2;
            }
        }

        // Goalkeepers and defenders get CS, if playing and eligible
        if (IsMidGkOrDef(element))
        {
            var csExplain = GetCS(explain);
            if (csExplain == null)
            {
                if (!HasOtherTeamScored(element, fixture))
                {
                    // Player has no CS and is playing...
                    var maxMinutes = 93.0 - fixtureMinutes + minutesExplain.value;
                    if (maxMinutes >= 60.0)
                    {
                        explain.stats.Add(new ExplainElement()
                        {
                            identifier = "clean_sheets",
                            value      = 1,
                            points     = element.element_type == 3 ? 1 : 4
                        });
                    }
                }
                else
                {
                    explain.stats.Add(new ExplainElement()
                    {
                        identifier = "clean_sheets",
                        value      = 0,
                        points     = 0
                    });
                }
            }
        }

        // Get any potential BPS
        if (bonusExplain == null)
        {
            // Fixture has started, and not completely finished?
            if (fixture.started && !fixture.finished)
            {
                var rank   = GetBpsRankInFixture(element, fixture);
                var points = 0;
                if (rank == 1)
                {
                    points = 3;
                }
                else if (rank == 2)
                {
                    points = 2;
                }
                else if (rank == 3)
                {
                    points = 1;
                }
                if (points > 0)
                {
                    explain.stats.Add(new ExplainElement()
                    {
                        identifier = "bonus",
                        value      = points,
                        points     = points
                    });
                }
            }
        }

        var currentScore = new ScoreCalculator().calculateFootballerScore(explain);
        var avg          = GetAverage(element);

        // If fixture has started, scale the average based on minutes played is player is in
        if (fixtureMinutes > 1.0e-6 && minutesExplain != null)
        {
            avg.points = (int)Math.Round(avg.points * (1.0 - fixtureMinutes / 90.0));
            avg.value  = 0;
        }

        // Only use average if average is > than the current + potential CS. If using average, only use the difference between avg and current
        if (avg.points > currentScore)
        {
            // If fixture hasn't started, use the average
            avg.points = avg.points - currentScore;
            explain.stats.Add(avg);
        }
    }
コード例 #5
0
 private void MakePrediction(TimelineLiveElement current, Fixture fixture, Explain explain)
 {
     AddPotential(current, fixture, explain);
 }
コード例 #6
0
 public TimelineLiveElement(TimelineLiveElement other)
     : base(other)
 {
     score = other.score;
 }