Skip to content

Commit

Permalink
updated
Browse files Browse the repository at this point in the history
  • Loading branch information
kul-sudo committed Aug 13, 2022
1 parent d6bcc39 commit 4350884
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 78 deletions.
2 changes: 1 addition & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
SMILEY = 1

NO_CREATURES = 0
SQUARES_ONE_SPECIES_WON = 1
ONE_SMILEY_SPECIES_WON = 1
ALL_ZOMBIES = 2
ONLY_ZOMBIE_BOSS = 3

Expand Down
14 changes: 7 additions & 7 deletions display_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import config

@handle
def D_find_average_from_smileys():
def D_find_average_from_smilies():
smilies_amount = len(smilies)

write_text_eventual = ''

averaged = {
'generation_n': round(fmean(smiley.generation_n for smiley in smilies)),
'plant_preference': round(fmean(1 if smiley.food_preference == PLANTS else 0 for smiley in smilies)), # Percent of smileys preferring plants
'plant_preference': round(fmean(1 if smiley.food_preference == PLANTS else 0 for smiley in smilies)), # Percent of smilies preferring plants
'vision_distance': round(fmean(smiley.vision_distance for smiley in smilies)),
'average_smiley_speed': round(fmean(smiley.speed for smiley in smilies)*SPEED_RATIO),
'procreation_threshold': round(fmean(smiley.procreation_threshold for smiley in smilies)),
Expand All @@ -25,7 +25,7 @@ def D_find_average_from_smileys():
averaged_analysis = {}

one_species_survived_line = 'One of the species has survived'
average_generation_number = f'The average generation number of the smileys of the survived species: {averaged["generation_n"]}'
average_generation_number = f'The average generation number of the smilies of the survived species: {averaged["generation_n"]}'

def ending() -> str: # Handling the 's' at the end of the word 'descendant'
return f"{smilies_amount} descendant{'s' if smilies_amount > 1 else ''} left"
Expand All @@ -39,7 +39,7 @@ def ending() -> str: # Handling the 's' at the end of the word 'descendant'
'energy': INITIAL_ENERGY
}

plant_preference_chance_text_turtle = round(sum(1 if smiley.food_preference == PLANTS else 0 for smiley in smilies)/smilies_amount*100) # Percent of smileys preferring plants
plant_preference_chance_text_turtle = round(sum(1 if smiley.food_preference == PLANTS else 0 for smiley in smilies)/smilies_amount*100) # Percent of smilies preferring plants
for property in averaged:
if property not in ('generation_n', 'descendants left', 'average_smiley_speed'):
if property == 'plant_preference':
Expand All @@ -66,9 +66,9 @@ def ending() -> str: # Handling the 's' at the end of the word 'descendant'
def D_display_results():
match evolution_status.result:
case config.NO_CREATURES:
write_text_eventual = 'Neither smileys nor zombies have survived'
case config.SQUARES_ONE_SPECIES_WON:
write_text_eventual = D_find_average_from_smileys()
write_text_eventual = 'Neither smilies nor zombies have survived'
case config.ONE_SMILEY_SPECIES_WON:
write_text_eventual = D_find_average_from_smilies()
case config.ONLY_ZOMBIE_BOSS:
write_text_eventual = 'Only the zombie boss has survived. This happens tremendously infrequently :)'
case _:
Expand Down
37 changes: 22 additions & 15 deletions draw_creatures.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
from ast import Return
from tkinter import ARC, PhotoImage
from tkinter.font import nametofont
from time import time

from config import *
from zombies_images import *
from global_items import evolution_status, smilies, zombies
from global_items import window_commands, evolution_status, smilies, zombies, boss_shape_size, zombie_shape_size

import global_items, config

# Zombie boss
def create_boss_image():
ZOMBIE_BOSS_SIZE_RATIO = 27 # Higher => smaller
# Equalizing the size of a smiley and the size of a zombie boss
global zombie_boss_shape, zombie_boss_width
global zombie_boss_shape
zombie_boss_shape = PhotoImage(data=ZOMBIE_BOSS).subsample(ZOMBIE_BOSS_SIZE_RATIO, ZOMBIE_BOSS_SIZE_RATIO)
global_items.zombie_boss_half_height = zombie_boss_shape.height()/2
zombie_boss_width = zombie_boss_shape.width()

boss_shape_size['half_width'] = zombie_boss_shape.width()/2
boss_shape_size['half_height'] = zombie_boss_shape.height()/2

def draw_zombie_boss():
global zombie_boss_shape
return global_items.canvas.create_image(
evolution_status.zombie_boss.x, evolution_status.zombie_boss.y,
image=zombie_boss_shape, tags='boss')
global_items.canvas.create_image(
evolution_status.zombie_boss.x, evolution_status.zombie_boss.y,
image=zombie_boss_shape, tags='boss')

def update_zombie_boss_image():
zombie_boss = evolution_status.zombie_boss
global_items.canvas.delete('boss')
zombie_boss.image_reference = draw_zombie_boss()
draw_zombie_boss()

# Demonstrating the fact that the zombie boss is sleeping/has wakened
def draw_z(x, y):
global_items.canvas.create_text(x, y, text='z', tags='z_z_z')

def draw_z_z_z():
'''Demonstrating the fact that the zombie boss is currently sleeping'''
global zombie_boss_width
zombie_boss = evolution_status.zombie_boss
if zombie_boss is None:
return
x_base = zombie_boss.x+zombie_boss_width/2
x_base = zombie_boss.x+boss_shape_size['half_width']
draw_z(x_base+2, zombie_boss.y-7)
draw_z(x_base+7, zombie_boss.y-13)
draw_z(x_base+12, zombie_boss.y-21)
Expand All @@ -57,21 +57,23 @@ def create_zombies_image():
# Equalizing the size of a smiley and the size of a zombie
global zombie_shape
zombie_shape = PhotoImage(data=ZOMBIE).subsample(ZOMBIE_SIZE_RATIO, ZOMBIE_SIZE_RATIO)
global_items.zombie_half_height = zombie_shape.height()/2

zombie_shape_size['half_height'] = zombie_shape.height()/2
zombie_shape_size['half_width'] = zombie_shape.width()/2

def draw_zombie(zombie):
global zombie_shape
return global_items.canvas.create_image(zombie.x, zombie.y, image=zombie_shape, tags='zombie')
global_items.canvas.create_image(zombie.x, zombie.y, image=zombie_shape, tags='zombie')

def update_zombie_images():
'''Erasing all of the zombies that have already been drawn and drawing new ones.'''
global_items.canvas.delete('zombie')
for zombie in zombies:
zombie.image_reference = draw_zombie(zombie)
draw_zombie(zombie)

# Drawing the smilies
def update_smiley_images():
'''Erasing all of the smileys that have already been drawn and drawing new ones.'''
'''Erasing all of the smilies that have already been drawn and drawing new ones.'''
global_items.canvas.delete('smiley')
for smiley in smilies:
smiley.image_reference = draw_smiley(smiley)
Expand Down Expand Up @@ -191,11 +193,16 @@ def draw_smiley(smiley):
smiley.stimulus_start = now
# Storing the time when the stimulus was resolved to be displayed
# The stimulus might be displayed in a succeeding tact

if time() > smiley.stimulus_start + DISPLAY_PERIOD\
or window_commands['to-show-selected-property'] != 'Nothing'\
or smiley.stimulus_start == now: # The stimulus is not displayed if there was one-tact-long sleep between active states (not sleeping)

draw_sleeping_smiley(smiley_to_draw)
else:
draw_aggressive_smiley(smiley_to_draw)

# The stimulus by smilies
x0, y0 = smiley_to_draw.x+0.5*SMILEY_SIZE, smiley_to_draw.y-2.3*SMILEY_SIZE
x1, y1 = x0+46, y0+28, # 46 and 28 have been chosen manually
tags = ('stimulus', smiley_to_draw.smiley_tag, 'smiley')
Expand Down
44 changes: 33 additions & 11 deletions draw_non_creatures.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from time import time
from tkinter import LAST, S, N
from tkinter import LAST, S, N, E

from config import *
from zombies_images import *
from crosses import crosses_list
from global_items import zombies, distance_between_objects, handle, smilies, plants, window_commands, evolution_status
from global_items import zombies, distance_between_objects, handle, smilies, plants, window_commands, evolution_status, boss_shape_size, zombie_shape_size
import global_items

# Plants
Expand Down Expand Up @@ -101,23 +101,41 @@ def display_property(creature: object, text: str, exceeding_y=0):
anchor=S
)

def display_collision_result(creature: object, decrease_x: int | float):
'''Displaying stuff related to the collision.'''
number = round(creature.collision.result)
sign = '+' if number >= 0 else '–'
text = f'{sign}{abs(number)}'
global_items.canvas.create_text(
creature.x-decrease_x-2, creature.y,
text=text,
tags='property',
anchor=E,
fill='blue' if sign == '+' else 'red'
)

NONE = 'None'
NEWLY_BORN_PERIOD = 4 # In seconds
COLLISION_RESULTS_DISPLAY_PERIOD = 1 # How long the stuff related to the collision shall be displaed

@handle
def D_handle_properties():
# Handling the properties displayed over creatures
global_items.canvas.delete('property')
global_items.canvas.delete('circle')

now = time()

for smiley in smilies:
match window_commands['to-show-selected-property']:
case 'Energy/health':
display_property(creature=smiley, text=round(smiley.energy), exceeding_y=HALF_SMILEY_SIZE)
if now < smiley.collision.moment + COLLISION_RESULTS_DISPLAY_PERIOD:
display_collision_result(smiley, HALF_SMILEY_SIZE)
case 'Speed':
display_property(creature=smiley, text=round(smiley.speed*SPEED_RATIO), exceeding_y=HALF_SMILEY_SIZE)
case '"Newly born" if newly born':
display_property(creature=smiley, text='Newly born' if time() <= smiley.birth_time + NEWLY_BORN_PERIOD and smiley.generation_n != 0 else '', exceeding_y=HALF_SMILEY_SIZE)
display_property(creature=smiley, text='Newly born' if now <= smiley.birth_time + NEWLY_BORN_PERIOD and smiley.generation_n != 0 else '', exceeding_y=HALF_SMILEY_SIZE)
case 'Procreation threshold':
display_property(creature=smiley, text=round(smiley.procreation_threshold), exceeding_y=HALF_SMILEY_SIZE)
case 'Food preference':
Expand All @@ -142,28 +160,32 @@ def D_handle_properties():
if not global_items.mask_exists:
draw_one_vision_distance_circle(creature=zombie_boss)
case 'Energy/health':
display_property(creature=zombie_boss, text=round(zombie_boss.health), exceeding_y=global_items.zombie_boss_half_height)
display_property(creature=zombie_boss, text=round(zombie_boss.health), exceeding_y=boss_shape_size['half_height'])
if now < zombie_boss.collision.moment + COLLISION_RESULTS_DISPLAY_PERIOD:
display_collision_result(zombie_boss, boss_shape_size['half_width'])
case 'Speed':
display_property(creature=zombie_boss, text=round(zombie_boss.speed*SPEED_RATIO), exceeding_y=global_items.zombie_boss_half_height)
display_property(creature=zombie_boss, text=round(zombie_boss.speed*SPEED_RATIO), exceeding_y=boss_shape_size['half_height'])
case _:
display_property(creature=zombie_boss, text=NONE, exceeding_y=global_items.zombie_boss_half_height)
display_property(creature=zombie_boss, text=NONE, exceeding_y=boss_shape_size['half_height'])

# Writing for zombies
for zombie in zombies:
match window_commands['to-show-selected-property']:
case 'Nothing':
continue
case 'Energy/health':
display_property(creature=zombie, text=round(zombie.health), exceeding_y=global_items.zombie_half_height)
display_property(creature=zombie, text=round(zombie.health), exceeding_y=zombie_shape_size['half_height'])
if now < zombie.collision.moment + COLLISION_RESULTS_DISPLAY_PERIOD:
display_collision_result(zombie, zombie_shape_size['half_width'])
case 'Speed':
display_property(creature=zombie, text=round(zombie.speed*SPEED_RATIO), exceeding_y=global_items.zombie_half_height)
display_property(creature=zombie, text=round(zombie.speed*SPEED_RATIO), exceeding_y=zombie_shape_size['half_height'])
case 'Vision distance':
draw_one_vision_distance_circle(creature=zombie)
case _:
display_property(creature=zombie, text=NONE, exceeding_y=global_items.zombie_half_height)
display_property(creature=zombie, text=NONE, exceeding_y=zombie_shape_size['half_height'])

# Stimulus
STIMULUS_DELAY: int = 25 # Displaying the stimulus toward the zombie boss in STIMULUS_DELAY seconds of inaction
STIMULUS_DELAY: int = 15 # Displaying the stimulus toward the zombie boss in STIMULUS_DELAY seconds of inaction

def set_stimulus_start_time():
# The stimulus is only displayed above the smilies which recently started sleeping
Expand All @@ -179,7 +201,7 @@ def display_stimulus(): # This function is called every second
zombie_boss = evolution_status.zombie_boss
if zombie_boss is not None:
global_items.canvas.create_text(
zombie_boss.x, zombie_boss.y+global_items.zombie_boss_half_height,
zombie_boss.x, zombie_boss.y+boss_shape_size['half_height'],
text='Lazy lounger!',
tags='stimulus',
anchor=N)
Expand Down
6 changes: 3 additions & 3 deletions evolution.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from tkinter import DISABLED
from config import *
from smileys_functions import create_zero_generation, D_delete_all_smileys
from smilies_functions import create_zero_generation, D_delete_all_smilies
from mask import D_delete_mask, D_handle_mask
from plants import create_initial_plants, create_plant_image, D_delete_all_plants
from draw_non_creatures import update_plant_images
Expand Down Expand Up @@ -35,7 +35,7 @@ def evolution():
evolution_status.description = DELETE_ERASE_EVERYTHING
global_items.stimulus_on = False
D_delete_mask()
D_delete_all_smileys()
D_delete_all_smilies()
D_delete_all_zombies()
D_delete_all_plants()
D_delete_all_crosses()
Expand All @@ -46,7 +46,7 @@ def evolution():

# Evolution prep
evolution_status.description = EVOLUTION_PREPARATION
global_items.canvas.create_rectangle(2, 2, evolution_field['width']+1, evolution_field['height']+1) # Evolution field frame
global_items.canvas.create_rectangle(2, 2, evolution_field['width']+1, evolution_field['height']+1, tags='frame') # Evolution field frame
create_zero_generation()
create_initial_plants()
update_smiley_images()
Expand Down
9 changes: 5 additions & 4 deletions evolution_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ def one_evolution():
D_one_evolution_step()
fps_clock.tick(FPS)

smileys_empty, zombies_empty = smilies == [], zombies == []
if smileys_empty and not zombies_empty:
smilies_empty, zombies_empty = smilies == [], zombies == []
if smilies_empty and not zombies_empty:
evolution_status.result = ALL_ZOMBIES
elif smileys_empty and zombies_empty:
elif smilies_empty and zombies_empty:
if evolution_status.zombie_boss is None:
evolution_status.result = NO_CREATURES
else:
evolution_status.result = ONLY_ZOMBIE_BOSS
elif zombies_empty and evolution_status.zombie_boss is None and len(set(smiley.species for smiley in smilies)) == 1:
evolution_status.result = SQUARES_ONE_SPECIES_WON
evolution_status.result = ONE_SMILEY_SPECIES_WON

if evolution_status.result is not None:
return
Expand Down Expand Up @@ -62,6 +62,7 @@ def D_one_evolution_step():
delete_old_cross()
update_cross_images()
D_handle_properties()
global_items.canvas.tag_raise('frame', 'all')
global_items.canvas.update()
if window_commands['run/pause'] == PAUSE:
evolution_status.description = PAUSED
Expand Down
9 changes: 9 additions & 0 deletions global_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ def __init__(self):
self.zombie_boss = None
self.result = None

class Collision:
'''Data about a collision with a smiley or a plant'''
def __init__(self):
self.result = None # The amount of received/spent energy/health
self.moment = float('-inf') # The time when the collision took place

class Creature: # For the smilies, normal zombies and the zombie boss
def __init__(
self,
Expand All @@ -31,6 +37,7 @@ def __init__(
self.vision_distance = vision_distance
self.speed = speed
self.x, self.y = x, y
self.collision = Collision()

class CreatureStatus:
def __init__(self):
Expand Down Expand Up @@ -65,6 +72,8 @@ def __init__(
evolution_field = {}
smilies_data ={}
scales = {}
boss_shape_size = {}
zombie_shape_size = {}

# Functions
def delete_help_window(event=None):
Expand Down
Loading

0 comments on commit 4350884

Please sign in to comment.