At this point you should ask yourself: "But how often do I need to draw the receiver or output without also drawing a neuron?". If the answer to that question is "probably never!", then you should just fold all of that functionality into the Neuron
class:
import math
import random
import pygame
class Neuron:
"""A single neuron with Synapses that connect to others"""
def __init__(self, x, y):
self.x = x
self.y = y
self.pos = x, y
self.width = 30
self.offset = self.width / 2
self.connections = []
self.angle = math.radians(random.randint(0, 360))
self.rect = (self.x - self.offset, self.y - self.offset,
self.width, self.width)
self.color = 200, 150, 50
def draw(self, surf):
pygame.draw.ellipse(surf, self.color, self.rect)
pygame.draw.ellipse(surf, *self.input)
pygame.draw.ellipse(surf, *self.output)
@property
def input(self):
color = 200, 255, 200
rect = self.calc_rect()
return color, rect
@property
def output(self):
color = 200, 255, 200
rect = self.calc_rect(output=True)
return color, rect
def calc_rect(self, output=False):
width = 0.5 * self.width
distance = 0.4 * self.width
offset = 0.25 * self.width
if output:
pos = (self.x + math.sin(self.angle) * distance,
self.y - math.cos(self.angle) * distance)
else:
pos = (self.x - math.sin(self.angle) * distance,
self.y + math.cos(self.angle) * distance)
return pos[0] - offset, pos[1] - offset, width, width
Here I did not go through the effort of making sure that Neuron.input
and Neuron.output
are only calculated once, but you could do it in the same way as I did above.
Note that I made all of your lists into tuples (like Neuron.pos
). This is just aesthetics atm, but if you want to be able to do e.g. neuron.pos[0] += 1
, then you need to make them lists again.