all repos — groupgardenbot @ d752172475554e59798085f5ad66e7ac2dd8552b

An extension of the game "botany", originally designed for unix-based systems, to the Telegram Bot API.

Gardening.py (view raw)

  1import random, os, time, datetime
  2from Constants import *
  3
  4water_duration = 3600 * 24
  5death_duration = 5 * water_duration
  6stage_factors = (1, 3, 10, 20, 30)
  7indicator_squares = 10
  8mutation_rarity = 20000 # Increase this # to make mutation rarer (chance 1 out of x each second)
  9max_plant_rarity = 256.0
 10
 11class Plant(object):
 12    # This is your plant!
 13    def __init__(self, owner, generation=1):
 14        # Constructor
 15        self.points = 0 # one point per second
 16        self.life_stages = tuple(st * water_duration for st in stage_factors)
 17        self.stage = 0
 18        self.mutation = 0
 19        self.species = random.randint(0, len(species_list) - 1)
 20        self.color = random.randint(0, len(color_list) - 1)
 21        self.name = plant_names[random.randint(0, len(plant_names) - 1)]
 22        self.rarity = self.rarity_check()
 23        self.generation = generation
 24        self.generation_bonus = 1 + (0.2 * (generation - 1))
 25        self.dead = False
 26        self.owner = owner.id
 27        self.owner_name = owner.full_name
 28        self.age_days = 0
 29        self.start_time = int(time.time())
 30        self.last_update = self.start_time
 31        self.last_water = self.start_time - water_duration
 32        self.last_water_user = owner.id
 33        self.last_water_name = ""
 34
 35    def update(self):
 36        now = int(time.time())
 37        water_delta = now - self.last_water
 38        if water_delta > death_duration:
 39            self.dead = True
 40            return
 41        self.age_days = round((now - self.start_time) / water_duration)
 42
 43        increase = min(water_delta, water_duration) - min(self.last_update - self.last_water, water_duration)
 44
 45        if increase != 0:
 46            self.points += increase
 47            self.mutate_check(increase)
 48
 49        stages = tuple(th / self.generation_bonus for th in self.life_stages) # bonus is applied to stage thresholds
 50        count = 0
 51        closest = None
 52        delta = self.points
 53
 54        for n in stages:
 55            if (n <= delta and (closest is None or (delta - n) < (delta - closest))):
 56                closest = n
 57                count += 1
 58
 59        self.stage = count
 60        self.last_update = now
 61        
 62    def parse_plant(self):
 63        # Converts plant data to human-readable format
 64        output = ""
 65        if self.stage >= 3:
 66            output += rarity_list[self.rarity] + " "
 67        if self.mutation != 0:
 68            output += mutation_list[self.mutation] + " "
 69        if self.stage >= 4:
 70            output += color_list[self.color] + " "
 71        output += stage_list[self.stage] + " "
 72        if self.stage >= 2:
 73            output += species_list[self.species] + " "
 74        return output.strip()
 75
 76    def rarity_check(self):
 77        # Generate plant rarity
 78        rare_seed = random.randint(1,max_plant_rarity)
 79        common_range =    round((2.0 / 3) * max_plant_rarity)
 80        uncommon_range =  round((2.0 / 3) * (max_plant_rarity - common_range))
 81        rare_range =      round((2.0 / 3) * (max_plant_rarity - common_range - uncommon_range))
 82        legendary_range = round((2.0 / 3) * (max_plant_rarity - common_range - uncommon_range - rare_range))
 83
 84        common_max = common_range
 85        uncommon_max = common_max + uncommon_range
 86        rare_max = uncommon_max + rare_range
 87        legendary_max = rare_max + legendary_range
 88        godly_max = max_plant_rarity
 89
 90        if 0 <= rare_seed <= common_max:
 91            return 0
 92        elif common_max < rare_seed <= uncommon_max:
 93            return 1
 94        elif uncommon_max < rare_seed <= rare_max:
 95            return 2
 96        elif rare_max < rare_seed <= legendary_max:
 97            return 3
 98        elif legendary_max < rare_seed <= godly_max:
 99            return 4
100
101    def mutate_check(self, increase):
102        # Create plant mutation
103        mutation_seed = mutation_rarity if increase >= mutation_rarity else random.randint(increase, mutation_rarity)
104        if mutation_seed == mutation_rarity:
105            # mutation gained!
106            mutation = random.randint(0, len(mutation_list) - 1)
107            if self.mutation == 0:
108                self.mutation = mutation
109                return True
110        else:
111            return False
112
113    def water(self, who):
114        if not self.dead:
115            self.last_water = int(time.time())
116            self.last_water_user = who.id
117            self.last_water_name = who.full_name
118
119    def start_over(self, owner):
120        next_generation = self.generation if self.dead else self.generation + 1
121        self.__init__(owner, next_generation)
122
123    def get_water(self):
124        water_delta = int(time.time()) - self.last_water
125        water_left_pct = max(0, 1 - (water_delta/water_duration))
126        water_left = int(round(water_left_pct * indicator_squares))
127        return f"{water_left * '🟦'}{'⬛' * (indicator_squares - water_left)} {str(round(water_left_pct * 100))}%"
128
129    def get_water_ascii(self):
130        water_delta = int(time.time()) - self.last_water
131        water_left_pct = max(0, 1 - (water_delta/water_duration))
132        water_left = int(round(water_left_pct * indicator_squares))
133        return f"|{water_left * 'â–ˆ'}{' ' * (indicator_squares - water_left)}| {str(round(water_left_pct * 100))}%"
134
135    def get_filename(self):
136        if self.dead == True: return 'rip.txt'
137        if datetime.date.today().month == 10 and datetime.date.today().day == 31: return 'jackolantern.txt'
138        if self.stage == 0: return 'seed.txt'
139        if self.stage == 1: return 'seedling.txt'
140        if self.stage == 2: return species_list[self.species]+'1.txt'
141        if self.stage == 3 or self.stage == 5: return species_list[self.species]+'2.txt'
142        if self.stage == 4: return species_list[self.species]+'3.txt'
143        return "template.txt"
144
145    def get_art(self):
146        filename = self.get_filename()
147        # Prints ASCII art from file at given coordinates
148        this_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "art")
149        this_filename = os.path.join(this_dir, filename)
150        this_file = open(this_filename,"r")
151        this_string = this_file.read()
152        this_file.close()
153        return this_string
154
155    def get_description(self):
156        output_text = ""
157        this_species = species_list[self.species]
158        this_color = color_list[self.color]
159        this_stage = self.stage
160
161        if self.dead:
162                this_stage = 99
163        try:
164            description_num = random.randint(0,len(stage_descriptions[this_stage]) - 1)
165        except KeyError as e:
166            print(e)
167            description_num = 0
168        # If not fully grown
169        if this_stage <= 4:
170            # Growth hint
171            if this_stage >= 1:
172                last_growth_at = self.life_stages[this_stage - 1]
173            else:
174                last_growth_at = 0
175            ticks_since_last = self.points - last_growth_at
176            ticks_between_stage = self.life_stages[this_stage] - last_growth_at
177            if ticks_since_last >= ticks_between_stage * 0.8:
178                output_text += "You notice your plant looks different.\n"
179
180        output_text += get_stage_description(this_stage, description_num, this_species, this_color) + "\n"
181
182        # if seedling
183        if this_stage == 1:
184            species_options = [species_list[self.species],
185                    species_list[(self.species + 3) % len(species_list)],
186                    species_list[(self.species - 3) % len(species_list)]]
187            random.shuffle(species_options)
188            output_text += f"It could be a(n) {species_options[0]}, {species_options[1]} or {species_options[2]}.\n"
189        # if young plant
190        if this_stage == 2:
191            if self.rarity >= 2:
192                output_text += "You feel like your plant is special.\n"
193
194        # if mature plant
195        if this_stage == 3:
196            color_options = [color_list[self.color],
197                    color_list[(self.color + 3) % len(color_list)],
198                    color_list[(self.color - 3) % len(color_list)]]
199            random.shuffle(color_options)
200            output_text += f"You can see the first hints of {color_options[0]}, {color_options[1]}, or {color_options[2]}.\n"
201
202        return output_text