#!/usr/bin/env python3
##############################################################################
# EVOLIFE  http://evolife.telecom-paris.fr             <NAME>  #
# Telecom Paris  2021                                      www.dessalles.fr  #
# -------------------------------------------------------------------------- #
# License:  Creative Commons BY-NC-SA                                        #
##############################################################################

""" Simple trajectory display (here, Brownian movement)
"""

from random import randint	# for Brownian movement

import sys
sys.path.append('../..')

import Evolife.QtGraphics.Evolife_Window as EW
import Evolife.Ecology.Observer as EO
import Evolife.QtGraphics.Curves as EC

NBAGENTS = 4
MAXSTEP = 10

class Agent:
	"   class Agent: defines what an individual consists of "
	def __init__(self, IdNb):
		self.ID = "A%d" % IdNb	# Identity number
		# basic colours are displayed at the right of Evolife curve display, from bottom up. Otherwise, use 'Shade'
		if IdNb % 2:	self.Colour = EC.Shade(IdNb, BaseColour='red', Max=NBAGENTS, darkToLight=False)
		else:			self.Colour = EC.Shade(IdNb, BaseColour='blue', Max=NBAGENTS)
		self.Size = 3
		self.CLocation = complex(50,50)

	def Location(self, NewLoc = None):
		if NewLoc is not None:
			self.CLocation.real, self.CLocation.imag = NewLoc[:2]
		return self.CLocation.real, self.CLocation.imag, self.Colour, self.Size

	def move(self, StepLoc=None):
		if StepLoc is None:
			# Just a Brownian movement
			step = randint(1,MAXSTEP)
			StepLoc = (randint(-step, step), randint(-step, step))
		NewCLoc = self.CLocation + complex(*StepLoc)
		# Coordinates:  (x, y, colour, size, toX, toY, segmentColour, segmentThickness)
		Segment = self.Location() + (NewCLoc.real, NewCLoc.imag, self.Colour, self.Size) 
		self.CLocation = NewCLoc
		return Segment
		
class Population:
	" defines the population of agents "

	def __init__(self, NbAgents, Observer):
		" creates a population of agents "
		self.Pop = [Agent(IdNb) for IdNb in range(NbAgents)]
		self.Obs = Observer
				 
	def __iter__(self):	return iter(self.Pop)	# allows to loop over Population
	
	#----------------------------------------------#	  
	# This function is run at each simulation step #	
	#----------------------------------------------#	  
	def one_year(self):
		self.Obs.StepId += 1	# updates simulation step in Observer
		for agent in self.Pop:	
			self.Obs.record(agent.move(), Window='Trajectories')
		return True

def Start():
	Obs = EO.Generic_Observer(TimeLimit=500)   # Observer stores graphic orders and performs statistics
	Obs.recordInfo('Title', "Trajectory display")

	# the following information will be displayed in the "Legend" window
	Obs.recordInfo('WindowLegends', """The "Trajectories" window shows agents' movements """)

	Obs.recordInfo('TrajectoriesWallpaper', '../../Evolife/QtGraphics/EvolifeBG.png')
	Obs.recordInfo('TrajectoriesTitle', 'Trajectories')
	
	# Evolife will start with this window open - sizes are in pixels
	# Obs.recordInfo('DefaultViews',	[('Trajectories', 300, 240)])	# just dimensions
	# Obs.recordInfo('DefaultViews',	[('Trajectories', 400, 200, 300, 240)])	# position and dimensions
	Obs.recordInfo('DefaultViews',	[('Trajectories', 400, 200, 300, 240, 0, 0, 0, 0)])	# Additional coordinates are margins
	
	Pop = Population(NbAgents=NBAGENTS, Observer=Obs)   # population of agents

	#--------------------------------------------------------------------------#
	# Start: launching Evolife window system                                   #
	#--------------------------------------------------------------------------#

	EW.Start(
		Pop.one_year, 	# this call-back function is called each year
		Obs, 	
		Capabilities='PT'	# means "photo" + "trajectory window"
		)
	

if __name__ == "__main__":
		print(__doc__)
		Start()
		print("Bye.......")


__author__ = 'Dessalles'

#!/usr/bin/env python3
##############################################################################
# EVOLIFE  http://evolife.telecom-paris.fr             <NAME>  #
# Telecom Paris  2021                                      www.dessalles.fr  #
# -------------------------------------------------------------------------- #
# License:  Creative Commons BY-NC-SA                                        #
##############################################################################

""" Simple trajectory display (here, Brownian movement)
"""

from random import randint	# for Brownian movement

import sys
sys.path.append('../..')

import Evolife.QtGraphics.Evolife_Window as EW
import Evolife.Ecology.Observer as EO
import Evolife.QtGraphics.Curves as EC

NBAGENTS = 4
MAXSTEP = 10

class Agent:
	"   class Agent: defines what an individual consists of "
	def __init__(self, IdNb):
		self.ID = "A%d" % IdNb	# Identity number
		# basic colours are displayed at the right of Evolife curve display, from bottom up. Otherwise, use 'Shade'
		if IdNb % 2:	self.Colour = EC.Shade(IdNb, BaseColour='red', Max=NBAGENTS, darkToLight=False)
		else:			self.Colour = EC.Shade(IdNb, BaseColour='blue', Max=NBAGENTS)
		self.Size = 3
		self.CLocation = complex(50,50)

	def Location(self, NewLoc = None):
		if NewLoc is not None:
			self.CLocation.real, self.CLocation.imag = NewLoc[:2]
		return self.CLocation.real, self.CLocation.imag, self.Colour, self.Size

	def move(self, StepLoc=None):
		if StepLoc is None:
			# Just a Brownian movement
			step = randint(1,MAXSTEP)
			StepLoc = (randint(-step, step), randint(-step, step))
		NewCLoc = self.CLocation + complex(*StepLoc)
		# Coordinates:  (x, y, colour, size, toX, toY, segmentColour, segmentThickness)
		Segment = self.Location() + (NewCLoc.real, NewCLoc.imag, self.Colour, self.Size) 
		self.CLocation = NewCLoc
		return Segment
		
class Population:
	" defines the population of agents "

	def __init__(self, NbAgents, Observer):
		" creates a population of agents "
		self.Pop = [Agent(IdNb) for IdNb in range(NbAgents)]
		self.Obs = Observer
				 
	def __iter__(self):	return iter(self.Pop)	# allows to loop over Population
	
	#----------------------------------------------#	  
	# This function is run at each simulation step #	
	#----------------------------------------------#	  
	def one_year(self):
		self.Obs.StepId += 1	# updates simulation step in Observer
		for agent in self.Pop:	
			self.Obs.record(agent.move(), Window='Trajectories')
		return True

def Start():
	Obs = EO.Generic_Observer(TimeLimit=500)   # Observer stores graphic orders and performs statistics
	Obs.recordInfo('Title', "Trajectory display")

	# the following information will be displayed in the "Legend" window
	Obs.recordInfo('WindowLegends', """The "Trajectories" window shows agents' movements """)

	Obs.recordInfo('TrajectoriesWallpaper', '../../Evolife/QtGraphics/EvolifeBG.png')
	Obs.recordInfo('TrajectoriesTitle', 'Trajectories')
	
	# Evolife will start with this window open - sizes are in pixels
	# Obs.recordInfo('DefaultViews',	[('Trajectories', 300, 240)])	# just dimensions
	# Obs.recordInfo('DefaultViews',	[('Trajectories', 400, 200, 300, 240)])	# position and dimensions
	Obs.recordInfo('DefaultViews',	[('Trajectories', 400, 200, 300, 240, 0, 0, 0, 0)])	# Additional coordinates are margins
	
	Pop = Population(NbAgents=NBAGENTS, Observer=Obs)   # population of agents

	#--------------------------------------------------------------------------#
	# Start: launching Evolife window system                                   #
	#--------------------------------------------------------------------------#

	EW.Start(
		Pop.one_year, 	# this call-back function is called each year
		Obs, 	
		Capabilities='PT'	# means "photo" + "trajectory window"
		)
	

if __name__ == "__main__":
		print(__doc__)
		Start()
		print("Bye.......")


__author__ = 'Dessalles'

#!/usr/bin/env python3 ############################################################################## # EVOLIFE  http://evolife.telecom-paris.fr             <NAME>  # # Telecom Paris  2021                                      www.dessalles.fr  # # -------------------------------------------------------------------------- # # License:  Creative Commons BY-NC-SA                                        # ############################################################################## Simple trajectory display (here, Brownian movement) # for Brownian movement # Identity number # basic colours are displayed at the right of Evolife curve display, from bottom up. Otherwise, use 'Shade' # Just a Brownian movement # Coordinates:  (x, y, colour, size, toX, toY, segmentColour, segmentThickness) # allows to loop over Population #----------------------------------------------# # This function is run at each simulation step # #----------------------------------------------# # updates simulation step in Observer # Observer stores graphic orders and performs statistics # the following information will be displayed in the "Legend" window The "Trajectories" window shows agents' movements # Evolife will start with this window open - sizes are in pixels # Obs.recordInfo('DefaultViews',	[('Trajectories', 300, 240)])	# just dimensions # Obs.recordInfo('DefaultViews',	[('Trajectories', 400, 200, 300, 240)])	# position and dimensions # Additional coordinates are margins # population of agents #--------------------------------------------------------------------------# # Start: launching Evolife window system                                   # #--------------------------------------------------------------------------# # this call-back function is called each year # means "photo" + "trajectory window"