particle.py 44.1 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)
91
        direction, 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
        if self.world.config_data.border == 1 and \
Karol Actun's avatar
Karol Actun committed
120
121
                (abs(direction_coord[0]) > self.world.get_sim_x_size() or abs(
                    direction_coord[1]) > self.world.get_sim_y_size()):
122
            direction = direction - 3 if direction > 2 else direction + 3
123
            direction_coord = get_coordinates_in_direction(self.coordinates, direction)
124
        return direction, direction_coord
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
125

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

130
        :param target: The matter can be either a particle, tile, or location
Ahmad Reza's avatar
Ahmad Reza committed
131
132
133
        :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
134
135
        if key is not None:
            tmp_memory = target.read_memory_with(key)
Ahmad Reza's avatar
Ahmad Reza committed
136
        else:
Karol Actun's avatar
Karol Actun committed
137
            tmp_memory = target.read_whole_memory()
Ahmad Reza's avatar
Ahmad Reza committed
138

Ahmad Reza's avatar
Ahmad Reza committed
139
140
141
142
143
144
145
146
147
148
149
150
        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
151
        return None
Ahmad Reza's avatar
Ahmad Reza committed
152

Karol Actun's avatar
Karol Actun committed
153
    def matter_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
154
        """
155
        :param direction: the directionection to check if a matter is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
156
157
        :return: True: if a matter is there, False: if not
        """
Karol Actun's avatar
Karol Actun committed
158
159
160
161
        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) \
162
                in self.world.get_location_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
163
164
165
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
166

Karol Actun's avatar
Karol Actun committed
167
    def tile_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
168
        """
Karol Actun's avatar
Karol Actun committed
169
        :param direction: the direction to check if a tile is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
170
171
        :return: True: if a tile is there, False: if not
        """
172
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_tile_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 particle_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 particle is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
180
181
        :return: True: if a particle is there, False: if not
        """
182
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_particle_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 location_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
188
        """
189
190
        :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
191
        """
192
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_location_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

Karol Actun's avatar
Karol Actun committed
197
    def get_matter_in(self, direction):
198
199
200
201
        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)]
202
203
        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
204
205
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
206

Karol Actun's avatar
Karol Actun committed
207
    def get_tile_in(self, direction):
208
209
        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
210
211
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
212

Karol Actun's avatar
Karol Actun committed
213
    def get_particle_in(self, direction):
214
215
        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
216
217
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
218

219
220
221
    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
222
223
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
224

225
226
227
    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
228
229
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
230

Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
231
    def get_tile(self):
Karol Actun's avatar
Karol Actun committed
232
        if self.coordinates in self.world.get_tile_map_coordinates():
233
            return self.world.get_tile_map_coordinates()[self.coordinates]
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
234
235
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
236

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

241
        :param target: The matter can be either a particle, tile, or location
Ahmad Reza's avatar
Ahmad Reza committed
242
243
244
245
        :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
246
247
248
        if data is not None:
            if key is None:
                wrote = target.write_memory(data)
Ahmad Reza's avatar
Ahmad Reza committed
249
            else:
Karol Actun's avatar
Karol Actun committed
250
251
252
253
                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
254
                    self.csv_particle_writer.write_particle(particle_write=1)
Karol Actun's avatar
Karol Actun committed
255
256
                elif target.type == "tile":
                    self.world.csv_round.update_metrics(tile_write=1)
Ahmad Reza's avatar
Ahmad Reza committed
257
                    self.csv_particle_writer.write_particle(tile_write=1)
258
259
260
                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
261
262
263
264
265
266
                return True
            else:
                return False
        else:
            return False

Karol Actun's avatar
Karol Actun committed
267
    def scan_for_matters_within(self, matter_type='all', hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
268
        """
269
        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
270
271
272

        :todo: If nothing then everything should be scanned

Karol Actun's avatar
Karol Actun committed
273
        :param matter_type: For what matter this method should scan for.
274
                            Can be either particles, tiles, locations, or (default) all
Ahmad Reza's avatar
Ahmad Reza committed
275
276
277
278
        :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
279
        within_hop_list = []
280
        for i in range(hop + 1):
Karol Actun's avatar
Karol Actun committed
281
            in_list = self.scan_for_matters_in(matter_type, i)
Ahmad Reza's avatar
Ahmad Reza committed
282
283
284
285
            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
286
287
288
        else:
            return None

Karol Actun's avatar
Karol Actun committed
289
    def scan_for_matters_in(self, matter_type='all', hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
290
        """
291
         Scanning for particles, tiles, or locations on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
292

Karol Actun's avatar
Karol Actun committed
293
         :param matter_type: For what matter this method should scan for.
294
                             Can be either particles, tiles, locations, or (default) all
Ahmad Reza's avatar
Ahmad Reza committed
295
296
297
         :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
298
299
300
301
302
303
304

        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)
305
306
        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
307
        else:
308
309
            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
310
            scanned_list.extend(scan_in(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid))
311
            scanned_list.extend(scan_in(self.world.location_map_coordinates, self.coordinates, hop, self.world.grid))
Karol Actun's avatar
Karol Actun committed
312
        return scanned_list
Ahmad Reza's avatar
Ahmad Reza committed
313

Ahmad Reza's avatar
Ahmad Reza committed
314
    def scan_for_particles_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
315
        """
316
        Scans for particles on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
317
318
319
320
321
322

        :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
323
        return scan_within(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
324

Ahmad Reza's avatar
Ahmad Reza committed
325
    def scan_for_particles_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
326
        """
327
        Scanning for particles on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
328
329
330
331
332

        :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
333
        return scan_in(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
334

Karol Actun's avatar
Karol Actun committed
335
    def scan_for_tiles_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
336
        """
337
        Scans for tiles on a given hop distance and all the matters within the hop distance
Ahmad Reza's avatar
Ahmad Reza committed
338
339
340
341
342
343
344

        :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
345
        return scan_within(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
346

Ahmad Reza's avatar
Ahmad Reza committed
347
    def scan_for_tiles_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
348
        """
349
        Scanning for tiles on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
350
351
352
353

        :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
354
        return scan_in(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid)
Ahmad Reza's avatar
Ahmad Reza committed
355

356
    def scan_for_locations_within(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
357
        """
358
        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
359
360
361
362
363
364
365

        :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
        """

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

368
    def scan_for_locations_in(self, hop=1):
Ahmad Reza's avatar
Ahmad Reza committed
369
        """
370
        Scanning for particles, tiles, or location on a given hop distance
Ahmad Reza's avatar
Ahmad Reza committed
371
372
373
374

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

Karol Actun's avatar
Karol Actun committed
377
    def take_me(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
378
379
380
        """
        The particle is getting taken from the the other particle on the given coordinate

Karol Actun's avatar
Karol Actun committed
381
        :param coordinates, the coordinates of the particle which takes this particle
Ahmad Reza's avatar
Ahmad Reza committed
382
383
384
385
        :return: True: Successful taken; False: Cannot be taken or wrong Coordinates
        """

        if not self.__isCarried:
386
387
            if self.coordinates in self.world.particle_map_coordinates:
                del self.world.particle_map_coordinates[self.coordinates]
Ahmad Reza's avatar
Ahmad Reza committed
388
            self.__isCarried = True
389
            self.coordinates = coordinates
390
391
            if self.world.vis is not None:
                self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
392
393
394
395
            return True
        else:
            return False

396
    def drop_me(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
397
398
399
        """
        The actual particle is getting dropped

400
        :param coordinates: the given position
Ahmad Reza's avatar
Ahmad Reza committed
401
402
        :return: None
        """
403
        self.coordinates = coordinates
Karol Actun's avatar
Karol Actun committed
404
        self.world.particle_map_coordinates[coordinates] = self
Ahmad Reza's avatar
Ahmad Reza committed
405
        self.__isCarried = False
406
407
        if self.world.vis is not None:
            self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
408

Karol Actun's avatar
Karol Actun committed
409
    def create_tile(self):
Ahmad Reza's avatar
Ahmad Reza committed
410
411
412
        """
        Creates a tile on the particles actual position

Ahmad Reza's avatar
Ahmad Reza committed
413
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
414
        """
415
        logging.info("Going to create a tile on position %s", str(self.coordinates))
Karol Actun's avatar
Karol Actun committed
416
        new_tile = self.world.add_tile(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
417
        if new_tile:
Karol Actun's avatar
Karol Actun committed
418
            self.world.tile_map_coordinates[self.coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
419
            self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
420
            self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
Karol Actun's avatar
Karol Actun committed
421
            self.world.csv_round.update_metrics(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
422
423
424
            return new_tile
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
425

Karol Actun's avatar
Karol Actun committed
426
    def create_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
427
        """
Karol Actun's avatar
Karol Actun committed
428
        Creates a tile either in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
429

Karol Actun's avatar
Karol Actun committed
430
        :param direction: The direction on which the tile should be created.
Ahmad Reza's avatar
Ahmad Reza committed
431
        :return: New tile or False
Ahmad Reza's avatar
Ahmad Reza committed
432
        """
Karol Actun's avatar
Karol Actun committed
433
434
        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
435
        if direction is not None:
436
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
Karol Actun's avatar
Karol Actun committed
437
            new_tile = self.world.add_tile(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
438
            if new_tile:
Karol Actun's avatar
Karol Actun committed
439
                self.world.tile_map_coordinates[coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
440
                logging.info("Tile is created")
Ahmad Reza's avatar
Ahmad Reza committed
441
                self.world.new_tile_flag = True
Ahmad Reza's avatar
Ahmad Reza committed
442
                self.csv_particle_writer.write_particle(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
443
                self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
Karol Actun's avatar
Karol Actun committed
444
                self.world.csv_round.update_metrics(tile_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
445
446
447
                return new_tile
            else:
                return False
Ahmad Reza's avatar
Ahmad Reza committed
448
449
        else:
            logging.info("Not created tile ")
Ahmad Reza's avatar
Ahmad Reza committed
450
            return False
Ahmad Reza's avatar
Ahmad Reza committed
451

Karol Actun's avatar
Karol Actun committed
452
    def create_tile_on(self, coordinates=None):
Ahmad Reza's avatar
Ahmad Reza committed
453
454
455
        """
        Creates a tile either on a given x,y coordinates

Karol Actun's avatar
Karol Actun committed
456
        :param coordinates: the coordinates
Ahmad Reza's avatar
Ahmad Reza committed
457
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
458
459
460
        """

        logging.info("particle with id %s is", self.get_id())
Karol Actun's avatar
Karol Actun committed
461
        if coordinates is not None:
462
            if self.world.grid.are_valid_coordinates(coordinates):
Karol Actun's avatar
Karol Actun committed
463
464
                logging.info("Going to create a tile on position %s" % str(coordinates))
                if self.world.add_tile(coordinates):
465
                    self.world.tile_map_coordinates[coordinates].created = True
Ahmad Reza's avatar
Ahmad Reza committed
466
                    self.world.new_tile_flag = True
Ahmad Reza's avatar
Ahmad Reza committed
467
                    self.csv_particle_writer.write_particle(tile_created=1)
Karol Actun's avatar
Karol Actun committed
468
469
                    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
470
471
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
472
                    logging.info("Not created tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
473
474
                    return False
            else:
Karol Actun's avatar
Karol Actun committed
475
                logging.info("Not created tile on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
476
                return False
Ahmad Reza's avatar
Ahmad Reza committed
477
478
479
480
481
482
483

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

        :return: True: Deleting successful; False: Deleting unsuccessful
        """
Karol Actun's avatar
Karol Actun committed
484
        logging.info("Particle %s is" % self.get_id())
Ahmad Reza's avatar
Ahmad Reza committed
485
        logging.info("is going to delete a tile on current position")
486
487
        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
488
489
490
491
492
493
                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
494
    def delete_tile_with(self, tile_id):
Ahmad Reza's avatar
Ahmad Reza committed
495
496
497
498
499
500
        """
        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
501
502
503
        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
504
505
506
            self.csv_particle_writer.write_particle(tile_deleted=1)
            return True
        else:
Karol Actun's avatar
Karol Actun committed
507
            logging.info("Could not delet tile with tile id %s" % str(tile_id))
Ahmad Reza's avatar
Ahmad Reza committed
508
509
            return False

510
    def delete_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
511
        """
512
        Deletes a tile either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
513

514
        :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
515
516
517

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

Karol Actun's avatar
Karol Actun committed
556
    def take_tile_with(self, tile_id):
Ahmad Reza's avatar
Ahmad Reza committed
557
        """
Karol Actun's avatar
Karol Actun committed
558
        Takes a tile with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
559

Karol Actun's avatar
Karol Actun committed
560
        :param tile_id:  The id of the tile that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
561
562
563
        :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
564
565
566
567
568
            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
569
570
                    if self.world.vis is not None:
                        self.world.vis.tile_changed(self.carried_tile)
Karol Actun's avatar
Karol Actun committed
571
                    self.world.csv_round.update_metrics(tiles_taken=1)
Ahmad Reza's avatar
Ahmad Reza committed
572
573
574
                    self.csv_particle_writer.write_particle(tiles_taken=1)
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
575
576
                    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
577
578
                    return False
            else:
Karol Actun's avatar
Karol Actun committed
579
                logging.info("Tile with tile id %s is not in the world" % str(tile_id))
Ahmad Reza's avatar
Ahmad Reza committed
580
581
                return False
        else:
Karol Actun's avatar
Karol Actun committed
582
583
584

            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
585
586
            return False

Karol Actun's avatar
Karol Actun committed
587
    def take_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
588
        """
Karol Actun's avatar
Karol Actun committed
589
        Takes a tile that is in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
590

Karol Actun's avatar
Karol Actun committed
591
        :param direction: The direction on which the tile should be taken.
Ahmad Reza's avatar
Ahmad Reza committed
592
593
        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
594
595
        coordinates = get_coordinates_in_direction(self.coordinates, direction)
        return self.take_tile_on(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
596

Karol Actun's avatar
Karol Actun committed
597
    def take_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
598
        """
Karol Actun's avatar
Karol Actun committed
599
        Takes a tile on given coordinates
Ahmad Reza's avatar
Ahmad Reza committed
600

Karol Actun's avatar
Karol Actun committed
601
        :param coordinates of the tile
Ahmad Reza's avatar
Ahmad Reza committed
602
603
        :return: True: successful taken; False: unsuccessful taken
        """
604
        if self.world.grid.are_valid_coordinates(coordinates):
605
            if coordinates in self.world.tile_map_coordinates:
Karol Actun's avatar
Karol Actun committed
606
                return self.take_tile_with(self.world.tile_map_coordinates[coordinates].get_id())
Ahmad Reza's avatar
Ahmad Reza committed
607
            else:
Karol Actun's avatar
Karol Actun committed
608
                logging.info("There is no Tile at %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
609
610
                return False
        else:
Karol Actun's avatar
Karol Actun committed
611
            logging.info("invalid coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
612
613
            return False

Karol Actun's avatar
Karol Actun committed
614
    def take_tile(self):
Ahmad Reza's avatar
Ahmad Reza committed
615
        """
Karol Actun's avatar
Karol Actun committed
616
        Takes a tile on the actual position
Ahmad Reza's avatar
Ahmad Reza committed
617
618
619

        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
620
        return self.take_tile_on(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
621
622
623
624
625
626
627

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

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

630
    def drop_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
631
        """
Karol Actun's avatar
Karol Actun committed
632
        Drops the taken tile on a given direction
Ahmad Reza's avatar
Ahmad Reza committed
633

634
         :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
635
        """
Karol Actun's avatar
Karol Actun committed
636
        return self.drop_tile_on(get_coordinates_in_direction(self.coordinates, direction))
Ahmad Reza's avatar
Ahmad Reza committed
637

Karol Actun's avatar
Karol Actun committed
638
    def drop_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
639
        """
Karol Actun's avatar
Karol Actun committed
640
        Drops the taken tile on a given direction
Ahmad Reza's avatar
Ahmad Reza committed
641

Karol Actun's avatar
Karol Actun committed
642
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
643
644
        """
        if self.carried_tile is not None:
645
            if self.world.grid.are_valid_coordinates(coordinates):
646
                if coordinates not in self.world.get_tile_map_coordinates():
Ahmad Reza's avatar
Ahmad Reza committed
647
                    try:  # cher: insert so to overcome the AttributeError
648
                        self.carried_tile.drop_me(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
649
650
651
                    except AttributeError:
                        pass
                    self.carried_tile = None
Karol Actun's avatar
Karol Actun committed
652
                    self.world.csv_round.update_metrics(tiles_dropped=1)
Ahmad Reza's avatar
Ahmad Reza committed
653
                    self.csv_particle_writer.write_particle(tiles_dropped=1)
654
                    logging.info("Dropped tile on %s coordinate", str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
655
656
657
658
659
660
661
662
663
664
665
                    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
666
    def create_particle(self):
Ahmad Reza's avatar
Ahmad Reza committed
667
668
669
        """
        Creates a particle on the particles actual position

Ahmad Reza's avatar
Ahmad Reza committed
670
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
671
        """
672
        logging.info("Going to create on position %s", str(self.coordinates))
Karol Actun's avatar
Karol Actun committed
673
        new_particle = self.world.add_particle(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
674
        if new_particle:
Karol Actun's avatar
Karol Actun committed
675
            self.world.particle_map_coordinates[self.coordinates[0], self.coordinates[1]].created = True
Ahmad Reza's avatar
Ahmad Reza committed
676
            self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
677
            self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
Karol Actun's avatar
Karol Actun committed
678
            self.world.csv_round.update_metrics(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
679
680
681
            return new_particle
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
682

Karol Actun's avatar
Karol Actun committed
683
    def create_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
684
        """
Karol Actun's avatar
Karol Actun committed
685
        Creates a particle either in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
686

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

Karol Actun's avatar
Karol Actun committed
689
        :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
690
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
691
        """
692
        if direction is not None:
693
694
            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
695
            new_particle = self.world.add_particle(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
696
            if new_particle:
Karol Actun's avatar
Karol Actun committed
697
                self.world.particle_map_coordinates[coordinates].created = True
698
                logging.info("Created particle on coordinates %s", coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
699
                self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
Karol Actun's avatar
Karol Actun committed
700
                self.world.csv_round.update_metrics(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
701
                self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
702
703
704
                return new_particle
            else:
                return False
Ahmad Reza's avatar
Ahmad Reza committed
705
        else:
Karol Actun's avatar
Karol Actun committed
706
            logging.info("Particle not created. invalid direction (None)")
Ahmad Reza's avatar
Ahmad Reza committed
707
            return False
Ahmad Reza's avatar
Ahmad Reza committed
708

Karol Actun's avatar
Karol Actun committed
709
    def create_particle_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
710
        """
Karol Actun's avatar
Karol Actun committed
711
        Creates a particle either on the given coordinates
Ahmad Reza's avatar
Ahmad Reza committed
712

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

Karol Actun's avatar
Karol Actun committed
715
        :param coordinates: the coordinates
Ahmad Reza's avatar
Ahmad Reza committed
716
        :return: New Particle or False
Ahmad Reza's avatar
Ahmad Reza committed
717
        """
Karol Actun's avatar
Karol Actun committed
718
        if coordinates is not None:
719
            if self.world.grid.are_valid_coordinates(coordinates):
Karol Actun's avatar
Karol Actun committed
720
721
                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
722
                if new_particle:
723
                    self.world.particle_map_coordinates[coordinates].created = True
Karol Actun's avatar
Karol Actun committed
724
                    logging.info("Created particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
725
                    self.world.csv_round.update_particle_num(len(self.world.get_particle_list()))
Karol Actun's avatar
Karol Actun committed
726
                    self.world.csv_round.update_metrics(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
727
                    self.csv_particle_writer.write_particle(particle_created=1)
Ahmad Reza's avatar
Ahmad Reza committed
728
                    return new_particle
Ahmad Reza's avatar
Ahmad Reza committed
729
730
731
732
733
                else:
                    return False
            else:
                return False
        else:
Karol Actun's avatar
Karol Actun committed
734
            logging.info("Not created particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
735
736
737
738
739
740
741
742
743
744
            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")
745
746
        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
747
748
749
750
751
752
                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
753
    def delete_particle_with(self, particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
754
755
756
        """
        Deletes a particle with a given id

Karol Actun's avatar
Karol Actun committed
757
        :param particle_id: The id of the particle that should be deleted
Ahmad Reza's avatar
Ahmad Reza committed
758
759
760
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
        logging.info("Particle %s is", self.get_id())
Karol Actun's avatar
Karol Actun committed
761
762
        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
763
            self.csv_particle_writer.write_particle(particle_deleted=1)
764
            return True
Ahmad Reza's avatar
Ahmad Reza committed
765
        else:
Karol Actun's avatar
Karol Actun committed
766
            logging.info("Could not delet particle with particle id %s" % str(particle_id))
767
            return False
Ahmad Reza's avatar
Ahmad Reza committed
768

769
    def delete_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
770
        """
771
        Deletes a particle either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
772

773
        :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
774
775
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
776
        if direction is not None:
777
            coordinates = get_coordinates_in_direction(self.coordinates, direction)
Karol Actun's avatar
Karol Actun committed
778
            logging.info("Deleting tile in %s directionection" % str(direction))
779
            if self.world.remove_particle_on(coordinates):
Karol Actun's avatar
Karol Actun committed
780
                logging.info("Deleted particle with particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
781
                self.csv_particle_writer.write_particle(particle_deleted=1)
782
                return True
Ahmad Reza's avatar
Ahmad Reza committed
783
            else:
Karol Actun's avatar
Karol Actun committed
784
                logging.info("Could not delet particle on coordinates %s" % str(coordinates))
785
                return False
Ahmad Reza's avatar
Ahmad Reza committed
786

Karol Actun's avatar
Karol Actun committed
787
    def delete_particle_on(self, coordinates=None):
Ahmad Reza's avatar
Ahmad Reza committed
788
789
790
        """
        Deletes a particle either on a given x,y coordinates

Karol Actun's avatar
Karol Actun committed
791
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
792
793
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
794
795
796
797
798
799
800
801
802
803
804
805
        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
806
        else:
807
            logging.info("Could not delete particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
808
809
            return False

810

Karol Actun's avatar
Karol Actun committed
811
    def take_particle_with(self, particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
812
        """
Karol Actun's avatar
Karol Actun committed
813
        Takes a particle with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
814

Karol Actun's avatar
Karol Actun committed
815
        :param particle_id:  The id of the particle that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
816
817
        :return: True: successful taken; False: unsuccessful taken
        """
818
819
820
821
822
823
824
825
826
827
828
829
        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
830
831
            if self.world.vis is not None:
                self.world.vis.particle_changed(self.carried_particle)
832
833
834
            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
835
        else:
836
837
838
839
            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
840

Karol Actun's avatar
Karol Actun committed
841
    def take_particle_on(self, coordinates):