particle.py 55.2 KB
Newer Older
Ahmad Reza's avatar
Ahmad Reza committed
1
2
3
4
5
6
7
8
9
10
11
"""
.. module:: particle
   :platform: Unix, Windows
   :synopsis: This module provides the interfaces of the robotics particle

.. moduleauthor:: Ahmad Reza Cheraghi

TODO: Erase Memory

"""

Karol Actun's avatar
Karol Actun committed
12
import logging
Ahmad Reza's avatar
Ahmad Reza committed
13
from lib import csv_generator, matter
14
from lib.swarm_sim_header import *
Ahmad Reza's avatar
Ahmad Reza committed
15

Ahmad Reza's avatar
Ahmad Reza committed
16

Ahmad Reza's avatar
Ahmad Reza committed
17
class Particle(matter.Matter):
18
    """In the classe marker all the methods for the characterstic of a marker is included"""
Karol Actun's avatar
Karol Actun committed
19
    def __init__(self, world, coordinates, color=black, transparency=1, particle_counter=0):
20
        """Initializing the marker constructor"""
Karol Actun's avatar
Karol Actun committed
21
        super().__init__( world, coordinates, color, transparency,
22
23
                          type="particle", mm_size=world.config_data.particle_mm_size)
        self.number = particle_counter
Ahmad Reza's avatar
Ahmad Reza committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
        self.__isCarried = False
        self.carried_tile = None
        self.carried_particle = None
        self.steps = 0
        self.csv_particle_writer = csv_generator.CsvParticleData( self.get_id(), self.number)

    def has_tile(self):
        if self.carried_tile == None:
            return False
        else:
            return True

    def has_particle(self):
        if self.carried_particle == None:
38
            return False 
Ahmad Reza's avatar
Ahmad Reza committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
        else:
            return True

    def get_carried_status(self):
        """
        Get the status if it is taken or not

        :return: Tiles status
        """
        return self.__isCarried

    def check_on_tile(self):
        """
        Checks if the particle is on a tile

        :return: True: On a tile; False: Not on a Tile
        """
56
        if self.coordinates in self.world.tile_map_coordinates:
Ahmad Reza's avatar
Ahmad Reza committed
57
58
59
60
61
62
63
64
65
66
            return True
        else:
            return False

    def check_on_particle(self):
        """
        Checks if the particle is on a particle

        :return: True: On a particle; False: Not on a particle
        """
67
        if self.coordinates in self.world.particle_map_coordinates:
Ahmad Reza's avatar
Ahmad Reza committed
68
69
70
71
            return True
        else:
            return False

72
    def check_on_marker(self):
Ahmad Reza's avatar
Ahmad Reza committed
73
        """
74
        Checks if the particle is on a marker
Ahmad Reza's avatar
Ahmad Reza committed
75

76
        :return: True: On a marker; False: Not on a marker
Ahmad Reza's avatar
Ahmad Reza committed
77
        """
78
        if self.coordinates in self.world.marker_map_coordinates:
Ahmad Reza's avatar
Ahmad Reza committed
79
80
81
82
            return True
        else:
            return False

83
    def move_to(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
84
        """
Karol Actun's avatar
Karol Actun committed
85
        Moves the particle to the given direction
Ahmad Reza's avatar
Ahmad Reza committed
86

Karol Actun's avatar
Karol Actun committed
87
        :param direction: The direction is defined by loaded grid class
Ahmad Reza's avatar
Ahmad Reza committed
88
89
        :return: True: Success Moving;  False: Non moving
        """
90
        direction_coord = get_coordinates_in_direction(self.coordinates, direction)
91
        direction, direction_coord = self.check_within_border(direction, direction_coord)
Karol Actun's avatar
Karol Actun committed
92
        if self.world.grid.is_valid_location(direction_coord):
93
            if not direction_coord in self.world.particle_map_coordinates:
Karol Actun's avatar
Karol Actun committed
94
                del self.world.particle_map_coordinates[self.coordinates]
95
96
                self.coordinates = direction_coord
                self.world.particle_map_coordinates[self.coordinates] = self
97
                logging.info("particle %s successfully moved to %s", str(self.get_id()), direction)
Ahmad Reza's avatar
Ahmad Reza committed
98
                self.world.csv_round.update_metrics( steps=1)
Ahmad Reza's avatar
Ahmad Reza committed
99
100
                self.csv_particle_writer.write_particle(steps=1)
                self.touch()
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
101
                self.check_for_carried_tile_or_particle()
Ahmad Reza's avatar
Ahmad Reza committed
102
                return True
Karol Actun's avatar
Karol Actun committed
103

104
        return False
Ahmad Reza's avatar
Ahmad Reza committed
105

Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
106
107
    def check_for_carried_tile_or_particle(self):
        if self.carried_tile is not None:
108
            self.carried_tile.coordinates = self.coordinates
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
109
110
            self.carried_tile.touch()
        elif self.carried_particle is not None:
111
            self.carried_particle.coordinates = self.coordinates
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
112
113
            self.carried_particle.touch()

114
    def check_within_border(self, direction, direction_coord):
Ahmad Reza's avatar
Ahmad Reza committed
115
        if self.world.config_data.border == 1 and \
116
117
                (abs(direction_coord[0]) > self.world.get_sim_x_size() or abs(direction_coord[1]) > self.world.get_sim_y_size()):
            direction = direction - 3 if direction > 2 else direction + 3
118
            direction_coord = get_coordinates_in_direction(self.coordinates, direction)
119
        return direction, direction_coord
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
120

121
    def move_to_in_bounds(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
122
        """
123
            Moves the particle to the given directionection if it would remain in bounds.
Ahmad Reza's avatar
Ahmad Reza committed
124

125
            :param direction: The directionection must be either: E, SE, SW, W, NW, or NE
Ahmad Reza's avatar
Ahmad Reza committed
126
127
            :return: True: Success Moving;  False: Non moving
        """
128
129
        direction_coord = get_coordinates_in_direction(self.coordinates, direction)
        sim_coord = coordinates_to_sim(direction_coord)
Ahmad Reza's avatar
Ahmad Reza committed
130
131
        if self.world.get_sim_x_size() >=  abs(sim_coord[0]) and \
                        self.world.get_sim_y_size() >=  abs(sim_coord[1]):
132
            return self.move_to(direction)
Ahmad Reza's avatar
Ahmad Reza committed
133
134
        else:
            # 'bounce' off the wall
135
136
            n_direction = direction - 3 if direction > 2 else direction + 3
            self.move_to(n_direction)
Ahmad Reza's avatar
Ahmad Reza committed
137
138
139

    def read_from_with(self, matter, key=None):
        """
140
        Read the memories from the matters (paricle, tile, or marker object) memories with a given keyword
Ahmad Reza's avatar
Ahmad Reza committed
141

142
        :param matter: The matter can be either a particle, tile, or marker
Ahmad Reza's avatar
Ahmad Reza committed
143
144
145
146
147
148
149
150
        :param key: A string keyword to searcg for the data in the memory
        :return: The matters memory; None
        """
        if key != None:
            tmp_memory = matter.read_memory_with(key)
        else:
            tmp_memory =  matter.read_whole_memory()

151
152
153
154
155
156
157
158
159
160
161
162
163
        if tmp_memory != None:
            if not(hasattr(tmp_memory, '__len__')) or len(tmp_memory) > 0:
                if matter.type == "particle":
                    self.world.csv_round.update_metrics( particle_read=1)
                    self.csv_particle_writer.write_particle(particle_read=1)
                elif matter.type == "tile":
                    self.world.csv_round.update_metrics( tile_read=1)
                    self.csv_particle_writer.write_particle(tile_read=1)
                elif matter.type == "marker":
                    self.world.csv_round.update_metrics( marker_read=1)
                    self.csv_particle_writer.write_particle(marker_read=1)
                return tmp_memory
        return None
Ahmad Reza's avatar
Ahmad Reza committed
164

165
    def matter_in(self, direction=E):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
166
        """
167
        :param direction: the directionection to check if a matter is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
168
169
        :return: True: if a matter is there, False: if not
        """
170
171
172
        if  get_coordinates_in_direction(self.coordinates, direction) in self.world.get_tile_map_coordinates() \
            or get_coordinates_in_direction(self.coordinates, direction) in self.world.get_particle_map_coordinates() \
            or get_coordinates_in_direction(self.coordinates, direction) in self.world.get_marker_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
173
174
175
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
176

177
    def tile_in(self, direction=E):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
178
        """
179
        :param direction: the directionection to check if a tile is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
180
181
        :return: True: if a tile is there, False: if not
        """
182
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_tile_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
183
184
185
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
186

187
    def particle_in(self, direction=E):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
188
        """
189
        :param direction: the directionection to check if a particle is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
190
191
        :return: True: if a particle is there, False: if not
        """
192
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_particle_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
193
194
195
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
196

197
    def marker_in(self, direction=E):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
198
        """
199
        :param direction: the directionection to check if a marker is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
200
201
        :return: True: if a marker is there, False: if not
        """
202
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_marker_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
203
204
205
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
206

207
    def get_matter_in(self, direction=E):
208
209
210
211
212
213
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_tile_map_coordinates():
            return self.world.get_tile_map_coordinates()[get_coordinates_in_direction(self.coordinates, direction)]
        elif get_coordinates_in_direction(self.coordinates, direction) in self.world.get_particle_map_coordinates():
            return self.world.get_particle_map_coordinates()[get_coordinates_in_direction(self.coordinates, direction)]
        elif get_coordinates_in_direction(self.coordinates, direction) in self.world.get_marker_map_coordinates():
            return self.world.get_marker_map_coordinates()[get_coordinates_in_direction(self.coordinates, direction)]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
214
215
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
216

217
    def get_tile_in(self, direction=E):
218
219
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_tile_map_coordinates():
            return self.world.get_tile_map_coordinates()[get_coordinates_in_direction(self.coordinates, direction)]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
220
221
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
222

223
    def get_particle_in(self, direction=E):
224
225
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_particle_map_coordinates():
            return self.world.get_particle_map_coordinates()[get_coordinates_in_direction(self.coordinates, direction)]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
226
227
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
228

229
    def get_marker_in(self, direction=E):
230
231
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_marker_map_coordinates():
            return self.world.get_marker_map_coordinates()[get_coordinates_in_direction(self.coordinates, direction)]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
232
233
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
234

235
    def get_marker(self):
236
237
        if self.coordinates in self.world.marker_map_coordinates:
            return self.world.get_marker_map_coordinates()[self.coordinates]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
238
239
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
240

Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
241
    def get_tile(self):
242
243
        if self.self.coordinates in self.world.get_tile_map_coordinates():
            return self.world.get_tile_map_coordinates()[self.coordinates]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
244
245
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
246
247
248

    def write_to_with(self, matter, key=None, data=None):
        """
249
        Writes data with given a keyword directionectly on the matters (paricle, tile, or marker object) memory
Ahmad Reza's avatar
Ahmad Reza committed
250

251
        :param matter: The matter can be either a particle, tile, or marker
Ahmad Reza's avatar
Ahmad Reza committed
252
253
254
255
256
257
258
259
260
261
262
263
264
        :param key: A string keyword so to order the data that is written into the memory
        :param data: The data that should be stored into the memory
        :return: True: Successful written into the memory; False: Unsuccessful
        """
        wrote=False
        if data != None:
            wrote=False
            if key==None:
                wrote=matter.write_memory(data)
            else:
                wrote= matter.write_memory_with(key, data)
            if  wrote==True:
                if matter.type == "particle":
Ahmad Reza's avatar
Ahmad Reza committed
265
                    self.world.csv_round.update_metrics( particle_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
266
267
                    self.csv_particle_writer.write_particle(particle_write=1)
                elif matter.type == "tile":
Ahmad Reza's avatar
Ahmad Reza committed
268
                    self.world.csv_round.update_metrics( tile_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
269
                    self.csv_particle_writer.write_particle(tile_write=1)
270
                elif matter.type == "marker":
Ahmad Reza's avatar
Ahmad Reza committed
271
                    self.world.csv_round.update_metrics( marker_write=1)
272
                    self.csv_particle_writer.write_particle(marker_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
273
274
275
276
277
278
                return True
            else:
                return False
        else:
            return False

Ahmad Reza's avatar
Ahmad Reza committed
279
    def scan_for_matters_within(self, matter='all', hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
280
        """
281
        Scans for particles, tiles, or marker on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
282
283
284

        :todo: If nothing then everything should be scanned

285
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
286
287
288
289
        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """

Ahmad Reza's avatar
Ahmad Reza committed
290
        within_hop_list = []
Ahmad Reza's avatar
Ahmad Reza committed
291
        for i in range(1, hop + 1):
Ahmad Reza's avatar
Ahmad Reza committed
292
293
294
295
296
            in_list = self.scan_for_matters_in(matter, i)
            if in_list is not None:
                within_hop_list.extend(in_list)
        if len(within_hop_list) != 0:
            return within_hop_list
Ahmad Reza's avatar
Ahmad Reza committed
297
298
299
        else:
            return None

Ahmad Reza's avatar
Ahmad Reza committed
300
    def scan_for_matters_in(self, matter='all', hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
301
        """
Ahmad Reza's avatar
Ahmad Reza committed
302
         Scanning for particles, tiles, or marker on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
303

Ahmad Reza's avatar
Ahmad Reza committed
304
305
306
307
         :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
         :param hop: The hop distance from thee actual position of the scanning particle
         :return: A list of the founded matters
         """
308
309
        starting_x = self.coordinates[0]
        starting_y = self.coordinates[1]
Ahmad Reza's avatar
Ahmad Reza committed
310
        scanned_list = []
311
        logging.info("particle on %s is scanning for %s in %i hops", str(self.coordinates), matter, hop)
Ahmad Reza's avatar
Ahmad Reza committed
312

Ahmad Reza's avatar
Ahmad Reza committed
313
        if matter == "particles":
Karol Actun's avatar
Karol Actun committed
314
            scanned_list = global_scanning(self.world.particle_map_coordinates, hop, self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
315
        elif matter == "tiles":
Karol Actun's avatar
Karol Actun committed
316
            scanned_list = global_scanning(self.world.tile_map_coordinates, hop, self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
317
        elif matter == "markers":
Karol Actun's avatar
Karol Actun committed
318
            scanned_list = global_scanning(self.world.marker_map_coordinates, hop, self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
319
        else:
Karol Actun's avatar
Karol Actun committed
320
            scanned_list = global_scanning(self.world.particle_map_coordinates, hop, self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
321
            if scanned_list is not None:
Karol Actun's avatar
Karol Actun committed
322
323
                scanned_list.extend(global_scanning(self.world.tile_map_coordinates, hop, self.coordinates))
                scanned_list.extend(global_scanning(self.world.marker_map_coordinates, hop, self.coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
324
            else:
Karol Actun's avatar
Karol Actun committed
325
                scanned_list = global_scanning(self.world.tile_map_coordinates, hop, self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
326
                if scanned_list is not None:
Karol Actun's avatar
Karol Actun committed
327
                    scanned_list.extend(global_scanning(self.world.marker_map_coordinates, hop, self.coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
328
                else:
Karol Actun's avatar
Karol Actun committed
329
                    scanned_list = global_scanning(self.world.marker_map_coordinates, hop, self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
330
331
        if scanned_list is not None:
            return scanned_list
Ahmad Reza's avatar
Ahmad Reza committed
332
333
334
        else:
            return None

Ahmad Reza's avatar
Ahmad Reza committed
335
    def scan_for_particles_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
336
        """
337
        Scans for particles, tiles, or marker on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
338
339
340

        :todo: If nothing then everything should be scanned

341
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
342
343
344
345
        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """

Ahmad Reza's avatar
Ahmad Reza committed
346
        within_hop_list = []
Ahmad Reza's avatar
Ahmad Reza committed
347
        for i in range(1, hop + 1):
Ahmad Reza's avatar
Ahmad Reza committed
348
349
350
351
352
            in_list = self.scan_for_particles_in(hop=i)
            if in_list is not None:
                within_hop_list.extend(in_list)
        if len(within_hop_list) != 0:
            return within_hop_list
Ahmad Reza's avatar
Ahmad Reza committed
353
354
355
        else:
            return None

Ahmad Reza's avatar
Ahmad Reza committed
356
    def scan_for_particles_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
357
        """
358
        Scanning for particles, tiles, or marker on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
359

360
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
361
362
363
364
        :param hop: The hop distance from thee actual position of the scanning particle
        :return: A list of the founded matters
        """

Ahmad Reza's avatar
Ahmad Reza committed
365
366
367
368
        scanned_list = self.scan_for_matters_in(matter='particles', hop=hop)
        return scanned_list

    def scan_for_tiles_within(self,  hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
369
        """
370
        Scans for particles, tiles, or marker on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
371
372
373

        :todo: If nothing then everything should be scanned

374
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
375
376
377
378
        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """

Ahmad Reza's avatar
Ahmad Reza committed
379
        within_hop_list = []
Ahmad Reza's avatar
Ahmad Reza committed
380
        for i in range(1, hop + 1):
Ahmad Reza's avatar
Ahmad Reza committed
381
382
383
384
385
            in_list = self.scan_for_tiles_in( hop=i)
            if in_list is not None:
                within_hop_list.extend(in_list)
        if len(within_hop_list) != 0:
            return within_hop_list
Ahmad Reza's avatar
Ahmad Reza committed
386
387
388
        else:
            return None

Ahmad Reza's avatar
Ahmad Reza committed
389
    def scan_for_tiles_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
390
        """
391
        Scanning for particles, tiles, or marker on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
392

393
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
394
395
396
        :param hop: The hop distance from thee actual position of the scanning particle
        :return: A list of the founded matters
        """
Ahmad Reza's avatar
Ahmad Reza committed
397
398
        scanned_list = self.scan_for_matters_in(matter='tiles', hop=hop)
        return scanned_list
Ahmad Reza's avatar
Ahmad Reza committed
399

Ahmad Reza's avatar
Ahmad Reza committed
400
    def scan_for_markers_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
401
        """
402
        Scans for particles, tiles, or marker on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
403
404
405

        :todo: If nothing then everything should be scanned

406
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
407
408
409
410
        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """

Ahmad Reza's avatar
Ahmad Reza committed
411
        within_hop_list = []
Ahmad Reza's avatar
Ahmad Reza committed
412
        for i in range(1, hop + 1):
Ahmad Reza's avatar
Ahmad Reza committed
413
414
415
416
417
            in_list = self.scan_for_markers_in(hop=i)
            if in_list is not None:
                within_hop_list.extend(in_list)
        if len(within_hop_list) != 0:
            return within_hop_list
Ahmad Reza's avatar
Ahmad Reza committed
418
419
420
        else:
            return None

Ahmad Reza's avatar
Ahmad Reza committed
421
    def scan_for_markers_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
422
        """
423
        Scanning for particles, tiles, or marker on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
424

425
        :param matter: For what matter this method should scan for. Can be either particles, tiles, markers, or (default)all
Ahmad Reza's avatar
Ahmad Reza committed
426
427
428
        :param hop: The hop distance from thee actual position of the scanning particle
        :return: A list of the founded matters
        """
Ahmad Reza's avatar
Ahmad Reza committed
429
430
        scanned_list = self.scan_for_matters_in(matter='markers', hop=hop)
        return scanned_list
Ahmad Reza's avatar
Ahmad Reza committed
431

432
    def take_me(self, coordinates=0):
Ahmad Reza's avatar
Ahmad Reza committed
433
434
435
        """
        The particle is getting taken from the the other particle on the given coordinate

436
        :param coordinates: Coordination of particle that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
437
438
439
440
        :return: True: Successful taken; False: Cannot be taken or wrong Coordinates
        """

        if not self.__isCarried:
441
442
            if self.coordinates in self.world.particle_map_coordinates:
                del self.world.particle_map_coordinates[self.coordinates]
Ahmad Reza's avatar
Ahmad Reza committed
443
            self.__isCarried = True
444
445
            self.coordinates = coordinates
            self.set_transparency(0.5)
Ahmad Reza's avatar
Ahmad Reza committed
446
447
448
449
450
            self.touch()
            return True
        else:
            return False

451
    def drop_me(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
452
453
454
        """
        The actual particle is getting dropped

455
        :param coordinates: the given position
Ahmad Reza's avatar
Ahmad Reza committed
456
457
        :return: None
        """
458
459
        self.world.particle_map_coordinates[coordinates] = self
        self.coordinates = coordinates
Ahmad Reza's avatar
Ahmad Reza committed
460
        self.__isCarried = False
461
        self.set_transparency(1)
Ahmad Reza's avatar
Ahmad Reza committed
462
463
        self.touch()

464
    def create_tile(self, color=gray, transparency=1):
Ahmad Reza's avatar
Ahmad Reza committed
465
466
467
        """
        Creates a tile on the particles actual position

Ahmad Reza's avatar
Ahmad Reza committed
468
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
469
        """
470
        logging.info("Going to create a tile on position %s", str(self.coordinates))
Karol Actun's avatar
Karol Actun committed
471
        new_tile = self.world.add_tile(self.coordinates, color, transparency)
Ahmad Reza's avatar
Ahmad Reza committed
472
        if new_tile:
Karol Actun's avatar
Karol Actun committed
473
            self.world.tile_map_coordinates[self.coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
474
            self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
475
476
            self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
            self.world.csv_round.update_metrics( tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
477
478
479
            return new_tile
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
480

481
    def create_tile_in(self, direction=None, color=gray, transparency=1):
Ahmad Reza's avatar
Ahmad Reza committed
482
        """
483
        Creates a tile either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
484

485
        :param direction: The directionection on which the tile should be created. Options: E, SE, SW, W, NW, NE,
Ahmad Reza's avatar
Ahmad Reza committed
486
        :return: New tile or False
Ahmad Reza's avatar
Ahmad Reza committed
487
488
        """
        logging.info("particle with id %s is", self.get_id())
489
        logging.info("Going to create a tile in %s ", str(direction) )
Karol Actun's avatar
Karol Actun committed
490
        if direction is not None:
491
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
Karol Actun's avatar
Karol Actun committed
492
            new_tile = self.world.add_tile(coordinates, color, transparency)
Ahmad Reza's avatar
Ahmad Reza committed
493
            if new_tile:
Karol Actun's avatar
Karol Actun committed
494
                self.world.tile_map_coordinates[coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
495
                logging.info("Tile is created")
Ahmad Reza's avatar
Ahmad Reza committed
496
                self.world.new_tile_flag = True
Ahmad Reza's avatar
Ahmad Reza committed
497
                self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
498
499
                self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
                self.world.csv_round.update_metrics( tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
500
501
502
                return new_tile
            else:
                return False
Ahmad Reza's avatar
Ahmad Reza committed
503
504
        else:
            logging.info("Not created tile ")
Ahmad Reza's avatar
Ahmad Reza committed
505
            return False
Ahmad Reza's avatar
Ahmad Reza committed
506

Karol Actun's avatar
Karol Actun committed
507
    def create_tile_on(self, coordinates=None, color=gray, transparency=1):
Ahmad Reza's avatar
Ahmad Reza committed
508
509
510
        """
        Creates a tile either on a given x,y coordinates

Karol Actun's avatar
Karol Actun committed
511
        :param coordinates: the coordinates
Ahmad Reza's avatar
Ahmad Reza committed
512
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
513
514
515
        """

        logging.info("particle with id %s is", self.get_id())
Karol Actun's avatar
Karol Actun committed
516
517
        if coordinates is not None:
            if grid.is_valid_location(coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
518
                logging.info("Going to create a tile on position \(%i , %i\)", x,y )
Karol Actun's avatar
Karol Actun committed
519
520
                if self.world.add_tile(coordinates, color, transparency):
                    self.world.tile_map_coordinates[coordinates, coordinates[1]].created = True
Ahmad Reza's avatar
Ahmad Reza committed
521
                    self.world.new_tile_flag = True
Ahmad Reza's avatar
Ahmad Reza committed
522
                    self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
523
524
                    self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()) )
                    self.world.csv_round.update_metrics( tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
525
526
                    return True
                else:
527
                    logging.info("Not created tile on coordinates  \(%i , %i\)", y,x )
Ahmad Reza's avatar
Ahmad Reza committed
528
529
                    return False
            else:
530
                logging.info("Not created tile on coordinates   \(%i , %i\)", y,x )
Ahmad Reza's avatar
Ahmad Reza committed
531
                return False
Ahmad Reza's avatar
Ahmad Reza committed
532
533
534
535
536
537
538
539
540

    def delete_tile(self):
        """
        Deletes a tile on current position

        :return: True: Deleting successful; False: Deleting unsuccessful
        """
        logging.info("Particle %s is", self.get_id())
        logging.info("is going to delete a tile on current position")
541
542
        if self.coordinates in self.world.get_tile_map_coordinates():
            if self.world.remove_tile_on(self.coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
                self.csv_particle_writer.write_particle(tile_deleted=1)
                return True
        else:
            logging.info("Could not delet tile")
            return False

    def delete_tile_with(self, id):
        """
        Deletes a tile with a given tile-id

        :param tile_id: The id of the tile that should be deleted
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
        logging.info("Particle %s is", self.get_id())
        logging.info("is going to delete a tile with tile id %s", str(id))
Ahmad Reza's avatar
Ahmad Reza committed
558
        if self.world.remove_tile(id):
Ahmad Reza's avatar
Ahmad Reza committed
559
560
561
562
563
564
            self.csv_particle_writer.write_particle(tile_deleted=1)
            return True
        else:
            logging.info("Could not delet tile with tile id %s", str(id))
            return False

565
    def delete_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
566
        """
567
        Deletes a tile either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
568

569
        :param direction: The directionection on which the tile should be deleted. Options: E, SE, SW, W, NW, NE,
Ahmad Reza's avatar
Ahmad Reza committed
570
571
572

        :return: True: Deleting successful; False: Deleting unsuccessful
        """
573
        coordinates = ()
574
        if direction is not None:
575
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
576
            logging.info("Deleting tile in %s directionection", str(direction))
577
578
579
            if coordinates is not None:
                if self.world.remove_tile_on(coordinates):
                    logging.info("Deleted tile with tile on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
580
581
582
                    self.csv_particle_writer.write_particle(tile_deleted=1)
                    return True
                else:
583
                    logging.info("Could not delet tile on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
584
585
                    return False
        else:
586
            logging.info("Could not delet tile on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
587
588
589
590
591
592
593
594
595
596
            return False

    def delete_tile_on(self, x=None, y=None):
        """
        Deletes a tile either on a given x,y coordinates
,
        :param x: x coordinate
        :param y: y coordinate
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
597
        coordinates = ()
Ahmad Reza's avatar
Ahmad Reza committed
598
        if x is not None and y is not None:
599
600
601
            coordinates = (x, y)
            if self.world.remove_tile_on(coordinates):
                logging.info("Deleted tile with tile on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
602
603
604
                self.csv_particle_writer.write_particle(tile_deleted=1)
                return True
            else:
605
                logging.info("Could not delet tile on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
606
607
                return False
        else:
608
            logging.info("Could not delet tile on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
609
610
611
612
613
614
615
616
617
618
            return False

    def take_tile(self):
        """
        Takes a tile on the actual position

        :param id:  The id of the tile that should be taken
        :return: True: successful taken; False: unsuccessful taken
        """
        if self.carried_particle is None and self.carried_tile is None:
619
620
621
            if self.coordinates in self.world.tile_map_coordinates:
                self.carried_tile = self.world.tile_map_coordinates[self.coordinates]
                if self.carried_tile.take(coordinates=self.coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
622
                    logging.info("Tile has been taken")
Ahmad Reza's avatar
Ahmad Reza committed
623
                    self.world.csv_round.update_metrics( tiles_taken=1)
Ahmad Reza's avatar
Ahmad Reza committed
624
625
626
627
628
629
                    self.csv_particle_writer.write_particle(tiles_taken=1)
                    return True
                else:
                    logging.info("Tile could not be taken")
                    return False
            else:
Ahmad Reza's avatar
Ahmad Reza committed
630
                logging.info("No tile on the actual position not in the world")
Ahmad Reza's avatar
Ahmad Reza committed
631
632
633
634
635
636
637
638
639
640
641
642
643
                return False
        else:
            logging.info("Tile cannot taken because particle is carrieng either a tile or a particle")
            return False

    def take_tile_with(self, id):
        """
        Takes a tile with a given tile id

        :param id:  The id of the tile that should be taken
        :return: True: successful taken; False: unsuccessful taken
        """
        if self.carried_particle is None and self.carried_tile is None:
Ahmad Reza's avatar
Ahmad Reza committed
644
645
646
            if id in self.world.tile_map_id:
                logging.info("Tile with tile id %s is in the world", str(id))
                self.carried_tile = self.world.tile_map_id[id]
647
                if self.carried_tile.take(coordinates=self.coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
648
                    logging.info("Tile with tile id %s  has been taken", str(id))
Ahmad Reza's avatar
Ahmad Reza committed
649
                    self.world.csv_round.update_metrics( tiles_taken=1)
Ahmad Reza's avatar
Ahmad Reza committed
650
651
652
653
654
655
                    self.csv_particle_writer.write_particle(tiles_taken=1)
                    return True
                else:
                    logging.info("Tile with tile id %s could not be taken", str(id))
                    return False
            else:
Ahmad Reza's avatar
Ahmad Reza committed
656
                logging.info("Tile with tile id %s is not in the world", str(id))
Ahmad Reza's avatar
Ahmad Reza committed
657
658
659
660
661
                return False
        else:
            logging.info("Tile cannot taken because particle is carrieng either a tile or a particle", str(id))
            return False

662
    def take_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
663
        """
664
        Takes a tile that is in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
665

Karol Actun's avatar
Karol Actun committed
666
        :param direction: The direction on which the tile should be taken.
Ahmad Reza's avatar
Ahmad Reza committed
667
668
669
        :return: True: successful taken; False: unsuccessful taken
        """
        if self.carried_particle is None and self.carried_tile is None:
670
671
672
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
            if coordinates in self.world.tile_map_coordinates:
                self.carried_tile = self.world.tile_map_coordinates[coordinates]
Ahmad Reza's avatar
Ahmad Reza committed
673
                logging.info("Tile with tile id %s is in the world", str(self.carried_tile.get_id()))
674
                if self.carried_tile.take(coordinates=self.coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
675
                    logging.info("Tile with tile id %s  has been taken", str(self.carried_tile.get_id()))
Ahmad Reza's avatar
Ahmad Reza committed
676
                    self.world.csv_round.update_metrics( tiles_taken=1)
Ahmad Reza's avatar
Ahmad Reza committed
677
678
679
680
681
682
                    self.csv_particle_writer.write_particle(tiles_taken=1)
                    return True
                else:
                    logging.info("Tile with tile id %s could not be taken", str(self.carried_tile.get_id()))
                    return False
            else:
Ahmad Reza's avatar
Ahmad Reza committed
683
                logging.info("Tile is not in the world")
Ahmad Reza's avatar
Ahmad Reza committed
684
685
686
687
688
                return False
        else:
            logging.info("Tile cannot taken because particle is carrieng either a tile or a particle")
            return False

Karol Actun's avatar
Karol Actun committed
689
    def take_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
690
        """
691
        Takes a tile that is in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
692

Karol Actun's avatar
Karol Actun committed
693
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
694
695
696
        :return: True: successful taken; False: unsuccessful taken
        """
        if self.carried_particle is None and self.carried_tile is None:
Karol Actun's avatar
Karol Actun committed
697
698
            if grid.is_valid_location(coordinates):

699
700
                if coordinates in self.world.tile_map_coordinates:
                    self.carried_tile = self.world.tile_map_coordinates[coordinates]
Ahmad Reza's avatar
Ahmad Reza committed
701
                    logging.info("Tile with tile id %s is in the world", str(self.carried_tile.get_id()))
702
                    if self.carried_tile.take(coordinates=self.coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
703
                        self.world.csv_round.update_metrics( tiles_taken=1)
Ahmad Reza's avatar
Ahmad Reza committed
704
705
706
707
708
709
710
                        self.csv_particle_writer.write_particle(tiles_taken=1)
                        logging.info("Tile with tile id %s  has been taken", str(self.carried_tile.get_id()))
                        return True
                    else:
                        logging.info("Tile with tile id %s could not be taken", str(self.carried_tile.get_id()))
                        return False
                else:
Ahmad Reza's avatar
Ahmad Reza committed
711
                    logging.info("Tile is not in the world")
Ahmad Reza's avatar
Ahmad Reza committed
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
                    return False
            else:
                logging.info("Coordinates are wrong")
                return False
        else:
            logging.info("Tile cannot taken because particle is carrieng either a tile or a particle")
            return False

    def drop_tile(self):
        """
        Drops the taken tile on the particles actual position

        :return: None
        """
        if self.carried_tile is not None:
727
            if self.coordinates not in self.world.tile_map_coordinates:
Ahmad Reza's avatar
Ahmad Reza committed
728
                try:  # cher: insert so to overcome the AttributeError
729
                    self.carried_tile.drop_me(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
730
731
732
733
                except AttributeError:
                    pass
                self.carried_tile = None
                logging.info("Tile has been dropped on the actual position")
Ahmad Reza's avatar
Ahmad Reza committed
734
                self.world.csv_round.update_metrics( tiles_dropped=1)
Ahmad Reza's avatar
Ahmad Reza committed
735
736
737
738
739
740
741
742
                self.csv_particle_writer.write_particle(tiles_dropped=1)
                return True
            else:
                logging.info("Is not possible to drop the tile on that position because it is occupied")
                return False
        else:
            return False

743
    def drop_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
744
        """
745
        Drops the taken tile on a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
746

747
         :param direction: The directionection on which the tile should be dropped. Options: E, SE, SW, W, NW, NE,
Ahmad Reza's avatar
Ahmad Reza committed
748
749
        """
        if self.carried_tile is not None:
750
751
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
            if coordinates not in self.world.tile_map_coordinates:
Ahmad Reza's avatar
Ahmad Reza committed
752
                try:  # cher: insert so to overcome the AttributeError
753
                    self.carried_tile.drop_me(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
754
755
756
                except AttributeError:
                    pass
                self.carried_tile = None
Ahmad Reza's avatar
Ahmad Reza committed
757
                self.world.csv_round.update_metrics( tiles_dropped=1)
Ahmad Reza's avatar
Ahmad Reza committed
758
                self.csv_particle_writer.write_particle(tiles_dropped=1)
759
                logging.info("Dropped tile on %s coordinate", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
760
761
762
763
764
765
766
767
768
                return True
            else:
                logging.info("Is not possible to drop the tile on that position")
                return False

        else:
            logging.info("No tile taken for dropping")
            return False

Karol Actun's avatar
Karol Actun committed
769
    def drop_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
770
        """
771
        Drops the taken tile on a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
772

Karol Actun's avatar
Karol Actun committed
773
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
774
775
        """
        if self.carried_tile is not None:
Karol Actun's avatar
Karol Actun committed
776
            if grid.is_valid_location(coordinates):
777
                if coordinates not in self.world.get_tile_map_coordinates():
Ahmad Reza's avatar
Ahmad Reza committed
778
                    try:  # cher: insert so to overcome the AttributeError
779
                        self.carried_tile.drop_me(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
780
781
782
                    except AttributeError:
                        pass
                    self.carried_tile = None
Ahmad Reza's avatar
Ahmad Reza committed
783
                    self.world.csv_round.update_metrics( tiles_dropped=1)
Ahmad Reza's avatar
Ahmad Reza committed
784
                    self.csv_particle_writer.write_particle(tiles_dropped=1)
785
                    logging.info("Dropped tile on %s coordinate", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
786
787
788
789
790
791
792
793
794
795
796
                    return True
                else:
                    logging.info("Is not possible to drop the tile on that position because it is occupied")
                    return False
            else:
                logging.info("Wrong coordinates for dropping the tile")
                return False
        else:
            logging.info("No tile is taken for dropping")
            return False

797
    def create_particle(self, color=black, transparency=1):
Ahmad Reza's avatar
Ahmad Reza committed
798
799
800
        """
        Creates a particle on the particles actual position

Ahmad Reza's avatar
Ahmad Reza committed
801
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
802
        """
803
804
        logging.info("Going to create on position %s", str(self.coordinates))
        new_particle = self.world.add_particle(self.coordinates[0], self.coordinates[1], color, transparency)
Ahmad Reza's avatar
Ahmad Reza committed
805
        if new_particle:
806
            self.world.particle_map_coordinates[self.coordinates[0], self.coordinates[1]].created=True
Ahmad Reza's avatar
Ahmad Reza committed
807
            self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
808
809
            self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
            self.world.csv_round.update_metrics( particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
810
811
812
            return new_particle
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
813

814
    def create_particle_in(self, direction=None, color=black, transparency=1):
Ahmad Reza's avatar
Ahmad Reza committed
815
        """
816
        Creates a particle either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
817

818
        :toDo: seperate the directionection and coordinates and delete state
Ahmad Reza's avatar
Ahmad Reza committed
819

820
        :param direction: The directionection on which the particle should be created. Options: E, SE, SW, W, NW, NE,
Ahmad Reza's avatar
Ahmad Reza committed
821
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
822
        """
823
        coordinates = (0, 0)
824
        if direction is not None:
825
826
827
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
            logging.info("Going to create a particle in %s on position %s", str(direction), str(coordinates))
            new_particle= self.world.add_particle(coordinates[0], coordinates[1], color, transparency)
Ahmad Reza's avatar
Ahmad Reza committed
828
            if new_particle:
829
830
                self.world.particle_map_coordinates[coordinates[0], coordinates[1]].created = True
                logging.info("Created particle on coordinates %s", coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
831
832
                self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
                self.world.csv_round.update_metrics( particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
833
                self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
834
835
836
                return new_particle
            else:
                return False
Ahmad Reza's avatar
Ahmad Reza committed
837
        else:
838
            logging.info("Not created particle on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
839
            return False
Ahmad Reza's avatar
Ahmad Reza committed
840

841
    def create_particle_on(self, x=None, y=None, color=black, transparency=1):
Ahmad Reza's avatar
Ahmad Reza committed
842
843
844
        """
        Creates a particle either on a given x,y coordinates

845
        :toDo: seperate the directionection and coordinates and delete state
Ahmad Reza's avatar
Ahmad Reza committed
846
847
848

        :param x: x coordinate
        :param y: y coordinate
Ahmad Reza's avatar
Ahmad Reza committed
849
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
850
        """
851
        coordinates = (0, 0)
Ahmad Reza's avatar
Ahmad Reza committed
852
        if x is not None and y is not None:
Karol Actun's avatar
Karol Actun committed
853
            if grid.is_valid_location(coordinates):
854
855
                logging.info("Going to create a particle on position %s", str(coordinates))
                new_particle = self.world.add_particle(coordinates[0], coordinates[1], color, transparency)
Ahmad Reza's avatar
Ahmad Reza committed
856
                if new_particle:
857
858
                    self.world.particle_map_coordinates[coordinates[0], coordinates[1]].created = True
                    logging.info("Created particle on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
859
860
                    self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
                    self.world.csv_round.update_metrics( particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
861
                    self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
862
                    return new_particle
Ahmad Reza's avatar
Ahmad Reza committed
863
864
865
866
867
                else:
                    return False
            else:
                return False
        else:
868
            logging.info("Not created particle on coordinates %s", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
869
870
871
872
873
874
875
876
877
878
            return False

    def delete_particle(self):
        """
        Deletes a tile on current position

        :return: True: Deleting successful; False: Deleting unsuccessful
        """
        logging.info("Particle %s is", self.get_id())
        logging.info("is going to delete a particle on current position")
879
880
        if self.coordinates in self.world.get_particle_map_coordinates():
            if self.world.remove_particle_on(self.coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
                self.csv_particle_writer.write_particle(particle_deleted=1)
                return True
        else:
            logging.info("Could not delet particle")
            return False

    def delete_particle_with(self, id):
        """
        Deletes a particle with a given id

        :param id: The id of the particle that should be deleted
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
        logging.info("Particle %s is", self.get_id())
        logging.info("is going to delete a particle with id %s", str(id))
Ahmad Reza's avatar
Ahmad Reza committed
896
        if self.world.remove_particle(id):
Ahmad Reza's avatar
Ahmad Reza committed
897
            self.csv_particle_writer.write_particle(particle_deleted=1)
898
            return True
Ahmad Reza's avatar
Ahmad Reza committed
899
900
        else:
            logging.info("Could not delet particle with particle id %s", str(id))
901
            return False
Ahmad Reza's avatar
Ahmad Reza committed
902

903
    def delete_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
904
        """
905
        Deletes a particle either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
906

907
        :param direction: The directionection on which the particle should be deleted. Options: E, SE, SW, W, NW, NE,
Ahmad Reza's avatar
Ahmad Reza committed
908
909
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
910
        if direction is not None:
911
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
912
            logging.info("Deleting tile in %s directionection", str(direction))
Ahmad Reza's avatar