Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_basic_evolution.py
- import random
- import tkinter as tk
- LETTER_SUCCESSORS = {
- 'a': list('bcdfghjklmnprstvwxz'),
- 'b': list('aeiloruy'),
- 'c': list('acehlortu'),
- 'd': list('aeioruyl'),
- 'e': list('abcdefgilmnoprstuvwxz'),
- 'f': list('aeiloruy'),
- 'g': list('abeiloruy'),
- 'i': list('abcdefgilmnoprstuvwxz'),
- 'l': list('aeioruyl'),
- 'm': list('aeiloruy'),
- 'n': list('aeioruy'),
- 'o': list('abcdefgilmnoprstuvwxz'),
- 'p': list('aehloruy'),
- 'r': list('aeioruy'),
- 's': list('aeioruyhpt'),
- 't': list('aeiohrsy'),
- 'u': list('abcdefgilmnoprstuvwxz'),
- 'w': list('aeiloruy'),
- 'y': list('abcdefgilmnoprstuvwxz'),
- }
- DOUBLED_LETTERS = set('eltsonrdpfgmbc')
- ALPHABET = list(LETTER_SUCCESSORS)
- MAX_LENGTH = 120
- MAX_SPECIES = 1000
- VOWELS = set('aeiouy')
- CONSONANTS = set(ALPHABET) - VOWELS
- species = set(['e'])
- extinct_species = {}
- all_species_ordered = ['e']
- ancestry = {'e': '-'}
- fossilization_status = {}
- canvas_items = {}
- root = tk.Tk()
- root.title('Brevity Words Evolution')
- root.geometry('1080x640+0+0')
- frame = tk.Frame(root)
- frame.pack(fill='both', expand=True)
- canvas = tk.Canvas(frame, bg='white', width=1000, height=640)
- canvas.pack(side='left', fill='both', expand=True)
- vscrollbar = tk.Scrollbar(frame, orient='vertical', command=canvas.yview)
- vscrollbar.pack(side='right', fill='y')
- canvas.configure(yscrollcommand=vscrollbar.set)
- def update_species_on_canvas(specie, index=-1):
- ancestor = ancestry.get(specie, 'Unknown')
- display_text = f"Ancestor: '{ancestor}' >>> Species: '{specie}'"
- if specie in species or len(specie) < 3:
- fill_color = 'black'
- else:
- fill_color = 'red'
- fossil_status = fossilization_status.get(specie, 'not fossilized')
- display_text += f" went extinct{fossil_status}"
- if index != -1:
- y_pos = 10 + index * 24
- x_start = 10
- text_id = canvas.create_text(x_start, y_pos, anchor='nw', text=display_text, font=('Consolas', 12), fill=fill_color)
- canvas_items[specie] = text_id
- canvas.configure(scrollregion=(0, 0, 0, y_pos + 40))
- else:
- canvas.itemconfig(canvas_items[specie], text=display_text, fill=fill_color)
- def show_species_on_canvas():
- canvas.delete('all')
- canvas_items.clear()
- for i, specie in enumerate(all_species_ordered):
- update_species_on_canvas(specie, i)
- def count_consec_letter_types(word, pos):
- letter = word[pos]
- is_vowel = letter in VOWELS
- count = 1
- i = pos - 1
- while i >= 0:
- if (word[i] in VOWELS) == is_vowel:
- count += 1
- i -= 1
- else:
- break
- i = pos + 1
- while i < len(word):
- if (word[i] in VOWELS) == is_vowel:
- count += 1
- i += 1
- else:
- break
- return count
- def can_insert_letter(word, index, letter):
- if len(word) + 1 > MAX_LENGTH:
- return False
- new_word = word[:index] + letter + word[index:]
- if len(new_word) >= 2 and new_word[0] == new_word[1]:
- return False
- start = max(0, index - 2)
- end = min(len(new_word), index + 3)
- for i in range(start, end - 2):
- if new_word[i] == new_word[i + 1] == new_word[i + 2]:
- return False
- if index > 0:
- prev_letter = new_word[index - 1]
- if letter not in LETTER_SUCCESSORS.get(prev_letter, ALPHABET):
- return False
- if index < len(new_word) - 1:
- next_letter = new_word[index + 1]
- if next_letter not in LETTER_SUCCESSORS.get(letter, ALPHABET):
- return False
- consec_count = count_consec_letter_types(new_word, index)
- if consec_count > 2:
- return False
- return True
- def is_valid_double(parent, insert_index, letter):
- if insert_index != 0:
- candidate = parent[:insert_index] + letter * 2 + parent[insert_index:]
- if len(candidate) >= 2 and candidate[0] == candidate[1]:
- return False, None
- triple_repeats = any(candidate[i] == candidate[i+1] == candidate[i+2] for i in range(len(candidate) - 2))
- valid_double = True
- if insert_index > 0:
- if letter not in LETTER_SUCCESSORS.get(parent[insert_index - 1], ALPHABET):
- valid_double = False
- if insert_index < len(parent):
- if parent[insert_index] not in LETTER_SUCCESSORS.get(letter, ALPHABET):
- valid_double = False
- if letter not in LETTER_SUCCESSORS.get(letter, ALPHABET):
- valid_double = False
- if triple_repeats:
- valid_double = False
- if valid_double and (count_consec_letter_types(candidate, insert_index) > 2 or count_consec_letter_types(candidate, insert_index + 1) > 2):
- valid_double = False
- return valid_double, candidate
- return False, None
- def evolve():
- global species, all_species_ordered, ancestry
- new_species = set(species)
- living = [word for word in species if len(word) < MAX_LENGTH]
- attempts = 0
- added = 0
- new_additions = []
- while added < 1000 and attempts < 5000:
- attempts += 1
- parent = random.choice(living)
- if len(parent) == 0:
- continue
- letter = random.choice(ALPHABET)
- insert_index = random.randint(0, len(parent))
- if not can_insert_letter(parent, insert_index, letter):
- continue
- if letter in DOUBLED_LETTERS and random.random() < 0.3:
- valid_double, candidate = is_valid_double(parent, insert_index, letter)
- if valid_double:
- offspring = candidate
- else:
- offspring = parent[:insert_index] + letter + parent[insert_index:]
- else:
- offspring = parent[:insert_index] + letter + parent[insert_index:]
- if offspring not in species and offspring not in new_species:
- new_species.add(offspring)
- all_species_ordered.append(offspring)
- ancestry[offspring] = parent
- new_additions.append(offspring)
- added += 1
- species = new_species
- for i, specie in enumerate(new_additions):
- update_species_on_canvas(specie, len(all_species_ordered) - len(new_additions) + i)
- def extinction():
- global species, extinct_species, fossilization_status
- if len(species) > MAX_SPECIES:
- extinct_amount = random.randint(200, 500)
- to_extinct = random.sample(list(species), extinct_amount)
- for death in to_extinct:
- fossil_status = '' if random.randint(0, 7) else ' and fossilized'
- species.remove(death)
- extinct_species[death] = True
- fossilization_status[death] = fossil_status
- if death not in canvas_items:
- return
- update_species_on_canvas(death)
- def run_simulation():
- evolve()
- extinction()
- root.after(1000, run_simulation)
- def on_mousewheel(event):
- canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
- canvas.bind_all("<MouseWheel>", on_mousewheel)
- show_species_on_canvas()
- root.after(0, run_simulation)
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment