Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
Optimized the rendering. The overall performance is a lot faster.
Fixed a bug where mutation chance did not work.
Changed the rendering button from enter to r.
Renamed a few variables and functions
  • Loading branch information
ThatSoundsFun committed Jul 16, 2016
1 parent 051e114 commit 3205476
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 88 deletions.
32 changes: 20 additions & 12 deletions game_class.py
Expand Up @@ -2,15 +2,22 @@
import pygame

pygame.init()
width, height = 800, 800
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
background_color = (255,255,255)

class Game:
running = True
toggle_render = True
tick = 0
screen = None

def init_screen(width, height):
Game.screen = pygame.display.set_mode((width, height))
Game.screen.fill((255,255,255))
pygame.display.update()

def clear_screen():
Game.screen.fill((255,255,255))
pygame.display.update()

def load_from_file(file, *default):
#if no data is found, then it will return default instead
Expand All @@ -25,20 +32,21 @@ def events():
for event in pygame.event.get():
if event.type == pygame.QUIT:
Game.running = False
elif event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
elif event.type == pygame.KEYDOWN and event.key == pygame.K_r:
if Game.toggle_render == True:
Game.toggle_render = False
Game.clear_screen()
else:
Game.toggle_render = True
Game.clear_screen()

def update_screen(max_fps):
pygame.display.update()
screen.fill(background_color)
if Game.toggle_render == True:
clock.tick(max_fps)

def dump_save(input, file):
def dump_save(file, *input):
print('Saving To file...')
with open(file,'wb') as file:
pickle.dump(input, file)
print('Done')
print('Done')

def tick_add(max_fps):
Game.tick += 1
if max_fps != None:
clock.tick(max_fps)
25 changes: 14 additions & 11 deletions main.py
Expand Up @@ -7,32 +7,35 @@
#config
save_file = 'wormloop_save.p'
log_file = 'wormloop-log.txt'
max_fps = 100
max_fps = None

unit = 5
random_seed = 0
width = 800
height = 800

sunlight_chance = 10 #actual chance is 1 / value
mutation_chance = 1000 #actual chance is 1 / value

random_seed = 2
starting_pattern = [['north', 400, 400],['south', -10, -10]], deque(['r','r','l','l','l','.','.','.','x']), [0,0,0]

Game.init_screen(width, height)
seed(random_seed)
Worm.list, Game.tick = Game.load_from_file(save_file, Worm.list, Game.tick)
Worm.first_init(*starting_pattern)
Worm.list, Game.tick = Game.load_from_file(save_file, Worm.list, Game.tick)
while Game.running == True:
Worm.clean_list(log_file)
Worm.check_collision()
Worm.check_collision(width, height, unit)
Worm.start_replication()
Worm.can_replicate(sunlight_chance)
Worm.move_worm(unit)
for self in Worm.list:
self.rotate_gene()
self.move_snake(unit)
self.change_direction()
self.mutation(mutation_chance)
self.display(unit)
self.mutation(mutation_chance, unit)
self.age += 1
Game.tick += 1
Game.tick_add(max_fps)
Game.events()
Game.update_screen(max_fps)


pygame.quit()
Game.dump_save((Worm.list, Game.tick), save_file)
Game.dump_save(save_file, Worm.list, Game.tick)
137 changes: 72 additions & 65 deletions worm_class.py
Expand Up @@ -4,7 +4,7 @@
from random import randrange
from collections import deque

dead_color = (240,240,240)
dead_color = (230,230,230)

class Worm:
list = []
Expand All @@ -18,16 +18,15 @@ def init(body, gene, color):

def first_init(*parameters):
#prevents the worm from initializing again after start
print(len(Worm.list))
if len(Worm.list) == 0:
Worm.init(*parameters)


def __init__(self, body, gene, color):
self.body = body
self.body_length = len(body)
self.gene = gene
self.color = color
self.body = body
self.length = len(body)
self.gene = gene
self.color = color

self.age = 0
self.is_dead = False
Expand All @@ -45,7 +44,7 @@ def is_completely_gone(self, log_file):
def write_worm_info(self, log_file):
#appends info about dying worm to file
gene = self.rotated_marker()
body = str(self.body_length)
body = str(self.length)
color = '{} {} {}'.format(str(self.color[0]).zfill(3), str(self.color[1]).zfill(3), str(self.color[2]).zfill(3))
age = str(self.age)
tick = Game.tick
Expand All @@ -67,25 +66,34 @@ def rotated_marker(self):
gene.rotate(1)
return ''.join(gene).replace('x','')

def check_collision():
def check_collision(width, height, unit):
for worm1 in Worm.list:
for worm2 in Worm.list:
#body[0][1:] is the head of the worm without the direction string
#body[1:] is the worm excluding head

for part in worm2.body[1:]:
if worm1.body[0][1:] == part[1:]:
for segment in worm2.body[1:]:
if worm1.body[0][1:] == segment[1:]:
#collision with body excluding head
worm1.is_dead = True
worm1.grey_out(unit)
break

if worm1.body[0][1:] == worm2.body[0][1:] and worm1 is not worm2:
#collision with head
worm1.is_dead = True
worm1.grey_out(unit)

if worm1.body[0][1] < 0 or worm1.body[0][1] >= width or worm1.body[0][2] < 0 or worm1.body[0][2] >= height:
#collision with boundary
worm1.is_dead = True
worm1.grey_out(unit)

def grey_out(self, unit):
if Game.toggle_render == True:
for segment in self.body:
pygame.draw.rect(Game.screen, dead_color, (segment[1], segment[2], unit, unit))
pygame.display.update(segment[1], segment[2], unit, unit)

def start_replication():
for worm1 in Worm.list:
Expand All @@ -99,18 +107,51 @@ def start_replication():

def can_replicate(sunlight_chance):
for worm1 in Worm.list:
for worm1_part in worm1.body:
if worm1_part[0] == 'north' and Worm.can_get_sunlight(worm1_part) == True and int(randrange(0,sunlight_chance)) == 0:
for worm1_segment in worm1.body:
if worm1_segment[0] == 'north' and Worm.can_get_sunlight(worm1_segment) == True and int(randrange(0,sunlight_chance)) == 0:
worm1.will_replicate = True
break


def can_get_sunlight(worm1_part):
def can_get_sunlight(worm1_segment):
#checks if no other worm is blocking this worm segment for sunlight
for worm2 in Worm.list:
for worm2_part in worm2.body:
if worm1_part[1] < worm2_part[1] and worm1_part[2] == worm2_part[2]:

for worm2_segment in worm2.body:
if worm1_segment[1] < worm2_segment[1] and worm1_segment[2] == worm2_segment[2]:
return False
return True


def move_worm(unit):
#every single tail must be updated first before the heads
#todo: maybe move the update part to a seperate function
for self in Worm.list:
self.update_tail(unit)

for self in Worm.list:
if self.is_dead == False:
self.body.insert(0, self.body[0].copy())
if self.body[0][0] == 'north':
self.body[0][2] -= unit
elif self.body[0][0] == 'south':
self.body[0][2] += unit
elif self.body[0][0] == 'west':
self.body[0][1] -= unit
elif self.body[0][0] == 'east':
self.body[0][1] += unit
self.update_head(unit)

del self.body[-1]

def update_head(self, unit):
if Game.toggle_render == True:
pygame.draw.rect(Game.screen, self.color, (self.body[0][1],self.body[0][2] , unit, unit))
pygame.display.update(self.body[0][1],self.body[0][2], unit, unit)

def update_tail(self, unit):
if Game.toggle_render == True:
pygame.draw.rect(Game.screen, (255,255,255), (self.body[-1][1],self.body[-1][2], unit, unit))
pygame.display.update(self.body[-1][1],self.body[-1][2], unit, unit)

def change_direction(self):
if self.is_dead == False and self.will_replicate == False:
Expand Down Expand Up @@ -144,24 +185,11 @@ def rotate_gene(self):
if self.will_replicate == False:
self.gene.rotate(1)
if self.gene[0] == 'x':
#'x' is a marker and must be ignored
self.gene.rotate(1)

def move_snake(self, unit):
if self.is_dead == False:
self.body.insert(0, self.body[0].copy())
if self.body[0][0] == 'north':
self.body[0][2] -= unit
elif self.body[0][0] == 'south':
self.body[0][2] += unit
elif self.body[0][0] == 'west':
self.body[0][1] -= unit
elif self.body[0][0] == 'east':
self.body[0][1] += unit

del self.body[-1]

def mutation(self, mutation_chance):
if int(randrange(0,1000)) == 0:

def mutation(self, mutation_chance, unit):
if int(randrange(0,mutation_chance)) == 0:
type = int(randrange(0,6))
if type == 0:
self.mutation_add_turn_gene()
Expand All @@ -174,7 +202,7 @@ def mutation(self, mutation_chance):
elif type == 4:
self.mutation_add_body_length()
elif type == 5:
self.mutation_remove_body_length()
self.mutation_remove_body_length(unit)

def mutation_add_turn_gene(self):
turn_type = int(randrange(0,2))
Expand Down Expand Up @@ -204,44 +232,23 @@ def mutation_remove_forward_gene(self):

def mutation_add_body_length(self):
self.body.append(['south',-10,-10])
self.body_length += 1
self.length += 1

def mutation_remove_body_length(self):
def mutation_remove_body_length(self, unit):
if len(self.body) > 1:
self.body_length -= 1
self.length -= 1
self.update_tail(unit)
del self.body[-1]

def new_color(self):
color = bin(randrange(0,63)).replace('0b', '').zfill(6)

red = color[0:2]
green = color[2:4]
blue = color[4:6]
#Red must not go above 200 or else the worm can become white or light grey which are the colors of the background and dying worms.
#There are 64 possible colors a worm can be.
red = randrange(0,4) * 65
green = randrange(0,4) * 85
blue = randrange(0,4) * 85

#red must not go above 200 or else the worm can become white or light grey which are the colors of the background and dying worms
red = int(red,2) * 60
green = int(blue,2) * 80
blue = int(blue,2) * 80
self.color = [red, green, blue]

self.color = [red, green, blue]

if all([c >= 200 for c in self.color]) == True:
#this prevents the worm from becoming white or light grey, which the background and dead worm uses.
self.color = [150,150,150]
self.new_color()


def display(self, unit):
if Game.toggle_render == True:
if self.is_dead == False:
#colors it normally if it didn't die.
for part in self.body:
pygame.draw.rect(screen, self.color, [part[1], part[2], unit, unit])
else:
#colors it gray if it did die.
for part in self.body:
pygame.draw.rect(screen, dead_color, [part[1], part[2], unit, unit])

def debug(self):
print(self.body)

0 comments on commit 3205476

Please sign in to comment.