Dismiss Notice
Wynncraft, the Minecraft MMORPG. Play it now on your Minecraft client at (IP): play.wynncraft.com. No mods required! Click here for more info...

Art White Horse Breeding Simulator

Discussion in 'Your Work' started by Skip, Apr 21, 2019.

Thread Status:
Not open for further replies.
  1. Skip

    Skip Wynncraft's only Elmo HERO

    Messages:
    95
    Likes Received:
    20
    Trophy Points:
    54
    Minecraft:
    Hello there fellow Wynncrafters!

    I've created a horse breeding simulator in Python in order to gain more insights into how much a white horse should cost on average and am happy to share this with you! What it basically does is tracks some breeding stats and produces a mean, minimum and maximum value for each stat. These stats are calculated over breeding an X amount of white horses.

    The algorithm uses the following breeding behaviour: First, it checks if there are any duplicate horse types. If so it breeds them into a new horse and if not it keeps buying brown horses till there are two. This process repeats until there is a white horse.

    Stats that are tracked per white horse breeding session are: Total emeralds spent, the number of times you've received a better horse from a breed, the number of times you've received the same horse from a breed and finally the number of times you've received a worse horse from a breed.

    Here is the outcome for breeding 10k horses:
    Code:
    Emerald stats: mean: 117LE 28B 8E, min: 3LE 48B 0E, max: 939LE 48B 0E
    Better horse stats: mean: 62, min: 7, max: 516
    Same horse stats: mean: 93, min: 0, max: 755
    Worse horse stats: mean: 156, min: 0, max: 1265
    And for breeding 100k:
    Code:
    Emerald stats: mean: 119LE 6B 34E, min: 3LE 24B 0E, max: 1093LE 8B 0E
    Better horse stats: mean: 63, min: 7, max: 580
    Same horse stats: mean: 94, min: 0, max: 923
    Worse horse stats: mean: 158, min: 0, max: 1474
    Finally, for 1 million white horses the outcome is as follows. I did not go higher than this because my PC can only calculate like 200 white horses per second, meaning it took me about one and a half hour to get the results for 1 mil.
    Code:
    Emerald stats: mean: 118LE 49B 9E, min: 3LE 0B 0E, max: 1508LE 40B 0E
    Better horse stats: mean: 63, min: 7, max: 772
    Same horse stats: mean: 94, min: 0, max: 1205
    Worse horse stats: mean: 157, min: 0, max: 2045
    
    The code of the simulator is as follows:
    Code:
    import math
    import random
    from statistics import mean
    from enum import Enum
    
    
    class HorseType(Enum):
        BROWN = 1
        BLACK = 2
        CHESTNUT = 3
        WHITE = 4
    
    
    class WhiteHorseBreeder:
        def __init__(self, verbose: bool = False):
            self.horses = []
            self.spentEmeralds = 0
            self.verbose = verbose
            self.better_horse_count = 0
            self.same_horse_count = 0
            self.worse_horse_count = 0
    
        def run(self):
            while not self.horses.__contains__(HorseType.WHITE):
                if self.verbose:
                    print("================================================================")
    
                breedable_horses = [i for i in HorseType if self.__horseCount(i) > 1]
    
                if len(breedable_horses) == 0:
                    self.__buyHorses()
                else:
                    for horseType in breedable_horses:
                        self.__breedHorses(horseType)
    
        def __breedHorses(self, horse_type: HorseType):
            self.horses.remove(horse_type)
            self.horses.remove(horse_type)
    
            new_horse = self.__randomHorseFromBreed(horse_type)
            self.horses.append(new_horse)
    
            if self.verbose:
                print("%s + %s = %s" % (horse_type.name, horse_type.name, new_horse.name))
                print(self.horses)
    
        def __randomHorseFromBreed(self, horse_type: HorseType) -> HorseType:
            random_number = random.randint(1, 10)
            if random_number in range(1, 3):
                self.better_horse_count += 1
                return HorseType(horse_type.value + 1)
            if random_number in range(3, 6):
                self.same_horse_count += 1
                try:
                    return HorseType(horse_type.value - 1)
                except Exception:
                    return horse_type
                pass
            self.worse_horse_count += 1
            return horse_type
    
        def __buyHorses(self):
            while self.__horseCount(HorseType.BROWN) < 2:
                self.horses.append(HorseType.BROWN)
                self.spentEmeralds += 24 * 64
                if self.verbose:
                    print("Bought a new horse!")
                    print(self.horses)
    
        def __horseCount(self, horse_type: HorseType):
            return len([i for i in self.horses if i == horse_type])
    
    
    def pretty_emerald_print(emeralds: int):
        liquids = math.floor(emeralds / 4096)
        blocks = math.floor((emeralds % 4096) / 64)
        leftover_emeralds = emeralds % 64
        return "%dLE %dB %dE" % (liquids, blocks, leftover_emeralds)
    
    
    def statistics(number_array):
        return mean(number_array), min(number_array), max(number_array)
    
    
    breeders = [WhiteHorseBreeder() for s in range(1000000)]
    
    for i, breeder in enumerate(breeders):
        print("{0:.2f}%".format((i / len(breeders)) * 100))
        breeder.run()
    
    mean_emeralds, min_emeralds, max_emeralds = statistics(list(map(lambda b: b.spentEmeralds, breeders)))
    better_horse_stats = statistics(list(map(lambda b: b.better_horse_count, breeders)))
    same_horse_stats = statistics(list(map(lambda b: b.same_horse_count, breeders)))
    worse_horse_stats = statistics(list(map(lambda b: b.worse_horse_count, breeders)))
    
    print("Emerald stats: mean: %s, min: %s, max: %s" % (pretty_emerald_print(mean_emeralds),
                                                         pretty_emerald_print(min_emeralds),
                                                         pretty_emerald_print(max_emeralds)))
    print("Better horse stats: mean: %d, min: %d, max: %d" % better_horse_stats)
    print("Same horse stats: mean: %d, min: %d, max: %d" % same_horse_stats)
    print("Worse horse stats: mean: %d, min: %d, max: %d" % worse_horse_stats)
    
    Please note that python isn't my best programming language! Also if you see any flaws in the code, please correct me in the comments!
     
    Last edited: Apr 21, 2019
    YoshisWorld likes this.
  2. Druser

    Druser ele defs don't matter HERO Featured Wynncraftian

    Messages:
    5,890
    Likes Received:
    11,491
    Trophy Points:
    215
    Guild:
    Minecraft:
    python reeee

    (but nice)
     
Thread Status:
Not open for further replies.