/// <summary> /// Returns a list of random affixes in this pool, making sure they are all of different types. The tiers will be determined through the provided Lottery. /// </summary> /// <param name="totalTiers">The total number of tiers of affixes to be generated</param> /// <param name="tierDistribution">The distribution of tiers</param> /// <returns></returns> public Affix[] GetUniqueRandomAffixes(int totalTiers, Lottery <int> tierDistribution, HashSet <AffixType> blacklist) { List <Affix> affixes = new List <Affix>(); lottery.StartBatchDraw(blacklist); while (totalTiers > 0) { // Get the tier of the Affix to be generated and cap it if it exceeds the total number of tiers left int tier = tierDistribution.Draw(); tier = tier > totalTiers ? totalTiers : tier; AffixType type = GetRandomType(); if (type == AffixType.None) { // We've run out of AffixTypes to draw from break; } affixes.Add(AffixInfo.GetAffixInfo(type).GenerateAffix(tier)); totalTiers -= tier; } lottery.EndBatchDraw(); return(affixes.ToArray()); }
void TestLotteryPerformance() { Stopwatch timer = new Stopwatch(); // setup Lottery <int> lottery = new Lottery <int>(1000000); HashSet <int> blacklist = new HashSet <int>(); for (int i = 0; i < 10000; i++) { lottery.Enter(i % 100, 100); if (i != 69) { blacklist.Add(i); } } lottery.StartBatchDraw(); timer.Start(); // actual test lottery.Draw(100); timer.Stop(); Debug.Log($"Test took {timer.Elapsed.ToString("fffffff").Insert(3, ".").TrimStart('0')} ms"); }
public void LotterySimpleDrawTest() { Lottery <int> lottery = new Lottery <int>(); lottery.Enter(3); Assert.That(lottery.Draw() == 3); }
public void LotteryReferenceDrawTest() { Lottery <TestReference> lottery = new Lottery <TestReference>(); var reference = new TestReference(); lottery.Enter(reference, 10); Assert.That(ReferenceEquals(reference, lottery.Draw())); }
/// <summary> /// Returns a random AffixType in this pool /// </summary> /// <returns></returns> public AffixType GetRandomType() { var result = lottery.Draw(); if (result == null) { result = AffixType.None; } return(result); }
public void LotteryRemoveDrawTest() { Lottery <int> lottery = new Lottery <int>(); lottery.Enter(1, 2); lottery.Enter(2, 10); lottery.Remove(1, 1); lottery.Remove(2); Assert.AreEqual(1, lottery.Draw()); }
public void LotterySimpleBatchDrawTest() { Lottery <int> lottery = new Lottery <int>(1); lottery.Enter(5, 20); lottery.Enter(3, 10); lottery.StartBatchDraw(); var result = lottery.Draw(3); Assert.That(result[0] == 5 && result[1] == 3 || result[0] == 3 && result[1] == 5); Assert.AreEqual(default(int), result[2]); }
public void LotteryBlacklistDrawTest() { Lottery <int> lottery = new Lottery <int>(); lottery.Enter(1); lottery.Enter(2); lottery.Enter(3); lottery.Enter(4); int result = lottery.Draw(new HashSet <int> { 1, 3, 4 }); Assert.AreEqual(2, result); }
public void ProbabilityTest() { var ticketsContainer = Resources.Load <TicketContainer>("Tickets"); Lottery lottery = new Lottery(ticketsContainer); int drawCount = 1000000; Ticket[] tickets = lottery.Draw(drawCount); tickets .GroupBy(e => e.Name) .ToList() .ForEach(e => { Ticket rep = e.First(); string rare = new string('★', rep.Rarity); Debug.LogFormat("{0} {1} レア度:{2,-5}", e.Count(), rep.Name, rare); }); }
public void LotteryRandom10000BatchDrawTest() { Lottery <int> lottery = new Lottery <int>(1000000); for (int i = 0; i < 10000; i++) { lottery.Enter(i); } lottery.StartBatchDraw(); var result = lottery.Draw(10000); HashSet <int> set = new HashSet <int>(); foreach (var item in result) { Assert.That(!set.Contains(item)); set.Add(item); } }
private void GenerateVoronoiPoints(int mapWidth, int mapHeight, int pointCount) { if (mapWidth * mapHeight < pointCount) { throw new System.Exception("Es können nicht mehr VoronoiPoints exisitieren als die gesamt Anzahl an Tiles"); } voronoiPoints = new VoronoiPoint[pointCount]; for (int i = 0; i < pointCount; i++) { VoronoiPoint newPoint = new VoronoiPoint(); do { newPoint.X = Random.Range(0, mapWidth); newPoint.Y = Random.Range(0, mapHeight); } while (VoronoiPointAlreadyExists(newPoint)); newPoint.TileIndex = (byte)(lottery.Draw().Index + 1);//+1 weil der Index 0 für die Border reserviert ist voronoiPoints[i] = newPoint; } }
/// <summary> /// Generates the Affixes and BaseAffixes for an item /// </summary> protected void GenerateAffixes(Item item) { item.Affixes.Clear(); item.BaseAffixes.Clear(); foreach (AffixType affixType in BaseAffixes) { item.BaseAffixes.Add(AffixInfo.GetAffixInfo(affixType).GenerateAffix(item.Tier)); } // Create new lottery to decide tier roll of each affix // TODO: make nicer Lottery<int> tierLottery = new Lottery<int>(); tierLottery.Enter(item.Tier, 10); if (item.Tier > 1) tierLottery.Enter(item.Tier - 1, 5); if (item.Tier > 2) tierLottery.Enter(item.Tier - 2, 2); if (item.Tier > 3) tierLottery.Enter(item.Tier - 3, 1); int quality = item.Quality; // Guaranteed affixes don't care about possible pool foreach (AffixType affixType in GuaranteedAffixes) { int tier = tierLottery.Draw(); tier = tier > quality ? quality : tier; item.Affixes.Add(AffixInfo.GetAffixInfo(affixType).GenerateAffix(tier)); quality -= tier; } // Fill up the rest of the affixes Affix[] randomAffixes = PossibleAffixes.GetUniqueRandomAffixes(quality, tierLottery, new HashSet<AffixType>(GuaranteedAffixes)); foreach (Affix affix in randomAffixes) { item.Affixes.Add(affix); } }
public void TicketLottery() { var rnd = new Random(); var lottery = new Lottery <Prizes>(Lottery <Prizes> .DrawResponse.RemoveTicket); for (int i = 0; i < 10000; i++) { var answers = new Dictionary <Prizes, int> { { Prizes.Prize1, 0 }, { Prizes.Prize2, 0 }, { Prizes.Prize3, 0 }, { Prizes.Prize4, 0 } }; int prize1 = rnd.Next(1, 50); int prize2 = rnd.Next(1, 50); int prize3 = rnd.Next(1, 50); int prize4 = rnd.Next(1, 50); lottery.AddTickets(Prizes.Prize1, prize1); lottery.AddTickets(Prizes.Prize2, prize2); lottery.AddTickets(Prizes.Prize3, prize3); lottery.AddTickets(Prizes.Prize4, prize4); do { var winner = lottery.Draw(); answers[winner]++; } while (lottery.NumberOfTickets > 0); Assert.Equal(prize1, answers[Prizes.Prize1]); Assert.Equal(prize2, answers[Prizes.Prize2]); Assert.Equal(prize3, answers[Prizes.Prize3]); Assert.Equal(prize4, answers[Prizes.Prize4]); } }
public void PrizeLottery() { var rnd = new Random(); var lottery = new Lottery <Prizes>(Lottery <Prizes> .DrawResponse.RemovePrize); for (int i = 0; i < 10000; i++) { var dicResposta = new Dictionary <Prizes, int> { { Prizes.Prize1, 0 }, { Prizes.Prize2, 0 }, { Prizes.Prize3, 0 }, { Prizes.Prize4, 0 } }; int moedas1 = rnd.Next(1, 50); int moedas2 = rnd.Next(1, 50); int powerUp = rnd.Next(1, 50); int powerUpeMoedas = rnd.Next(1, 50); lottery.AddTickets(Prizes.Prize1, moedas1); lottery.AddTickets(Prizes.Prize2, moedas2); lottery.AddTickets(Prizes.Prize3, powerUp); lottery.AddTickets(Prizes.Prize4, powerUpeMoedas); do { var winner = lottery.Draw(); dicResposta[winner]++; } while (lottery.NumberOfPrizes > 0); Assert.Equal(1, dicResposta[Prizes.Prize1]); Assert.Equal(1, dicResposta[Prizes.Prize2]); Assert.Equal(1, dicResposta[Prizes.Prize3]); Assert.Equal(1, dicResposta[Prizes.Prize4]); } }
/// <summary> /// Draws a random entrant from this lottery /// </summary> /// <returns></returns> public T Draw() { if (entrants.Count == 0) { throw new LotteryException("Can't draw from empty lottery!"); } if (batchLottery == null) { return(entrants[rng.Next(entrants.Count)]); } // else draw from the batch lottery try { T result = batchLottery.Draw(); batchLottery.Remove(result); return(result); } catch (LotteryException) { return(default(T)); } }
private void SpawnItems() { for (int x = 0; x < mapWidth; x++) { for (int y = 0; y < mapHeight; y++) { TileType type = TileTypes[map[x, y] - 1]; bool spawnItem = Random.Range(0, 100) <= type.ItemSpawnChance && type.UniqueItemForTileType.Length != 0; if (spawnItem) { SpawnItemAtLocation(x, y, type.ItemSpawnLottery.Draw()); } else { bool generalSpawnItem = Random.Range(0, 100) <= ItemSpawnChance && ItemSpawns.Length != 0; if (generalSpawnItem) { SpawnItemAtLocation(x, y, itemSpawnLottery.Draw()); } } } } }
public async Task Fish(CommandContext ctx) { //Ablauf was alles passieren muss: //-zukünftig evtl Minispiel //-Player muss eine Standardzeit - Bonuszeit von Ausrüstung warten //✔️Fish wird generiert & Bild von dem Fish wird in den Channel gepostet //✔️Fish wird dem Player im Inventar hinzugefügt //✔️Wenn man mit Ködern Angelt werden diese auch abgezogen //Was muss alles gegeben sein damit man fischen kann: //-Es muss aktiv eine fishing rod ausgerüstet sein //✔️Man muss an einer Insel stehen //-Man darf nicht schon überladen sein //->Eventuell berechnung von Max. Gewicht was man finden kann + aktuelles Gewicht < Max gewicht??? // Player player = checkPlayer(ctx.Member.Id); if (player.id == -1) { await ctx.Channel.SendMessageAsync("Please register first.").ConfigureAwait(false); return; } else if ((bool)player.locked) { await ctx.Channel.SendMessageAsync("You can't do that at this moment").ConfigureAwait(false); return; } lockPlayer(player.id); Random rnd = new Random(); var fishingRod = "Obsidian Fishing Pole"; int? amount = null; //Ködern abziehen if (player.equippedBaitId > 0) { amount = insertPlayerInventory(player.id, (int)player.equippedBaitId, 2, -1); if (amount < 0 || !amount.HasValue) { await ctx.Channel.SendMessageAsync("You don't have enough bait for this action.").ConfigureAwait(false); return; } } var msg = await ctx.Channel.SendMessageAsync($"You cast your {fishingRod}.").ConfigureAwait(false); List <Fish> fishPool = getFishPool((int)player.currentIslandId, player.equippedBaitId); var lottery = new Lottery <string>(); foreach (var fishType in fishPool) { lottery.Add(fishType.name, (double)fishType.percentage); } string caughtFishName = lottery.Draw(true).Key; int caughtFishId = fishPool.Where(x => x.name == caughtFishName).Select(x => x.id).First(); Item caughtFish = selectItem(caughtFishId); await Task.Delay(2000); var caughtFishAmount = insertPlayerInventory(player.id, caughtFish.id, 1, 1); Tuple <int, int> level = addPlayerXp(player.id, (int)caughtFish.xp); var catchMsgBuilder = new DiscordEmbedBuilder() { Title = "Success!", Description = $"You caught a {caughtFishName}!\nYou gained {caughtFish.xp} experience.\n{(level.Item1 == 1 ? $"You leveled up! You are now level {level.Item2}\n" : string.Empty)}" + $"You alreday got caught {caughtFishAmount} {caughtFish.name}{(player.equippedBaitId == 0 ? string.Empty : $"\nYou got {amount} bait left")}", ImageUrl = caughtFish.imageURL }; await ctx.Channel.SendMessageAsync(catchMsgBuilder).ConfigureAwait(false); unlockPlayer(player.id); return; }
/// <summary> /// Generates the areas for the map /// </summary> /// <param name="AreaTierCalculation"> /// A Function that calculates the Tier for an area, gets called after the area /// has all cells set that will be in this area /// </param> void GenerateAreas(Func <Area, int> AreaTierCalculation) { System.Random rng = new System.Random((int)DateTime.Now.Ticks); // lottery for area size #region Area Size Lottery Lottery <int> lottery = new Lottery <int>(); lottery.Enter(1, 30); lottery.Enter(2, 50); lottery.Enter(3, 42); lottery.Enter(4, 17); #endregion List <HexCell> nextPossibleAreaCenters = new List <HexCell> { this[0, 0] }; //int i= 0; while (nextPossibleAreaCenters.Count > 0) { HexCell AreaBegin = nextPossibleAreaCenters[rng.Next(0, nextPossibleAreaCenters.Count)]; nextPossibleAreaCenters.Remove(AreaBegin); List <HexCell> possibleCellsForArea = new List <HexCell>(GetNeighborsWithoutArea(AreaBegin)); Area newArea = new Area(lottery.Draw()); Areas.Add(newArea.AreaID, newArea); newArea.TryEstablishRelationWithCell(AreaBegin); //Debug.Log("Map::GenerateAreas - Chose Cell: " + AreaBegin.ToString()); #region Fill area while (!newArea.IsFull() && possibleCellsForArea.Count > 0) { // get random cell from possible entries HexCell cell = possibleCellsForArea[rng.Next(0, possibleCellsForArea.Count)]; //Debug.Log("Map::GenerateAreas - Chose Cell: " + cell.ToString()); // add to area newArea.TryEstablishRelationWithCell(cell); // if cell was added to area // remove slectred cell form possneighbors and // if in nextPossibleAreaCenters remove it as well if (cell.ParentArea != null) { possibleCellsForArea.Remove(cell); if (nextPossibleAreaCenters.Contains(cell)) { //Debug.Log("Map::GenerateAreas - Removing cell from next possible area centers list"); nextPossibleAreaCenters.Remove(cell); } // end if next area begin contains } // end if cell parent area null // get all neigbors without areas from this recently added cell // add them to possible neighbors foreach (HexCell c in GetNeighborsWithoutArea(cell)) { if (!possibleCellsForArea.Contains(c)) { possibleCellsForArea.Add(c); } } }// end while area not full and poss neighbors count > 0 #endregion newArea.SetTier(AreaTierCalculation(newArea)); //area finsihed //Debug.Log("Map::GenerateAreas - Finiehsd Area: "+ newArea.ToString()); // add all cells in poss neigbors that are not already in nextPossibleAreaCenters to the list of // next possible area Centers //Debug.Log(possibleCellsForArea.Count + " cells left in possible cells for area"); #region Adding outline of cells adjacent to cell with area assigned foreach (HexCell c in possibleCellsForArea) { if (!nextPossibleAreaCenters.Contains(c)) { //Debug.Log("Adding cell"); nextPossibleAreaCenters.Add(c); } } #endregion }// end while next poss area begins count > 0 }