Example #1
0
        private void FindPossessor(ref Player possessor, ref Side possessionTeam, Coordinate startLocation = default(Coordinate))
        {
            if (startLocation == default(Coordinate))
            {
                startLocation = Coordinate.Random();
            }

            var homeTeamStartPlayer = TeamFormationAttributes.GetNearestPlayer(true, startLocation);
            var awayTeamStartPlayer = TeamFormationAttributes.GetNearestPlayer(false, startLocation);

            Log(string.Format("Battle for possession between {0} and {1} at {2}", homeTeamStartPlayer.LastName, awayTeamStartPlayer.LastName, startLocation));

            possessionTeam = homeTeamStartPlayer.Rating > awayTeamStartPlayer.Rating ? Side.Home : Side.Away;

            possessor = possessionTeam == Side.Home ? homeTeamStartPlayer : awayTeamStartPlayer;
        }
Example #2
0
        public MatchSimulator(IDictionary <int, Player> homeTeamFormation, IDictionary <int, Player> awayTeamFormation)
        {
            Log = s =>
            {
                if (this.PlayerMatch)
                {
                    logger.Debug(s);
                }
            };

            Random                  = new Random();
            HomeTeamPlayers         = homeTeamFormation.Values.ToList();
            AwayTeamPlayers         = awayTeamFormation.Values.ToList();
            TeamFormationAttributes = new TeamFormationAttributes(HomeTeamPlayers, AwayTeamPlayers, Log);

            HomeGoal = new Coordinate {
                X = 0.5d, Y = 0d
            };
            AwayGoal = new Coordinate {
                X = 0.5d, Y = 1d
            };
        }
Example #3
0
        private void LogRatingBattle()
        {
            var height = 120;
            var width  = 25;

            var stringBuilder = new StringBuilder("\n");

            stringBuilder.AppendLine(string.Join("", Enumerable.Repeat("_", height).ToArray()));

            for (var i = 1; i < width; ++i)
            {
                for (var j = 0; j < height; ++j)
                {
                    if (j == 0 || j == height - 1)
                    {
                        stringBuilder.Append("|");
                        continue;
                    }

                    if (j == 1 && i % 2 == 0)
                    {
                        stringBuilder.Append(" ");
                        continue;
                    }

                    var rating = (int)(TeamFormationAttributes.TeamStrength(true, new Coordinate {
                        X = (double)i / width, Y = (double)j / height
                    }) -
                                       TeamFormationAttributes.TeamStrength(false, new Coordinate {
                        X = (double)i / width, Y = (double)j / height
                    }));

                    stringBuilder.Append(rating);

                    j += (int)rating == 0 ? 1 : (int)Math.Log10(Math.Abs(rating)) + 1;

                    if (rating < 0)
                    {
                        ++j;
                    }

                    if (j == height)
                    {
                        stringBuilder.Append("|");
                    }
                    else if (j == height - 1)
                    {
                        stringBuilder.Append(" |");
                    }
                    else if (j == height - 2)
                    {
                        stringBuilder.Append("  |");
                        j += 2;
                    }
                    else
                    {
                        stringBuilder.Append(" ");
                    }
                }

                stringBuilder.AppendLine();
            }

            stringBuilder.AppendLine(string.Join("", Enumerable.Repeat("_", height).ToArray()));

            Log(stringBuilder.ToString());
        }
Example #4
0
        private void PlayPhase(IFixture fixture, Action <double, double[, ]> updateUi, ref Player possessor, ref Side possessionTeam, ref PossessionGraph <Player> possessionGraph)
        {
            if (possessor == null)
            {
                FindPossessor(ref possessor, ref possessionTeam);

                Log(string.Format("{0} wins it for {1}", possessor.LastName, possessor.TeamName));
            }

            possessionGraph = possessionTeam == Side.Home ?
                              TeamFormationAttributes.HomeTeamPossessionGraph() :
                              TeamFormationAttributes.AwayTeamPossessionGraph();

            if (TeamFormationAttributes.DelmeFlag)
            {
                var ignore = possessionTeam == Side.Away ?
                             TeamFormationAttributes.HomeTeamPossessionGraph() :
                             TeamFormationAttributes.AwayTeamPossessionGraph();
                TeamFormationAttributes.DelmeFlag = false;
            }

            var possessionIterations = 0;
            var option = default(int);

            //	TODO: Modifier for +ve Team Balance, -ve Defensive shape?
            while (possessionIterations++ < 15)
            {
                ++PhasesOfPlay;
                if (PlayerMatch)
                {
                    updateUi(HomeTouches / (HomeTouches + AwayTouches), ColourHeatMap(possessor.Location.RandomNear()));
                    Thread.Sleep(500);                          //	TODO: put back to 100 to speed it up again // make it a reasonable pace
                }

                var isShooting = default(bool);
                option = possessionGraph.PhaseOfPlay(ref possessor, out isShooting);

                if (possessionTeam == Side.Home)
                {
                    ++HomeTouches;
                }
                else
                {
                    ++AwayTouches;
                }

                if (option < 750)
                {
                    PossessionGraph <Player> .Chain.WriteLine("\"{0}\",{1},{2},lost", possessor.TeamName, possessionIterations, isShooting);

                    PossessionGraph <Player> .Chain.Flush();

                    break;
                }

                if (option < 1250)
                {
                    PossessionGraph <Player> .Chain.WriteLine("\"{0}\",{1},{2},restart", possessor.TeamName, possessionIterations, isShooting);

                    PossessionGraph <Player> .Chain.Flush();

                    possessor = TeamFormationAttributes.GetNearestPlayer(possessionTeam == Side.Home, RestartedBallPosition(possessionTeam, (option - 500d) / 1000));
                    Log(string.Format("Working from the back with {0}", possessor.LastName));
                    continue;
                }

                if (isShooting)
                {
                    PossessionGraph <Player> .Chain.WriteLine("\"{0}\",{1},true,shoot", possessor.TeamName, possessionIterations);

                    PossessionGraph <Player> .Chain.Flush();

                    if (possessionTeam == Side.Home)
                    {
                        ++fixture.ChancesHome;
                    }
                    else
                    {
                        ++fixture.ChancesAway;
                    }

                    if (option > 2000)
                    {
                        Log(string.Format("He shoots, he scores! Goal for {0}", possessor.LastName));
                        if (possessionTeam == Side.Home)
                        {
                            ++fixture.GoalsHome;
                        }
                        else
                        {
                            ++fixture.GoalsAway;
                        }

                        ++possessor.Goals;
                        option = 500;                           // to allow the restarted position (see GetNearestPlayer invocation below) to be at the halfway line
                    }
                    else
                    {
                        Log(string.Format("Shot from {0} but no goal", possessor.LastName));
                    }

                    break;
                }
            }

            FindPossessor(ref possessor, ref possessionTeam, possessor.Location.RandomNear());

            Log(string.Format("Restart for {0} with {1} at {2}", possessor.TeamName, possessor.LastName, possessor.Location));
        }
Example #5
0
        public void Play(IFixture fixture, Action <double, double[, ]> updateUi)
        {
            HeatMap = new double[Configuration.HeatMapDimensions.Item1, Configuration.HeatMapDimensions.Item2];

            if (PlayerMatch)
            {
                updateUi(0.5d, null);
            }

            var ballPosition = new Coordinate {
                X = 0.5d, Y = 0.5d
            };
            var kickoff = DateTime.Now;

            PlayerMatch  = updateUi != null;
            PhasesOfPlay = 0;

            if (PlayerMatch)
            {
                updateUi(0.5d, HeatMap);
                Thread.Sleep(5000);
            }

            LogTeam(Side.Home);
            LogRatingBattle(Side.Home);
            LogTeam(Side.Away);
            LogRatingBattle(Side.Away);
            LogRatingBattle();

            fixture.PlayingPeriod = PlayingPeriod.FirstHalf;
            PlayHalf(fixture, updateUi);

            fixture.PlayingPeriod = PlayingPeriod.HalfTime;
            HeatMap = new double[Configuration.HeatMapDimensions.Item1, Configuration.HeatMapDimensions.Item2];

            if (PlayerMatch)
            {
                updateUi(HomeTouches / (HomeTouches + AwayTouches), null);
                Thread.Sleep(5000);
            }

            PhasesOfPlay          = 0;
            fixture.PlayingPeriod = PlayingPeriod.SecondHalf;

            var temp = HomeGoal;

            HomeGoal = AwayGoal;
            AwayGoal = temp;

            //	Switching sides at halftime is covered by the ViewModel bound animation.
            //	Non-player matches have to do this here.
            if (!PlayerMatch)
            {
                HomeTeamPlayers.Concat(AwayTeamPlayers).Execute(p => p.Location.Invert());
            }

            TeamFormationAttributes.SecondHalf();

            PlayHalf(fixture, updateUi);

            fixture.PlayingPeriod = PlayingPeriod.FullTime;
        }