Beispiel #1
0
class GroundBody(Body):
    """
    classdocs
    """

    def __init__(self, parent=None):
        """

        :param parent:
        :return:
        """
        super(GroundBody, self).__init__(name="ground", parent=parent)

        #   type of body
        self.body_type = "ground"

        #   body id
        self.body_id = -1

        #   name
        self._name = "Ground"

        #   visualization properties
        self.color = np.array([0.8, 0.8, 0.8])

        #   grid object
        self.grid = Grid(parent=self)

    def set_vtk_data(self):
        """
        Create grid to display
        :return:
        """
        self.grid.set_vtk_data()
def dict_to_grid(grid_as_dict) -> Grid:
    grid = Grid(branches_number=8,
                radius=250,
                invisible_branches=320,
                inv_nodes_per_branch=71)
    grid.branches = [_dict_to_branch(br) for br in grid_as_dict['branches']]
    grid.recalculate_invisibles()
    return grid
Beispiel #3
0
 def __init__(self):
     self.__stage = WindowStage.EDIT_OBSTACLES
     self.__width = CANVAS_WIDTH
     self.__height = CANVAS_HEIGHT
     self.__grid = Grid(GRID_WIDTH, GRID_HEIGHT)
     self.__root = tk.Tk()
     self.__canvas = tk.Canvas(self.__root,
                               width=self.__width,
                               height=self.__height,
                               bg='white')
     self.__canvas.pack(padx=ELEMENTS_PADDING, pady=ELEMENTS_PADDING)
     self.__canvas.bind('<Button-1>', self.__on_canvas_click)
     self.__algorithm = tk.StringVar()
     self.__algorithm.set('DFS')
     tk.Button(self.__root,
               text='obstacle',
               bg='black',
               fg='white',
               command=lambda _=None: self.__set_stage(
                   WindowStage.EDIT_OBSTACLES)).pack(
                       padx=ELEMENTS_PADDING,
                       pady=(ELEMENTS_PADDING // 2),
                       side=tk.LEFT)
     tk.Button(self.__root,
               text='start',
               bg='cyan',
               command=lambda _=None: self.__set_stage(
                   WindowStage.EDIT_START)).pack(padx=ELEMENTS_PADDING,
                                                 pady=(ELEMENTS_PADDING //
                                                       2),
                                                 side=tk.LEFT)
     tk.Button(self.__root,
               text='destination',
               bg='blue',
               fg='white',
               command=lambda _=None: self.__set_stage(
                   WindowStage.EDIT_DESTINATION)).pack(
                       padx=ELEMENTS_PADDING,
                       pady=(ELEMENTS_PADDING // 2),
                       side=tk.LEFT)
     tk.Button(self.__root,
               text='solve',
               bg='green',
               fg='white',
               command=lambda _=None: self.__solve()).pack(
                   padx=ELEMENTS_PADDING,
                   pady=(ELEMENTS_PADDING // 2),
                   side=tk.LEFT)
     tk.OptionMenu(self.__root, self.__algorithm, 'DFS', 'BFS',
                   'A*').pack(padx=ELEMENTS_PADDING,
                              pady=(ELEMENTS_PADDING // 2),
                              side=tk.LEFT)
     self.__solvers = {
         'DFS': dfs.DfsSearch,
         'BFS': bfs.BfsSearch,
         'A*': astar.AStar
     }
Beispiel #4
0
    def __init__(self):
        """Read config file and initialise default parameters."""
        # Open grid config file
        file = open("./gridConfig.json")
        # Read grid config from file
        gridConfig = json.load(file)
        # Close file
        file.close()

        # Initialise base path to logging directory
        self.baseLogDir = gridConfig["baseLogDir"]

        # Initialise path to log current events
        self.currentLogDir = None

        # Initilaise number of days
        self.noOfDays = gridConfig["noOfDays"]

        # Initialise grid size
        self.gridSize = gridConfig["gridSize"]

        # Initialise grid with grid size
        self.grid = Grid(self.gridSize)

        # Initialise a lock for grid
        self.gridLock = threading.Semaphore()

        # Initialise food limit
        self.foodLimit = gridConfig["foodLimit"]

        # Initialise array to hold players
        self.players = []

        # Initialise array to hold threads
        self.threads = []

        # Iterate till player limit is reached
        for i in range(gridConfig["noOfPlayers"]):
            # Call function to create players
            self.initialisePlayer()
Beispiel #5
0
    def __init__(self, parent=None):
        """

        :param parent:
        :return:
        """
        super(GroundBody, self).__init__(name="ground", parent=parent)

        #   type of body
        self.body_type = "ground"

        #   body id
        self.body_id = -1

        #   name
        self._name = "Ground"

        #   visualization properties
        self.color = np.array([0.8, 0.8, 0.8])

        #   grid object
        self.grid = Grid(parent=self)
Beispiel #6
0
class UserInput:
    def __init__(self):
        self.wanted_x = -1
        self.wanted_y = -1
        self.turns = -1
        self.grid = Grid()

    def set_size(self, size):
        if check_if_size_is_correct(size):
            size_list = size.split(', ')
            self.grid.x = int(size_list[0])
            self.grid.y = int(size_list[1])
        else:
            raise ValueError("Invalid input! Size must be like 'x, y'.")

    def set_grid(self):
        for row in range(0, self.grid.x):
            new_row = input('Enter row #{}: '.format(row))
            if check_if_row_size_is_correct(
                    new_row, self.grid.y
            ) and check_if_row_contains_only_valid_chars(new_row):
                self.grid.add_row(new_row)
            else:
                raise ValueError(
                    "Invalid row it should only contain '1' and '0' and must be with length {}"
                    .format(self.grid.y))

    def set_wanted(self, wanted):
        if check_if_wanted_values_are_valid(wanted) and \
                check_if_wanted_values_are_in_the_bounds(wanted, self.grid.x, self.grid.y):
            wanted_list = wanted.split(', ')
            self.wanted_x = int(wanted_list[0])
            self.wanted_y = int(wanted_list[1])
            self.turns = int(wanted_list[2])
        else:
            raise ValueError(
                "Invalid expected input it should be like: 'x, y, turns'.")

    def get_input(self):
        size = input("Enter the size of the grid in format: 'x, y'. ")
        self.set_size(size)
        self.set_grid()
        wanted = input(
            "Enter the coordinates of the cell and the round in format: 'x, y, round'. "
        )
        self.set_wanted(wanted)

    def get_output(self):
        times = 0
        self.grid.create_next_generation()
        for generation in range(0, self.turns):
            if self.grid.grid[self.wanted_x][self.wanted_y] == '1':
                times += 1
            self.grid.create_next_generation()
        print('The cell with coordinates ({}, {}) was green {} times'.format(
            self.wanted_x, self.wanted_y, times))
Beispiel #7
0
    def __init__(self):
        ShowBase.__init__(self)

        self.editormode = True

        base.win.setClearColor((0, 0, 0, 1))
        base.win.setClearColorActive(True)
        lang = "ita"
        '''
        #ortho camera lens
        lens = OrthographicLens()
        lens.setFilmSize(12, 9)  #TODO: quattro terzi, fixare, spostare tutto nella classe telecamera e adattare in base allo schermo utente
        base.cam.node().setLens(lens)
        base.cam.setY(-5)
        base.cam.setP(-355)
        '''

        #enabling shader system (and ppl)
        render.setShaderAuto()
        #base.oobe()

        #defining global variables
        # TAKE CARE: these must be objects created form classes which
        # structure has been built with globalness in mind!!
        #
        # for completeness: add minus 'p' before class name for naming variables
        __builtin__.main = self
        __builtin__.pGrid = Grid()
        __builtin__.extract = ExtractTitle()
        __builtin__.baloons = BaloonManager()
        #__builtin__.configManager = ConfigManager()
        __builtin__.audioManager = AudioManager()

        __builtin__.editorCamera = EditorCamera()
        __builtin__.customCamera = __builtin__.editorCamera
        #careful, refactor? here for compatibility between game engine and editor engine

        __builtin__.script = Script()
        __builtin__.persistence = Persistence()

        self.prepareEditor()

        self.accept("editor_loadmap", self.loadMap)
Beispiel #8
0
    def __init__(self):
        ShowBase.__init__(self)

        self.editormode = True

        base.win.setClearColor((0, 0, 0, 1))
        base.win.setClearColorActive(True)
        lang = "ita"
        '''
        #ortho camera lens
        lens = OrthographicLens()
        lens.setFilmSize(12, 9)  #TODO: quattro terzi, fixare, spostare tutto nella classe telecamera e adattare in base allo schermo utente
        base.cam.node().setLens(lens)
        base.cam.setY(-5)
        base.cam.setP(-355)
        '''

        __builtins__.resourceManager = ResourceManager()
        __builtins__.configManager = ConfigManager(resourceManager)

        __builtins__.pGrid = Grid()
        __builtins__.extract = ExtractTitle()
        __builtins__.baloons = BaloonManager()
        #__builtins__.configManager = ConfigManager()
        __builtins__.audioManager = AudioManager()

        __builtins__.editorCamera = EditorCamera()
        __builtins__.customCamera = editorCamera  #TODO: why?!
        #careful, refactor? here for compatibility between game engine and editor engine

        __builtins__.script = Script()
        __builtins__.persistence = Persistence()

        __builtins__.main = self

        #enabling shader system (and ppl)
        render.setShaderAuto()
        #base.oobe()

        self.prepareEditor()

        self.accept("editor_loadmap", self.loadMap)
Beispiel #9
0
actor = Actor()

os.popen("VampiresVSWerewolvesGameServer.exe")

name = 'paul'

conn = Connector("127.0.0.1", 5555)

# envoit sequence NME
conn.send("NME".encode() + struct.pack("1B", len(name)) + name.encode())

# recoit commande SET
Set = conn.receive()
# initialise la carte
grid = Grid(Set[1][0], Set[1][1])

# recoit HME --inutile mais il faut quand même le recevoir
conn.receive()
# recoit HME --inutile mais il faut quand même le recevoir
conn.receive()

#
Map = conn.receive()
grid.update_all_groups(Map[1])

# tant que la partie est active
while conn.connected:

    # ecoute le serveur
    order = conn.receive()
Beispiel #10
0
import pytest
from grid.grid import Grid

new_grid = Grid()

test_board = [[7, 8, 0, 4, 0, 0, 1, 2, 0], [6, 0, 0, 0, 7, 5, 0, 0, 9],
              [0, 0, 0, 6, 0, 1, 0, 7, 8], [0, 0, 7, 0, 4, 0, 2, 6, 0],
              [0, 0, 1, 0, 5, 0, 9, 3, 0], [9, 0, 4, 0, 6, 0, 0, 0, 5],
              [0, 7, 0, 3, 0, 0, 0, 1, 2], [1, 2, 0, 0, 0, 7, 4, 0, 0],
              [0, 4, 9, 2, 0, 6, 0, 0, 7]]


def test_set_board():
    new_grid.set_board(new_grid.empty_board)
    assert new_grid.board == new_grid.empty_board


def test_print(capsys):
    new_grid.set_board(test_board)
    new_grid.print()
    captured = capsys.readouterr()
    assert captured.out == test_board


# def test_new_func():
#     assert 4 == 5
Beispiel #11
0
 def __init__(self):
     self.wanted_x = -1
     self.wanted_y = -1
     self.turns = -1
     self.grid = Grid()
def run(boxes,options):
	#set the renderer
	if 'box' in options:
		_renderer = BoxRenderer()
	elif 'text' in options:
		_renderer = TextRenderer()


	#total area of all the boxes
	area = reduce(lambda i,j:i+j,map(lambda i:i[0]*i[1],boxes))

	#get the max width of the boxes 
	#make the the first height to test of the rectangle
	#this is becuase of the presorting in descending order
	width = boxes[0][0]

	#get the max length
	#used to show when to stop making rectangles to check
	max_length = max(map(lambda i:i[1],boxes))

	#find the height that 
	#is greater than or equal to the area of the boxes total area
	height = 0
	a = 0
	while height == 0:
		a=a+1
		if a*width >= area:
			height = a

	#some info for the user
	if 'verbose' in options:
		print "using boxes:"
		print boxes

		print "total area:"
		print area

		print "start with minimal width rectangle:"
		print (width,height)
	
	#initialize results
	#use maxint
	result = {'area':9999999999999,'dimensions':(0,0),'grid':None}

	
	
	initial_width = width
	initial_height = height
	
	#main search loop
	while height >= max_length:
		
		#check to see if this rectangle is worth testing
		#it doesn't make sense to test a recntangle that is already larger
		#than our best.
		if (height*width)<=result['area']:
			
			if 'verbose' in options:
				print "testing:"
				print (width,height)
			
			#initiallize grid and run the main loop
			#if the boxes can't fit in the rectangle 
			#increase the height until the boxes fit
			g = Grid(height,width)
			if 'recursive' in options:
				while g.placeRecursively(boxes,0) != True:
					g = Grid(width,g.l+1)
			elif 'greedy' in options:				
				while g.placeGreedily(boxes) != True:
					g = Grid(width,g.l+1)
				
			#set the renderer and display info for the user	
			g.setRenderer(_renderer)
			
			if 'verbose' in options:
				print "found the following:"
				g.display()
				print "containing rectangle:"
				print (g.l,g.w)
				print "area of rectangle:"
				print g.l*g.w
			if result['area'] > g.l*g.w:
				result['area'] = g.l*g.w
				result['dimensions'] = (g.l,g.w)
				result['grid'] = g
		
		#increase the width
		#minimize height which is also
		#greater than the area of the boxes	

		#this needs work
		width=width+1
		a=0
		while width*a < area:
			a=a+1
		height=a
		if height==1:
			height=0
		
	result['grid'].display()
	print result['area']
from grid import ipfsapi
import base64
import random
import keras
import json
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD
import numpy as np
from grid.grid import Grid

grid = Grid()
print("grid id: {}".format(grid.id))
grid.work()
Beispiel #14
0
    def __init__(self):
        ShowBase.__init__(self)

        self.editormode = False

        base.win.setClearColor((0, 0, 0, 1))
        base.win.setClearColorActive(True)
        lang = "ita"
        '''
        #ortho camera lens
        lens = OrthographicLens()
        lens.setFilmSize(12, 9)  #TODO: quattro terzi, fixare, spostare tutto nella classe telecamera e adattare in base allo schermo utente
        base.cam.node().setLens(lens)
        base.cam.setY(-5)
        base.cam.setP(-355)
        '''

        #enabling shader system (and ppl)
        render.setShaderAuto()
        #base.oobe()

        #filters -- experimental
        filters = CommonFilters(base.win, base.cam)

        #defining global variables
        # TAKE CARE: these must be objects created form classes which
        # structure has been built with globalness in mind!!
        #
        # for completeness: add minus 'p' before class name for naming variables
        __builtins__.main = self
        __builtins__.pGrid = Grid()
        __builtins__.extract = ExtractTitle()
        __builtins__.baloons = BaloonManager()
        #__builtins__.configManager = ConfigManager()
        __builtins__.audioManager = AudioManager()
        __builtins__.fadingtext = FadingTextManager()
        __builtins__.customCamera = CustomCamera()
        __builtins__.script = Script()
        __builtins__.persistence = Persistence()
        __builtins__.fademanager = FadeOut()
        __builtins__.flow = Flow()
        __builtins__.myfilters = filters

        # ===========================================
        #load the config class
        #configmanager.loadConfig()
        #lang = configmanager.getData("LANGUAGE").lower()
        # ===========================================

        __builtins__.mainMenu = MainMenu(lang)

        lang = configManager.getData("LANGUAGE").lower()

        #extract.extractTxt("ita")
        extract.extractTxt(lang)
        #DEBUG for the getResource
        #print(resourceManager.getResource("misc/grass.png"))

        configManager.saveConfig("LANGUAGE", "ITA")
        lang = configManager.getData("LANGUAGE").lower()
        extract.extractTxt(lang)
        """
        r = ResourceManager()
        print(r.getResource('misc/grass') # deve dire path assoluto = res/misc/grass.png)
        """

        #self.entrypoint = ['camera.map', '3,3']
        #self.entrypoint = ['finedemo.map', '1,1']
        #self.entrypoint = ['parcogiochi.map', '9,12']
        #self.entrypoint = ['incidente.map', '20,11']
        #self.entrypoint = ['macchinadasola.map', '2,2']
        #self.entrypoint = ['black.map', '5,5']

        #cinematica
        self.entrypoint = ['tetto.map', '4,2']

        #inizio vero
        #self.entrypoint = ['classe.map', '5,2', 'up']
        mainMenu.show()

        #UNCOMMENT TO ENABLE INTRO
        i = Intro()
        i.start()
def _get_palette():
    default_grid = Grid(branches_number=8, radius=250, invisible_branches=320, inv_nodes_per_branch=71)
    return Palette(default_grid)
Beispiel #16
0
class MainWindow:
    def __init__(self):
        self.__stage = WindowStage.EDIT_OBSTACLES
        self.__width = CANVAS_WIDTH
        self.__height = CANVAS_HEIGHT
        self.__grid = Grid(GRID_WIDTH, GRID_HEIGHT)
        self.__root = tk.Tk()
        self.__canvas = tk.Canvas(self.__root,
                                  width=self.__width,
                                  height=self.__height,
                                  bg='white')
        self.__canvas.pack(padx=ELEMENTS_PADDING, pady=ELEMENTS_PADDING)
        self.__canvas.bind('<Button-1>', self.__on_canvas_click)
        self.__algorithm = tk.StringVar()
        self.__algorithm.set('DFS')
        tk.Button(self.__root,
                  text='obstacle',
                  bg='black',
                  fg='white',
                  command=lambda _=None: self.__set_stage(
                      WindowStage.EDIT_OBSTACLES)).pack(
                          padx=ELEMENTS_PADDING,
                          pady=(ELEMENTS_PADDING // 2),
                          side=tk.LEFT)
        tk.Button(self.__root,
                  text='start',
                  bg='cyan',
                  command=lambda _=None: self.__set_stage(
                      WindowStage.EDIT_START)).pack(padx=ELEMENTS_PADDING,
                                                    pady=(ELEMENTS_PADDING //
                                                          2),
                                                    side=tk.LEFT)
        tk.Button(self.__root,
                  text='destination',
                  bg='blue',
                  fg='white',
                  command=lambda _=None: self.__set_stage(
                      WindowStage.EDIT_DESTINATION)).pack(
                          padx=ELEMENTS_PADDING,
                          pady=(ELEMENTS_PADDING // 2),
                          side=tk.LEFT)
        tk.Button(self.__root,
                  text='solve',
                  bg='green',
                  fg='white',
                  command=lambda _=None: self.__solve()).pack(
                      padx=ELEMENTS_PADDING,
                      pady=(ELEMENTS_PADDING // 2),
                      side=tk.LEFT)
        tk.OptionMenu(self.__root, self.__algorithm, 'DFS', 'BFS',
                      'A*').pack(padx=ELEMENTS_PADDING,
                                 pady=(ELEMENTS_PADDING // 2),
                                 side=tk.LEFT)
        self.__solvers = {
            'DFS': dfs.DfsSearch,
            'BFS': bfs.BfsSearch,
            'A*': astar.AStar
        }

    def main_loop(self):
        self.__grid.draw(self.__canvas)
        self.__root.mainloop()

    def __solve(self):
        if self.__grid.start_cell and self.__grid.dest_cell:
            prev_stage = self.__stage
            self.__stage = WindowStage.FINDING_PATH
            self.__grid.reset_colors()
            self.__grid.draw(self.__canvas)
            solve_way = self.__algorithm.get()
            if solve_way in self.__solvers:
                self.__solvers[solve_way](self.__grid).solve(
                    self.__canvas)  # word 'solve' occurred three times!
            else:
                raise NotImplementedError('WIP')
            self.__stage = prev_stage

    def __set_stage(self, stage):
        if self.__stage != WindowStage.FINDING_PATH:
            self.__stage = stage

    def __on_canvas_click(self, event):
        if self.__stage == WindowStage.FINDING_PATH:
            return
        self.__grid.reset_colors()
        cell_clicked = self.__grid.get_cell_by_coord(self.__width,
                                                     self.__height, event.x,
                                                     event.y)
        if self.__stage == WindowStage.EDIT_OBSTACLES:
            if self.__grid.is_obstacle(cell_clicked):
                self.__grid.unset_obstacle(cell_clicked)
            elif self.__grid.is_free(cell_clicked):
                self.__grid.set_obstacle(cell_clicked)
        elif self.__stage == WindowStage.EDIT_START and self.__grid.is_free(
                cell_clicked):
            self.__grid.start_cell = cell_clicked
        elif self.__stage == WindowStage.EDIT_DESTINATION and self.__grid.is_free(
                cell_clicked):
            self.__grid.dest_cell = cell_clicked
        self.__grid.draw(self.__canvas)
Beispiel #17
0
    10,  #R needed to reach half of maximum consumption rate (res)
    0.4,  #population generated by max consumption (pop)
    0.02,  #pop natural death rate (year^-1)
    10,  #foundingp pop
    100,
)  # carrying capacity (pop)

R = Res(
    0.2,  #resource natural growth
    60)  #resource carrying capacity

sim = Grid(
    Nstart,
    start,
    N,
    R,
    Europe,
    0.01,  #alpha -- production taxation (%.year^-1)
    10,  #range
    dt)

fig, ax = plt.subplots()
plt.axis('off')

im = plt.imshow(sim.get_img())
ax.set_title(f'Year: 0')


def animate(i):
    for _ in range(scale):
        sim.update()
Beispiel #18
0
def execute(name, algorithm, ip, port):
    print(ip, port)
    """

    :param name: name of the ai
    :param algorithm: 1 for greedy, 2 for alpha-beta
    :return:
    """
    actor = Actor(algorithm)
    conn = Connector(ip, port)

    # envoie sequence NME
    conn.send("NME".encode()+struct.pack("1B",len(name))+name.encode())

    # recoit commande SET
    Set = conn.receive()
    # initialise la carte
    grid = Grid(Set[1][0],Set[1][1])

    # recoit HUM —inutile mais il faut quand même le recevoir
    conn.receive()
    # recoit HME — utile pour identifier son espèce
    hme = conn.receive()

    #
    Map = conn.receive()
    grid.initiate_all_groups(Map[1],hme[1])

    turn = 0
    # tant que la partie est active
    while conn.connected:

        # écoute le serveur
        logging.info('starting turn {}'.format(turn))
        order = conn.receive()
        start_time = time.time()

        if order[0] == "UPD":
            #update la grille
            grid.update_map(order[1])
        elif order[0] == "BYE":
            # TODO clean break
            logging.error("server unexpectedly close connexion")
            break
        elif order[0] == "END":
            logging.info("finishing game")
            # TODO clean break
            break

        # prend la decision
        actor.action(grid, turn)

        # envoie file d'actions au serveur
        conn.send(actor.send_moves())

        logging.info('finishing turn {} \n elapsed time : {}s'.format(turn, time.time()-start_time))

        # vide la file d'action pour prochain tour
        actor.clean_moves()


        # attend une seconde pour visualiser sur .exe


        #time.sleep(0.5)

        turn += 1
Beispiel #19
0
#  Copyright (c) 2019 Aliaksandr Tsukanau.
#  Licensed under GNU General Public Licence, version 3.
#  You may not use this file except in compliance with GNU General Public License, version 3.
#  See the GNU General Public License, version 3 for more details. https://www.gnu.org/licenses/gpl-3.0.en.html
#
#

from db.grid_driver import GridMongoClient
from grid.grid import Grid

driver = GridMongoClient()
grid = Grid(branches_number=8,
            radius=250,
            invisible_branches=320,
            inv_nodes_per_branch=71)

driver.save_grid(grid, 'testing_my_grid')

saved_grid = driver.get_grid_obj('testing_my_grid')
Beispiel #20
0
class Ecosystem:
    # Initialise constructor
    def __init__(self):
        """Read config file and initialise default parameters."""
        # Open grid config file
        file = open("./gridConfig.json")
        # Read grid config from file
        gridConfig = json.load(file)
        # Close file
        file.close()

        # Initialise base path to logging directory
        self.baseLogDir = gridConfig["baseLogDir"]

        # Initialise path to log current events
        self.currentLogDir = None

        # Initilaise number of days
        self.noOfDays = gridConfig["noOfDays"]

        # Initialise grid size
        self.gridSize = gridConfig["gridSize"]

        # Initialise grid with grid size
        self.grid = Grid(self.gridSize)

        # Initialise a lock for grid
        self.gridLock = threading.Semaphore()

        # Initialise food limit
        self.foodLimit = gridConfig["foodLimit"]

        # Initialise array to hold players
        self.players = []

        # Initialise array to hold threads
        self.threads = []

        # Iterate till player limit is reached
        for i in range(gridConfig["noOfPlayers"]):
            # Call function to create players
            self.initialisePlayer()

    # Function to create players and place them on grid
    def initialisePlayer(self):
        """Create a new player object and place in along a grid edge."""
        # Initialise player
        player = Player()
        # Choose random coordinates
        coordinate = (random.randint(0, self.gridSize - 1),
                      random.randint(0, 1) * (self.gridSize - 1))
        # Toss to check if coordinates should be reversed
        if random.randint(1, 2) == 1:
            # Reverse coordinates
            coordinate = coordinate[::-1]
        # Update location for player
        player.updateLocation(coordinate)
        # Add player to players array
        self.players.append(player)
        # Acquire lock
        self.gridLock.acquire()
        # Add player to coordinate
        self.grid.grid[coordinate[0]][coordinate[1]].addPlayer(player)
        # Release lock
        self.gridLock.release()
        # Return player
        return player

    # Function to get player target
    def getTargetLocation(self, currentLocation, target, visionLimit):
        """Get snapshot of grid and call search function to locate target.

        Keyword arguments:
        currentLocation -- tuple
        target -- string in 'food' or 'home'
        visionLimit -- integer
        """
        # Initialise target
        targetLocation = None
        # Check if target is among valid targets
        if target in ["food", "home"]:
            # Acquire lock
            self.gridLock.acquire()
            # Get snapshot of grid
            snapshot = self.grid.getSnapshot(target)
            # Release lock
            self.gridLock.release()
            # Check if target is food
            if target == "food":
                # Initialise search
                search = Search(snapshot, currentLocation, "F", visionLimit)
            elif target == "home":
                # Initialise search
                search = Search(snapshot, currentLocation, "H", visionLimit)
            # Get target location
            targetLocation = search.locateTarget()
        # TODO: throw error (invalid target)
        # else:
        return targetLocation

    # Function to print snapshot of grid
    def displayGrid(self, target="all"):
        """Get snapshot of grid and print it element wise.

        Keyword arguments:
        target -- string in 'all', 'food' or 'home'
        """
        # Check if target is among valid targets
        if target in ["all", "food", "home"]:
            # Acquire lock
            self.gridLock.acquire()
            # Get snapshot of grid
            snapshot = self.grid.getSnapshot(target)
            # Release lock
            self.gridLock.release()
            # Print a divider
            print("---###---")
            # Iterate over each row
            for i in range(self.gridSize):
                # Iterate over each column
                for j in range(self.gridSize):
                    # Print cell
                    print(snapshot[i][j], end="\t")
                # Enter new line for each row
                print()
        # TODO: throw error (invalid target)
        # else:

    # Function to write snapshot of grid to log file
    def logGrid(self):
        """Get snapshot of grid and write it to log file."""
        # Acquire lock
        self.gridLock.acquire()
        # Get snapshot of grid
        snapshot = self.grid.getSnapshot("all")
        # Release lock
        self.gridLock.release()
        # Iterate over each row
        for i in range(self.gridSize):
            # Iterate over each column
            for j in range(self.gridSize):
                # Print cell
                writeLogs(self.currentLogDir, "grid",
                          str(snapshot[i][j]) + ",")
            # Enter new line for each row
            writeLogs(self.currentLogDir, "grid", "\n")

    # Function to calculate player's next move
    def calculateNextMove(self, currentLocation, hungerStatus, safetyStatus,
                          visionLimit):
        """Calculate player's target and its current location. Return step to move towards target.

        Keyword arguments:
        currentLocation -- tuple
        hungerStatus -- boolean
        safetyStatus -- boolean
        visionLimit -- integer
        """
        # Initialise new location
        newLocation = currentLocation
        # Initialise target location
        targetLocation = None
        # Check parameter types
        if type(currentLocation) == type(
            (1, 2)) and type(hungerStatus) == type(True) and type(
                safetyStatus) == type(True):
            # Get player target
            target = getTarget(hungerStatus, safetyStatus)
            # Check if player target is not None
            if not target == None:
                # Get player target location
                targetLocation = self.getTargetLocation(
                    currentLocation, target, visionLimit)
                # Check if target location is None
                if targetLocation == None:
                    # Call function to get randon coordinates
                    targetLocation = getRandomCoordinates(self.gridSize)
                # Get new location
                newLocation = getNextStep(currentLocation, targetLocation)
        # Return new location
        return targetLocation, newLocation

    # Function to move players
    def movePlayer(self, player):
        """Move player towards target.

        Keyword arguments:
        player -- player object
        """
        # Get player id
        playerId = player.getId()
        # Set movement limit
        maxMoves = player.getMovementLimit()
        # Iterate till movement limit is reached
        for move in range(maxMoves):
            # Get player current location
            currentLocation = player.getLocation()
            # Call function to get new location to move to
            targetLocation, newLocation = self.calculateNextMove(
                currentLocation, player.getHungerStatus(),
                player.getSafetyStatus(), player.getVisionLimit())
            # Prepare string to write to log file
            logString = str(player.getHungerStatus())
            logString = logString + "," + str(player.getSafetyStatus())
            logString = logString + "," + str(currentLocation[0]) + "," + str(
                currentLocation[1])
            logString = logString + "," + str(targetLocation[0]) + "," + str(
                targetLocation[1])
            logString = logString + "," + str(newLocation[0]) + "," + str(
                newLocation[1]) + "\n"
            # Write player state to file
            writeLogs(self.currentLogDir, playerId, logString)
            # Check if new location matches current location
            if not newLocation == currentLocation:
                # Acquire lock
                self.gridLock.acquire()
                # Move player
                self.grid.movePlayer(playerId, currentLocation, newLocation)
                # Update player safety status
                player.updateSafetyStatus(
                    self.grid.grid[newLocation[0]][newLocation[1]].isSafe())
                # Check if player has reached target
                if newLocation == targetLocation:
                    # Check if player is hungry and cell has food
                    if player.getHungerStatus() and self.grid.grid[
                            newLocation[0]][newLocation[1]].foodExists():
                        # Remove food from cell
                        self.grid.grid[newLocation[0]][
                            newLocation[1]].modifyFoodCount("decrement")
                        # Update player's hunger status
                        player.updateHungerStatus(False)
                # Release lock
                self.gridLock.release()
            # Check if hunger is False and safety is True
            if not player.getHungerStatus() and player.getSafetyStatus():
                # Break from loop
                break
            # Wait till recharge duration ends
            time.sleep(player.getRechargeDuration())

    # Function to assign thread to each player
    def assignThreads(self):
        """Iterate over players and assign a thread to each."""
        # Iterate over each player
        for player in self.players:
            # Create a thread and append to array
            self.threads.append(
                threading.Thread(target=self.movePlayer, args=[player]))

    # Function to perfrom day activities
    def beginDay(self):
        """Call functions to initialise food, assign threads and start threads."""
        # Acquire lock
        self.gridLock.acquire()
        # Initialise food on grid
        self.grid.initialiseFood(self.foodLimit)
        # Release lock
        self.gridLock.release()
        # Log grid state to file
        self.logGrid()
        # Call function to assign threads to players
        self.assignThreads()
        # Iterate over all threads
        for thread in self.threads:
            # Start thread
            thread.start()
        # Sleep tillall threads complete execution
        while threading.active_count() > 1:
            time.sleep(1)

    # Function to perform night activities
    def beginNight(self):
        """Call function to reset food on grid and remove players who do not meet end conditions."""
        # Acquire lock
        self.gridLock.acquire()
        # Call function to reset food on grid
        self.grid.resetFood()
        # Release lock
        self.gridLock.release()
        # Iterate over all players
        for player in self.players:
            # Call function to update player parameters
            player.updateParameters()
            # Initialise string with player movemment limit, vision limit and recharge duration
            logString = str(player.getId())
            logString = logString + "," + str(player.getMovementLimit())
            logString = logString + "," + str(player.getVisionLimit())
            logString = logString + "," + str(
                player.getRechargeDuration()) + "\n"
            # Write log to file
            writeLogs(self.currentLogDir, "playerConfig", logString)
            # Check if player is hungry or is in unsafe cell
            if player.getHungerStatus() or not player.getSafetyStatus():
                # Get player location
                location = player.getLocation()
                # Acquire lock
                self.gridLock.acquire()
                # Remove player from grid
                self.grid.grid[location[0]][location[1]].removePlayer(
                    player.getId())
                # Release lock
                self.gridLock.release()
        # Remove hungry players
        self.players = [
            player for player in self.players if not player.getHungerStatus()
        ]
        # Remove players in unsafe cells
        self.players = [
            player for player in self.players if player.getSafetyStatus()
        ]
        # Reset threads
        self.threads = []
        # Iterate over all players
        for player in self.players:
            # Check if player should reproduce
            if random.uniform(0, 1) < player.getReproductionChance():
                # Reset player reproduction chance
                player.updateReproductionChance("reset")
                # Get player config
                config = player.getConfig()
                # Create a new player object
                newPlayer = self.initialisePlayer()
                # Update new player config
                newPlayer.updateConfig(config)
            else:
                # Increment reproduction chances
                player.updateReproductionChance("increment")
            # Set player hunger status to True
            player.updateHungerStatus(True)

    # Function to start simulation
    def startSimulation(self):
        """Initialise log directory and call functions to start and complete cycle."""
        # Iterate over number of days
        for i in range(self.noOfDays):
            # Set current log dir
            self.currentLogDir = os.path.join(self.baseLogDir, "day" + str(i))
            # Create a directory for logging
            os.makedirs(self.currentLogDir)
            # Acquire lock
            self.gridLock.acquire()
            # Update log directory path in grid
            self.grid.updateLogDirectoryLocation(self.currentLogDir)
            # Release lock
            self.gridLock.release()
            # Call function to begin day
            self.beginDay()
            # Call function to begin night
            self.beginNight()
            # If player array is empty, exit loop
            if not len(self.players) > 0:
                # Exit loop
                break