particle.py 44.9 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):
Karol Actun's avatar
Karol Actun committed
18
19

    def __init__(self, world, coordinates, color, particle_counter=0):
20
        """Initializing the particle constructor"""
Karol Actun's avatar
Karol Actun committed
21
22
        super().__init__(world, coordinates, color,
                         type="particle", mm_size=world.config_data.particle_mm_size)
23
        self.number = particle_counter
Ahmad Reza's avatar
Ahmad Reza committed
24
25
26
27
        self.__isCarried = False
        self.carried_tile = None
        self.carried_particle = None
        self.steps = 0
Karol Actun's avatar
Karol Actun committed
28
        self.csv_particle_writer = csv_generator.CsvParticleData(self.get_id(), self.number)
Ahmad Reza's avatar
Ahmad Reza committed
29
30

    def has_tile(self):
Karol Actun's avatar
Karol Actun committed
31
        if self.carried_tile is None:
Ahmad Reza's avatar
Ahmad Reza committed
32
33
34
35
36
            return False
        else:
            return True

    def has_particle(self):
Karol Actun's avatar
Karol Actun committed
37
38
        if self.carried_particle is None:
            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_location(self):
Ahmad Reza's avatar
Ahmad Reza committed
73
        """
74
        Checks if the particle is on a location
Ahmad Reza's avatar
Ahmad Reza committed
75

76
        :return: True: On a location; False: Not on a location
Ahmad Reza's avatar
Ahmad Reza committed
77
        """
78
        if self.coordinates in self.world.location_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)
Ahmad Reza's avatar
Ahmad Reza committed
91
        direction_coord = self.check_within_border(direction, direction_coord)
Ahmad Reza's avatar
Ahmad Reza committed
92
93
94
95
96
97
        if self.world.grid.are_valid_coordinates(direction_coord) \
        and direction_coord not in self.world.particle_map_coordinates:
            if self.coordinates in self.world.particle_map_coordinates:
                del self.world.particle_map_coordinates[self.coordinates]
            self.coordinates = direction_coord
            self.world.particle_map_coordinates[self.coordinates] = self
98
99
            if self.world.vis is not None:
                self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
100
101
102
103
104
            logging.info("particle %s successfully moved to %s", str(self.get_id()), direction)
            self.world.csv_round.update_metrics(steps=1)
            self.csv_particle_writer.write_particle(steps=1)
            self.check_for_carried_tile_or_particle()
            return True
Karol Actun's avatar
Karol Actun committed
105

106
        return False
Ahmad Reza's avatar
Ahmad Reza committed
107

Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
108
109
    def check_for_carried_tile_or_particle(self):
        if self.carried_tile is not None:
110
            self.carried_tile.coordinates = self.coordinates
111
112
            if self.world.vis is not None:
                self.world.vis.tile_changed(self.carried_tile)
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
113
        elif self.carried_particle is not None:
114
            self.carried_particle.coordinates = self.coordinates
115
116
            if self.world.vis is not None:
                self.world.vis.particle_changed(self.carried_particle)
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
117

118
    def check_within_border(self, direction, direction_coord):
Ahmad Reza's avatar
Ahmad Reza committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
        if self.world.config_data.border == 1:
            if self.world.config_data.type == 1:
                if abs(direction_coord[0]) > self.world.get_world_x_size():
                    direction_coord = (-1 * (self.coordinates[0] - direction[0]), direction_coord[1], direction_coord[2])
                if abs(direction_coord[1]) > self.world.get_world_y_size():
                    direction_coord = (direction_coord[0], -1* (self.coordinates[1] - direction[1]), direction_coord[2])
                if abs(direction_coord[2]) > self.world.get_world_z_size():
                    direction_coord = (direction_coord[0], direction_coord[1], -1* (self.coordinates[2] - direction[2]))
            else:
                if abs(direction_coord[0]) > self.world.get_world_x_size():
                    direction_coord = (self.coordinates[0], direction_coord[1], direction_coord[2])
                if abs(direction_coord[1]) > self.world.get_world_y_size():
                    direction_coord = (direction_coord[0], self.coordinates[1], direction_coord[2])
                if abs(direction_coord[2]) > self.world.get_world_z_size():
                    direction_coord = (direction_coord[0], direction_coord[1], self.coordinates[2])
        return direction_coord
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
135

Karol Actun's avatar
Karol Actun committed
136
    def read_from_with(self, target, key=None):
Ahmad Reza's avatar
Ahmad Reza committed
137
        """
138
        Read the memories from the matters (particle, tile, or location object) memories with a given keyword
Ahmad Reza's avatar
Ahmad Reza committed
139

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

Ahmad Reza's avatar
Ahmad Reza committed
149
150
151
152
153
154
155
156
157
158
159
160
        if tmp_memory is not None \
        and not (hasattr(tmp_memory, '__len__')) or len(tmp_memory) > 0:
            if target.type == "particle":
                self.world.csv_round.update_metrics(particle_read=1)
                self.csv_particle_writer.write_particle(particle_read=1)
            elif target.type == "tile":
                self.world.csv_round.update_metrics(tile_read=1)
                self.csv_particle_writer.write_particle(tile_read=1)
            elif target.type == "location":
                self.world.csv_round.update_metrics(location_read=1)
                self.csv_particle_writer.write_particle(location_read=1)
            return tmp_memory
161
        return None
Ahmad Reza's avatar
Ahmad Reza committed
162

Karol Actun's avatar
Karol Actun committed
163
    def matter_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
164
        """
165
        :param direction: the directionection to check if a matter is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
166
167
        :return: True: if a matter is there, False: if not
        """
Karol Actun's avatar
Karol Actun committed
168
169
170
171
        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) \
172
                in self.world.get_location_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

Karol Actun's avatar
Karol Actun committed
177
    def tile_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
178
        """
Karol Actun's avatar
Karol Actun committed
179
        :param direction: the direction 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

Karol Actun's avatar
Karol Actun committed
187
    def particle_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
188
        """
Karol Actun's avatar
Karol Actun committed
189
        :param direction: the direction 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 location_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
198
        """
199
200
        :param direction: the direction to check if a location is there
        :return: True: if a location is there, False: if not
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
201
        """
202
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_location_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

Karol Actun's avatar
Karol Actun committed
207
    def get_matter_in(self, direction):
208
209
210
211
        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)]
212
213
        elif get_coordinates_in_direction(self.coordinates, direction) in self.world.get_location_map_coordinates():
            return self.world.get_location_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

Karol Actun's avatar
Karol Actun committed
217
    def get_tile_in(self, direction):
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

Karol Actun's avatar
Karol Actun committed
223
    def get_particle_in(self, direction):
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
230
231
    def get_location_in(self, direction):
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_location_map_coordinates():
            return self.world.get_location_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
236
237
    def get_location(self):
        if self.coordinates in self.world.location_map_coordinates:
            return self.world.get_location_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):
Karol Actun's avatar
Karol Actun committed
242
        if self.coordinates in self.world.get_tile_map_coordinates():
243
            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

Karol Actun's avatar
Karol Actun committed
247
    def write_to_with(self, target, key=None, data=None):
Ahmad Reza's avatar
Ahmad Reza committed
248
        """
249
        Writes data with given a keyword direction on the matters (particle, tile, or location object) memory
Ahmad Reza's avatar
Ahmad Reza committed
250

251
        :param target: The matter can be either a particle, tile, or location
Ahmad Reza's avatar
Ahmad Reza committed
252
253
254
255
        :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
        """
Karol Actun's avatar
Karol Actun committed
256
257
258
        if data is not None:
            if key is None:
                wrote = target.write_memory(data)
Ahmad Reza's avatar
Ahmad Reza committed
259
            else:
Karol Actun's avatar
Karol Actun committed
260
261
262
263
                wrote = target.write_memory_with(key, data)
            if wrote:
                if target.type == "particle":
                    self.world.csv_round.update_metrics(particle_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
264
                    self.csv_particle_writer.write_particle(particle_write=1)
Karol Actun's avatar
Karol Actun committed
265
266
                elif target.type == "tile":
                    self.world.csv_round.update_metrics(tile_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
267
                    self.csv_particle_writer.write_particle(tile_write=1)
268
269
270
                elif target.type == "location":
                    self.world.csv_round.update_metrics(location_write=1)
                    self.csv_particle_writer.write_particle(location_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
271
272
273
274
275
276
                return True
            else:
                return False
        else:
            return False

Karol Actun's avatar
Karol Actun committed
277
    def scan_for_matters_within(self, matter_type='all', hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
278
        """
279
        Scans for particles, tiles, or locations on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
280
281
282

        :todo: If nothing then everything should be scanned

Karol Actun's avatar
Karol Actun committed
283
        :param matter_type: For what matter this method should scan for.
284
                            Can be either particles, tiles, locations, or (default) all
Ahmad Reza's avatar
Ahmad Reza committed
285
286
287
288
        :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
289
        within_hop_list = []
290
        for i in range(hop + 1):
Karol Actun's avatar
Karol Actun committed
291
            in_list = self.scan_for_matters_in(matter_type, i)
Ahmad Reza's avatar
Ahmad Reza committed
292
293
294
295
            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
296
297
298
        else:
            return None

Karol Actun's avatar
Karol Actun committed
299
    def scan_for_matters_in(self, matter_type='all', hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
300
        """
301
         Scanning for particles, tiles, or locations on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
302

Karol Actun's avatar
Karol Actun committed
303
         :param matter_type: For what matter this method should scan for.
304
                             Can be either particles, tiles, locations, or (default) all
Ahmad Reza's avatar
Ahmad Reza committed
305
306
307
         :param hop: The hop distance from thee actual position of the scanning particle
         :return: A list of the founded matters
         """
Karol Actun's avatar
Karol Actun committed
308
309
310
311
312
313
314

        logging.info("particle on %s is scanning for %s in %i hops", str(self.coordinates), matter_type, hop)

        if matter_type == "particles":
            scanned_list = scan_in(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid)
        elif matter_type == "tiles":
            scanned_list = scan_in(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid)
315
316
        elif matter_type == "locations":
            scanned_list = scan_in(self.world.location_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
317
        else:
318
319
            scanned_list = []
            scanned_list.extend(scan_in(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid))
Karol Actun's avatar
Karol Actun committed
320
            scanned_list.extend(scan_in(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid))
321
            scanned_list.extend(scan_in(self.world.location_map_coordinates, self.coordinates, hop, self.world.grid))
Karol Actun's avatar
Karol Actun committed
322
        return scanned_list
Ahmad Reza's avatar
Ahmad Reza committed
323

Ahmad Reza's avatar
Ahmad Reza committed
324
    def scan_for_particles_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
325
        """
326
        Scans for particles on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
327
328
329
330
331
332

        :todo: If nothing then everything should be scanned

        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """
Karol Actun's avatar
Karol Actun committed
333
        return scan_within(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
334

Ahmad Reza's avatar
Ahmad Reza committed
335
    def scan_for_particles_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
336
        """
337
        Scanning for particles on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
338
339
340
341
342

        :param hop: The hop distance from thee actual position of the scanning particle
        :return: A list of the founded matters
        """

Karol Actun's avatar
Karol Actun committed
343
        return scan_in(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
344

Karol Actun's avatar
Karol Actun committed
345
    def scan_for_tiles_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
346
        """
347
        Scans for tiles on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
348
349
350
351
352
353
354

        :todo: If nothing then everything should be scanned

        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """

Karol Actun's avatar
Karol Actun committed
355
        return scan_within(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
356

Ahmad Reza's avatar
Ahmad Reza committed
357
    def scan_for_tiles_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
358
        """
359
        Scanning for tiles on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
360
361
362
363

        :param hop: The hop distance from thee actual position of the scanning particle
        :return: A list of the founded matters
        """
Karol Actun's avatar
Karol Actun committed
364
        return scan_in(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
365

366
    def scan_for_locations_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
367
        """
368
        Scans for particles, tiles, or location on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
369
370
371
372
373
374
375

        :todo: If nothing then everything should be scanned

        :param hop: The hop distance from the actual position of the scanning particle
        :return: A list of the founded matters
        """

376
        return scan_within(self.world.location_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
377

378
    def scan_for_locations_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
379
        """
380
        Scanning for particles, tiles, or location on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
381
382
383
384

        :param hop: The hop distance from thee actual position of the scanning particle
        :return: A list of the founded matters
        """
385
        return scan_in(self.world.location_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
386

Karol Actun's avatar
Karol Actun committed
387
    def take_me(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
388
389
390
        """
        The particle is getting taken from the the other particle on the given coordinate

Karol Actun's avatar
Karol Actun committed
391
        :param coordinates, the coordinates of the particle which takes this particle
Ahmad Reza's avatar
Ahmad Reza committed
392
393
394
395
        :return: True: Successful taken; False: Cannot be taken or wrong Coordinates
        """

        if not self.__isCarried:
396
397
            if self.coordinates in self.world.particle_map_coordinates:
                del self.world.particle_map_coordinates[self.coordinates]
Ahmad Reza's avatar
Ahmad Reza committed
398
            self.__isCarried = True
399
            self.coordinates = coordinates
400
401
            if self.world.vis is not None:
                self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
402
403
404
405
            return True
        else:
            return False

406
    def drop_me(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
407
408
409
        """
        The actual particle is getting dropped

410
        :param coordinates: the given position
Ahmad Reza's avatar
Ahmad Reza committed
411
412
        :return: None
        """
413
        self.coordinates = coordinates
Karol Actun's avatar
Karol Actun committed
414
        self.world.particle_map_coordinates[coordinates] = self
Ahmad Reza's avatar
Ahmad Reza committed
415
        self.__isCarried = False
416
417
        if self.world.vis is not None:
            self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
418

Karol Actun's avatar
Karol Actun committed
419
    def create_tile(self):
Ahmad Reza's avatar
Ahmad Reza committed
420
421
422
        """
        Creates a tile on the particles actual position

Ahmad Reza's avatar
Ahmad Reza committed
423
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
424
        """
425
        logging.info("Going to create a tile on position %s", str(self.coordinates))
Karol Actun's avatar
Karol Actun committed
426
        new_tile = self.world.add_tile(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
427
        if new_tile:
Karol Actun's avatar
Karol Actun committed
428
            self.world.tile_map_coordinates[self.coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
429
            self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
430
            self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
Karol Actun's avatar
Karol Actun committed
431
            self.world.csv_round.update_metrics(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
432
433
434
            return new_tile
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
435

Karol Actun's avatar
Karol Actun committed
436
    def create_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
437
        """
Karol Actun's avatar
Karol Actun committed
438
        Creates a tile either in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
439

Karol Actun's avatar
Karol Actun committed
440
        :param direction: The direction on which the tile should be created.
Ahmad Reza's avatar
Ahmad Reza committed
441
        :return: New tile or False
Ahmad Reza's avatar
Ahmad Reza committed
442
        """
Karol Actun's avatar
Karol Actun committed
443
444
        logging.info("particle with id %s is" % self.get_id())
        logging.info("Going to create a tile in %s " % str(direction))
Karol Actun's avatar
Karol Actun committed
445
        if direction is not None:
446
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
Karol Actun's avatar
Karol Actun committed
447
            new_tile = self.world.add_tile(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
448
            if new_tile:
Karol Actun's avatar
Karol Actun committed
449
                self.world.tile_map_coordinates[coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
450
                logging.info("Tile is created")
Ahmad Reza's avatar
Ahmad Reza committed
451
                self.world.new_tile_flag = True
Ahmad Reza's avatar
Ahmad Reza committed
452
                self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
453
                self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
Karol Actun's avatar
Karol Actun committed
454
                self.world.csv_round.update_metrics(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
455
456
457
                return new_tile
            else:
                return False
Ahmad Reza's avatar
Ahmad Reza committed
458
459
        else:
            logging.info("Not created tile ")
Ahmad Reza's avatar
Ahmad Reza committed
460
            return False
Ahmad Reza's avatar
Ahmad Reza committed
461

Karol Actun's avatar
Karol Actun committed
462
    def create_tile_on(self, coordinates=None):
Ahmad Reza's avatar
Ahmad Reza committed
463
464
465
        """
        Creates a tile either on a given x,y coordinates

Karol Actun's avatar
Karol Actun committed
466
        :param coordinates: the coordinates
Ahmad Reza's avatar
Ahmad Reza committed
467
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
468
469
470
        """

        logging.info("particle with id %s is", self.get_id())
Karol Actun's avatar
Karol Actun committed
471
        if coordinates is not None:
472
            if self.world.grid.are_valid_coordinates(coordinates):
Karol Actun's avatar
Karol Actun committed
473
474
                logging.info("Going to create a tile on position %s" % str(coordinates))
                if self.world.add_tile(coordinates):
475
                    self.world.tile_map_coordinates[coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
476
                    self.world.new_tile_flag = True
Ahmad Reza's avatar
Ahmad Reza committed
477
                    self.csv_particle_writer.write_particle(tile_created=1)
Karol Actun's avatar
Karol Actun committed
478
479
                    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
480
481
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
482
                    logging.info("Not created tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
483
484
                    return False
            else:
Karol Actun's avatar
Karol Actun committed
485
                logging.info("Not created tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
486
                return False
Ahmad Reza's avatar
Ahmad Reza committed
487
488
489
490
491
492
493

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

        :return: True: Deleting successful; False: Deleting unsuccessful
        """
Karol Actun's avatar
Karol Actun committed
494
        logging.info("Particle %s is" % self.get_id())
Ahmad Reza's avatar
Ahmad Reza committed
495
        logging.info("is going to delete a tile on current position")
496
497
        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
498
499
500
501
502
503
                self.csv_particle_writer.write_particle(tile_deleted=1)
                return True
        else:
            logging.info("Could not delet tile")
            return False

Karol Actun's avatar
Karol Actun committed
504
    def delete_tile_with(self, tile_id):
Ahmad Reza's avatar
Ahmad Reza committed
505
506
507
508
509
510
        """
        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
        """
Karol Actun's avatar
Karol Actun committed
511
512
513
        logging.info("Particle %s is" % self.get_id())
        logging.info("is going to delete a tile with tile id %s" % str(tile_id))
        if self.world.remove_tile(tile_id):
Ahmad Reza's avatar
Ahmad Reza committed
514
515
516
            self.csv_particle_writer.write_particle(tile_deleted=1)
            return True
        else:
Karol Actun's avatar
Karol Actun committed
517
            logging.info("Could not delet tile with tile id %s" % str(tile_id))
Ahmad Reza's avatar
Ahmad Reza committed
518
519
            return False

520
    def delete_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
521
        """
522
        Deletes a tile either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
523

524
        :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
525
526
527

        :return: True: Deleting successful; False: Deleting unsuccessful
        """
528
        coordinates = ()
529
        if direction is not None:
530
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
Karol Actun's avatar
Karol Actun committed
531
            logging.info("Deleting tile in %s directionection" % str(direction))
532
533
            if coordinates is not None:
                if self.world.remove_tile_on(coordinates):
Karol Actun's avatar
Karol Actun committed
534
                    logging.info("Deleted tile with tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
535
536
537
                    self.csv_particle_writer.write_particle(tile_deleted=1)
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
538
                    logging.info("Could not delet tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
539
540
                    return False
        else:
Karol Actun's avatar
Karol Actun committed
541
            logging.info("Could not delet tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
542
543
544
545
546
547
548
549
550
551
            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
        """
552
        coordinates = ()
Ahmad Reza's avatar
Ahmad Reza committed
553
        if x is not None and y is not None:
554
555
            coordinates = (x, y)
            if self.world.remove_tile_on(coordinates):
Karol Actun's avatar
Karol Actun committed
556
                logging.info("Deleted tile with tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
557
558
559
                self.csv_particle_writer.write_particle(tile_deleted=1)
                return True
            else:
Karol Actun's avatar
Karol Actun committed
560
                logging.info("Could not delet tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
561
562
                return False
        else:
Karol Actun's avatar
Karol Actun committed
563
            logging.info("Could not delet tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
564
565
            return False

Karol Actun's avatar
Karol Actun committed
566
    def take_tile_with(self, tile_id):
Ahmad Reza's avatar
Ahmad Reza committed
567
        """
Karol Actun's avatar
Karol Actun committed
568
        Takes a tile with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
569

Karol Actun's avatar
Karol Actun committed
570
        :param tile_id:  The id of the tile that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
571
572
573
        :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
574
575
576
577
578
            if tile_id in self.world.tile_map_id:
                self.carried_tile = self.world.tile_map_id[tile_id]
                if self.carried_tile.take():
                    logging.info("Tile with tile id %s  has been taken", str(tile_id))
                    self.carried_tile.coordinates = self.coordinates
579
580
                    if self.world.vis is not None:
                        self.world.vis.tile_changed(self.carried_tile)
Karol Actun's avatar
Karol Actun committed
581
                    self.world.csv_round.update_metrics(tiles_taken=1)
Ahmad Reza's avatar
Ahmad Reza committed
582
583
584
                    self.csv_particle_writer.write_particle(tiles_taken=1)
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
585
586
                    self.carried_tile = None
                    logging.info("Tile with tile id %s could not be taken" % str(tile_id))
Ahmad Reza's avatar
Ahmad Reza committed
587
588
                    return False
            else:
Karol Actun's avatar
Karol Actun committed
589
                logging.info("Tile with tile id %s is not in the world" % str(tile_id))
Ahmad Reza's avatar
Ahmad Reza committed
590
591
                return False
        else:
Karol Actun's avatar
Karol Actun committed
592
593
594

            logging.info("Tile cannot taken because particle is carrying either a tile or a particle (%s, %s)"
                         % (str(self.carried_tile), str(self.carried_particle)))
Ahmad Reza's avatar
Ahmad Reza committed
595
596
            return False

Karol Actun's avatar
Karol Actun committed
597
    def take_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
598
        """
Karol Actun's avatar
Karol Actun committed
599
        Takes a tile that is in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
600

Karol Actun's avatar
Karol Actun committed
601
        :param direction: The direction on which the tile should be taken.
Ahmad Reza's avatar
Ahmad Reza committed
602
603
        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
604
605
        coordinates = get_coordinates_in_direction(self.coordinates, direction)
        return self.take_tile_on(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
606

Karol Actun's avatar
Karol Actun committed
607
    def take_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
608
        """
Karol Actun's avatar
Karol Actun committed
609
        Takes a tile on given coordinates
Ahmad Reza's avatar
Ahmad Reza committed
610

Karol Actun's avatar
Karol Actun committed
611
        :param coordinates of the tile
Ahmad Reza's avatar
Ahmad Reza committed
612
613
        :return: True: successful taken; False: unsuccessful taken
        """
614
        if self.world.grid.are_valid_coordinates(coordinates):
615
            if coordinates in self.world.tile_map_coordinates:
Karol Actun's avatar
Karol Actun committed
616
                return self.take_tile_with(self.world.tile_map_coordinates[coordinates].get_id())
Ahmad Reza's avatar
Ahmad Reza committed
617
            else:
Karol Actun's avatar
Karol Actun committed
618
                logging.info("There is no Tile at %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
619
620
                return False
        else:
Karol Actun's avatar
Karol Actun committed
621
            logging.info("invalid coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
622
623
            return False

Karol Actun's avatar
Karol Actun committed
624
    def take_tile(self):
Ahmad Reza's avatar
Ahmad Reza committed
625
        """
Karol Actun's avatar
Karol Actun committed
626
        Takes a tile on the actual position
Ahmad Reza's avatar
Ahmad Reza committed
627
628
629

        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
630
        return self.take_tile_on(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
631
632
633
634
635
636
637

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

        :return: None
        """
Karol Actun's avatar
Karol Actun committed
638
        return self.drop_tile_on(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
639

640
    def drop_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
641
        """
Karol Actun's avatar
Karol Actun committed
642
        Drops the taken tile on a given direction
Ahmad Reza's avatar
Ahmad Reza committed
643

644
         :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
645
        """
Karol Actun's avatar
Karol Actun committed
646
        return self.drop_tile_on(get_coordinates_in_direction(self.coordinates, direction))
Ahmad Reza's avatar
Ahmad Reza committed
647

Karol Actun's avatar
Karol Actun committed
648
    def drop_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
649
        """
Karol Actun's avatar
Karol Actun committed
650
        Drops the taken tile on a given direction
Ahmad Reza's avatar
Ahmad Reza committed
651

Karol Actun's avatar
Karol Actun committed
652
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
653
654
        """
        if self.carried_tile is not None:
655
            if self.world.grid.are_valid_coordinates(coordinates):
656
                if coordinates not in self.world.get_tile_map_coordinates():
Ahmad Reza's avatar
Ahmad Reza committed
657
                    try:  # cher: insert so to overcome the AttributeError
658
                        self.carried_tile.drop_me(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
659
660
661
                    except AttributeError:
                        pass
                    self.carried_tile = None
Karol Actun's avatar
Karol Actun committed
662
                    self.world.csv_round.update_metrics(tiles_dropped=1)
Ahmad Reza's avatar
Ahmad Reza committed
663
                    self.csv_particle_writer.write_particle(tiles_dropped=1)
664
                    logging.info("Dropped tile on %s coordinate", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
665
666
667
668
669
670
671
672
673
674
675
                    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

Karol Actun's avatar
Karol Actun committed
676
    def create_particle(self):
Ahmad Reza's avatar
Ahmad Reza committed
677
678
679
        """
        Creates a particle on the particles actual position

Ahmad Reza's avatar
Ahmad Reza committed
680
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
681
        """
682
        logging.info("Going to create on position %s", str(self.coordinates))
Karol Actun's avatar
Karol Actun committed
683
        new_particle = self.world.add_particle(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
684
        if new_particle:
Karol Actun's avatar
Karol Actun committed
685
            self.world.particle_map_coordinates[self.coordinates[0], self.coordinates[1]].created = True
Ahmad Reza's avatar
Ahmad Reza committed
686
            self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
687
            self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
Karol Actun's avatar
Karol Actun committed
688
            self.world.csv_round.update_metrics(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
689
690
691
            return new_particle
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
692

Karol Actun's avatar
Karol Actun committed
693
    def create_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
694
        """
Karol Actun's avatar
Karol Actun committed
695
        Creates a particle either in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
696

Karol Actun's avatar
Karol Actun committed
697
        :toDo: separate the direction and coordinates and delete state
Ahmad Reza's avatar
Ahmad Reza committed
698

Karol Actun's avatar
Karol Actun committed
699
        :param direction: The direction on which the particle should be created. Options: E, SE, SW, W, NW, NE,
Ahmad Reza's avatar
Ahmad Reza committed
700
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
701
        """
702
        if direction is not None:
703
704
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
            logging.info("Going to create a particle in %s on position %s", str(direction), str(coordinates))
Karol Actun's avatar
Karol Actun committed
705
            new_particle = self.world.add_particle(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
706
            if new_particle:
Karol Actun's avatar
Karol Actun committed
707
                self.world.particle_map_coordinates[coordinates].created = True
708
                logging.info("Created particle on coordinates %s", coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
709
                self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
Karol Actun's avatar
Karol Actun committed
710
                self.world.csv_round.update_metrics(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
711
                self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
712
713
714
                return new_particle
            else:
                return False
Ahmad Reza's avatar
Ahmad Reza committed
715
        else:
Karol Actun's avatar
Karol Actun committed
716
            logging.info("Particle not created. invalid direction (None)")
Ahmad Reza's avatar
Ahmad Reza committed
717
            return False
Ahmad Reza's avatar
Ahmad Reza committed
718

Karol Actun's avatar
Karol Actun committed
719
    def create_particle_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
720
        """
Karol Actun's avatar
Karol Actun committed
721
        Creates a particle either on the given coordinates
Ahmad Reza's avatar
Ahmad Reza committed
722

Karol Actun's avatar
Karol Actun committed
723
        :toDo: separate the direction and coordinates and delete state
Ahmad Reza's avatar
Ahmad Reza committed
724

Karol Actun's avatar
Karol Actun committed
725
        :param coordinates: the coordinates
Ahmad Reza's avatar
Ahmad Reza committed
726
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
727
        """
Karol Actun's avatar
Karol Actun committed
728
        if coordinates is not None:
729
            if self.world.grid.are_valid_coordinates(coordinates):
Karol Actun's avatar
Karol Actun committed
730
731
                logging.info("Going to create a particle on position %s" % str(coordinates))
                new_particle = self.world.add_particle(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
732
                if new_particle:
733
                    self.world.particle_map_coordinates[coordinates].created = True
Karol Actun's avatar
Karol Actun committed
734
                    logging.info("Created particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
735
                    self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
Karol Actun's avatar
Karol Actun committed
736
                    self.world.csv_round.update_metrics(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
737
                    self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
738
                    return new_particle
Ahmad Reza's avatar
Ahmad Reza committed
739
740
741
742
743
                else:
                    return False
            else:
                return False
        else:
Karol Actun's avatar
Karol Actun committed
744
            logging.info("Not created particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
745
746
747
748
749
750
751
752
753
754
            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")
755
756
        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
757
758
759
760
761
762
                self.csv_particle_writer.write_particle(particle_deleted=1)
                return True
        else:
            logging.info("Could not delet particle")
            return False

Karol Actun's avatar
Karol Actun committed
763
    def delete_particle_with(self, particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
764
765
766
        """
        Deletes a particle with a given id

Karol Actun's avatar
Karol Actun committed
767
        :param particle_id: The id of the particle that should be deleted
Ahmad Reza's avatar
Ahmad Reza committed
768
769
770
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
        logging.info("Particle %s is", self.get_id())
Karol Actun's avatar
Karol Actun committed
771
772
        logging.info("is going to delete a particle with id %s" % str(particle_id))
        if self.world.remove_particle(particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
773
            self.csv_particle_writer.write_particle(particle_deleted=1)
774
            return True
Ahmad Reza's avatar
Ahmad Reza committed
775
        else:
Karol Actun's avatar
Karol Actun committed
776
            logging.info("Could not delet particle with particle id %s" % str(particle_id))
777
            return False
Ahmad Reza's avatar
Ahmad Reza committed
778

779
    def delete_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
780
        """
781
        Deletes a particle either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
782

783
        :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
784
785
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
786
        if direction is not None:
787
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
Karol Actun's avatar
Karol Actun committed
788
            logging.info("Deleting tile in %s directionection" % str(direction))
789
            if self.world.remove_particle_on(coordinates):
Karol Actun's avatar
Karol Actun committed
790
                logging.info("Deleted particle with particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
791
                self.csv_particle_writer.write_particle(particle_deleted=1)
792
                return True
Ahmad Reza's avatar
Ahmad Reza committed
793
            else:
Karol Actun's avatar
Karol Actun committed
794
                logging.info("Could not delet particle on coordinates %s" % str(coordinates))
795
                return False
Ahmad Reza's avatar
Ahmad Reza committed
796

Karol Actun's avatar
Karol Actun committed
797
    def delete_particle_on(self, coordinates=None):
Ahmad Reza's avatar
Ahmad Reza committed
798
799
800
        """
        Deletes a particle either on a given x,y coordinates

Karol Actun's avatar
Karol Actun committed
801
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
802
803
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
804
805
806
807
808
809
810
811
812
813
814
815
        if coordinates is None:
            logging.info("coordinates are 'None'...")
            return False

        if not self.world.grid.are_valid_coordinates(coordinates):
            logging.info("invalid coordinates")
            return False

        if self.world.remove_particle_on(coordinates):
            logging.info("Deleted particle with particle on coordinates %s" % str(coordinates))
            self.csv_particle_writer.write_particle(particle_deleted=1)
            return True
Ahmad Reza's avatar
Ahmad Reza committed
816
        else:
817
            logging.info("Could not delete particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
818
819
            return False

820

Karol Actun's avatar
Karol Actun committed
821
    def take_particle_with(self, particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
822
        """
Karol Actun's avatar
Karol Actun committed
823
        Takes a particle with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
824

Karol Actun's avatar
Karol Actun committed
825
        :param particle_id:  The id of the particle that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
826
827
        :return: True: successful taken; False: unsuccessful taken
        """
828
829
830
831
832
833
834
835
836
837
838
839
        if self.carried_tile is not None or self.carried_particle is not None:
            logging.info("particle %s is already carrying a particle or a tile" % str(self.get_id()))
            return False

        if particle_id not in self.world.get_particle_map_id():
            logging.info("particle with particle id %s is not in the world" % str(particle_id))
            return False

        self.carried_particle = self.world.particle_map_id[particle_id]
        if self.carried_particle.take_me(self.coordinates):
            logging.info("particle with particle id %s  has been taken" % str(particle_id))
            self.carried_particle.coordinates = self.coordinates
840
841
            if self.world.vis is not None:
                self.world.vis.particle_changed(self.carried_particle)
842
843
844
            self.world.csv_round.update_metrics(particles_taken=1)
            self.csv_particle_writer.write_particle(particles_taken=1)
            return True
Ahmad Reza's avatar
Ahmad Reza committed
845
        else:
846
847
848
849
            self.carried_particle = None
            logging.info("particle with particle id %s could not be taken" % str(particle_id))
            return False

Ahmad Reza's avatar
Ahmad Reza committed
850