Пример #1
0
        public void LimitedShuffleTest()
        {
            var array = Enumerable.Range(1, 10).ToArray();

            Debug.WriteLine(string.Join(", ", LimitedShuffle.Get(array, 0.1).Take(array.Length)));
            Debug.WriteLine(string.Join(", ", LimitedShuffle.Get(array, 0.2).Take(array.Length)));
            Debug.WriteLine(string.Join(", ", LimitedShuffle.Get(array, 0.3).Take(array.Length)));

            foreach (var i in Enumerable.Range(1, 4))
            {
                var v = Enumerable.Range(4 - i, 1 + 2 * i).Select(x => CountAverage(() => LimitedShuffle.Get(array, 0.1 * i).IndexOf(5), y => y == x)).ToList();
                var t = 1d / (1 + 2 * i);
                Debug.WriteLine($"{v.Select(x => $"{x * 100:F1}%").JoinToString(", ")} (target: {t * 100:F1}%)");
                foreach (var d in v)
                {
                    Assert.AreEqual(t, d, 0.06, "something wrong at " + i);
                }
            }
        }
Пример #2
0
        public void BigLimitedShuffleTest()
        {
            var array = Enumerable.Range(1, 100).ToArray();

            {
                var v0 = CountAverage(() => LimitedShuffle.Get(array, 0.01).IndexOf(4), x => x < 2 || x > 4);
                var v1 = CountAverage(() => LimitedShuffle.Get(array, 0.01).IndexOf(4), x => x == 2);
                var v2 = CountAverage(() => LimitedShuffle.Get(array, 0.01).IndexOf(4), x => x == 3);
                var v3 = CountAverage(() => LimitedShuffle.Get(array, 0.01).IndexOf(4), x => x == 4);

                Assert.AreEqual(0, v0, "0.01: out of bounds");
                Assert.AreEqual(0.33, v1, 0.03, "0.01: something wrong");
                Assert.AreEqual(0.33, v2, 0.03, "0.01: something wrong");
                Assert.AreEqual(0.33, v3, 0.03, "0.01: something wrong");
            }

            {
                var v0 = CountAverage(() => LimitedShuffle.Get(array, 0.02).IndexOf(4), x => x < 1 || x > 5);
                var v1 = CountAverage(() => LimitedShuffle.Get(array, 0.02).IndexOf(4), x => x == 1);

                Assert.AreEqual(0, v0, "0.02: out of bounds");
                Assert.AreEqual(0.2, v1, 0.03, "0.02: something wrong");
            }
        }
Пример #3
0
        public async Task <IList <Game.AiCar> > GenerateGameEntries(CancellationToken cancellation = default(CancellationToken))
        {
            if (IsBusy)
            {
                await RebuildGridAsync();

                if (cancellation.IsCancellationRequested)
                {
                    return(null);
                }
            }

            var opponentsNumber = OpponentsNumberLimited;

            if (FilteredView.Count == 0 || opponentsNumber == 0)
            {
                return(new Game.AiCar[0]);
            }

            var skins = new Dictionary <string, GoodShuffle <CarSkinObject> >();

            foreach (var car in FilteredView.OfType <RaceGridEntry>().Where(x => x.CarSkin == null).Select(x => x.Car).Distinct())
            {
                await car.SkinsManager.EnsureLoadedAsync();

                if (cancellation.IsCancellationRequested)
                {
                    return(null);
                }

                skins[car.Id] = GoodShuffle.Get(car.EnabledOnlySkins);
            }

            NameNationality[] nameNationalities;
            if (opponentsNumber == 7 && OptionNfsPorscheNames)
            {
                nameNationalities = new[] {
                    new NameNationality {
                        Name = "Dylan", Nationality = "Wales"
                    },
                    new NameNationality {
                        Name = "Parise", Nationality = "Italy"
                    },
                    new NameNationality {
                        Name = "Steele", Nationality = "United States"
                    },
                    new NameNationality {
                        Name = "Wingnut", Nationality = "England"
                    },
                    new NameNationality {
                        Name = "Leadfoot", Nationality = "Australia"
                    },
                    new NameNationality {
                        Name = "Amazon", Nationality = "United States"
                    },
                    new NameNationality {
                        Name = "Backlash", Nationality = "United States"
                    }
                };
            }
            else if (DataProvider.Instance.NationalitiesAndNames.Any())
            {
                nameNationalities = GoodShuffle.Get(DataProvider.Instance.NationalitiesAndNamesList).Take(opponentsNumber).ToArray();
            }
            else
            {
                nameNationalities = null;
            }

            List <int> aiLevels;

            if (AiLevelFixed)
            {
                aiLevels = null;
            }
            else
            {
                var aiLevelsInner = from i in Enumerable.Range(0, opponentsNumber)
                                    select AiLevelMin + ((opponentsNumber < 2 ? 1d : 1d - i / (opponentsNumber - 1d)) * (AiLevel - AiLevelMin)).RoundToInt();
                if (AiLevelArrangeReverse)
                {
                    aiLevelsInner = aiLevelsInner.Reverse();
                }

                if (Equals(AiLevelArrangeRandom, 1d))
                {
                    aiLevelsInner = GoodShuffle.Get(aiLevelsInner);
                }
                else if (AiLevelArrangeRandom > 0d)
                {
                    aiLevelsInner = LimitedShuffle.Get(aiLevelsInner, AiLevelArrangeRandom);
                }

                aiLevels = aiLevelsInner.Take(opponentsNumber).ToList();
                Logging.Debug("AI levels: " + aiLevels.Select(x => $@"{x}%").JoinToString(@", "));
            }

            IEnumerable <RaceGridEntry> final;

            if (Mode.CandidatesMode)
            {
                var list = FilteredView.OfType <RaceGridEntry>().SelectMany(x => new[] { x }.Repeat(x.CandidatePriority)).ToList();

                if (ShuffleCandidates)
                {
                    var shuffled = GoodShuffle.Get(list);

                    if (_playerCar != null)
                    {
                        var same = list.FirstOrDefault(x => x.Car == _playerCar);
                        if (same != null)
                        {
                            shuffled.IgnoreOnce(same);
                        }
                    }

                    final = shuffled.Take(opponentsNumber);
                }
                else
                {
                    var skip = _playerCar;
                    final = LinqExtension.RangeFrom().Select(x => list.RandomElement()).Where(x => {
                        if (x.Car == skip)
                        {
                            skip = null;
                            return(false);
                        }

                        return(true);
                    }).Take(opponentsNumber);
                }
            }
            else
            {
                final = NonfilteredList.Where(x => !x.SpecialEntry);
            }

            if (_playerCar != null)
            {
                skins.GetValueOrDefault(_playerCar.Id)?.IgnoreOnce(_playerCar.SelectedSkin);
            }

            var takenNames = new List <string>(opponentsNumber);

            return(final.Take(opponentsNumber).Select((entry, i) => {
                var level = entry.AiLevel ?? aiLevels?[i] ?? 100;

                var skin = entry.CarSkin;
                if (skin == null)
                {
                    skin = skins.GetValueOrDefault(entry.Car.Id)?.Next;
                }

                var name = entry.Name;
                if (string.IsNullOrWhiteSpace(name) && SettingsHolder.Drive.QuickDriveUseSkinNames)
                {
                    var skinDriverNames = skin?.DriverName?.Split(',').Select(x => x.Trim()).Where(x => x.Length > 0).ToList();
                    if (skinDriverNames?.Count > 0)
                    {
                        name = GoodShuffle.Get(skinDriverNames).Take(skinDriverNames.Count).FirstOrDefault(x => !takenNames.Contains(x)) ?? name;
                        takenNames.Add(name);
                    }
                }

                if (string.IsNullOrWhiteSpace(name))
                {
                    name = nameNationalities?[i].Name ?? @"AI #" + i;
                    takenNames.Add(name);
                }

                var nationality = entry.Nationality ?? nameNationalities?[i].Nationality ?? @"Italy";
                var skinId = skin?.Id;

                return new Game.AiCar {
                    AiLevel = level,
                    CarId = entry.Car.Id,
                    DriverName = AiLevelInDriverName ? $@"{name} ({level}%)" : name,
                    Nationality = nationality,
                    Setup = "",
                    SkinId = skinId
                };
            }).ToList());
        }