particle.py 43.7 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)
92
        if self.world.grid.are_valid_coordinates(direction_coord):
Karol Actun's avatar
Karol Actun committed
93
94
95
            if 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]
96
97
                self.coordinates = direction_coord
                self.world.particle_map_coordinates[self.coordinates] = self
Karol Actun's avatar
Karol Actun committed
98
                self.world.vis.particle_changed(self)
99
                logging.info("particle %s successfully moved to %s", str(self.get_id()), direction)
Karol Actun's avatar
Karol Actun committed
100
                self.world.csv_round.update_metrics(steps=1)
Ahmad Reza's avatar
Ahmad Reza committed
101
                self.csv_particle_writer.write_particle(steps=1)
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
102
                self.check_for_carried_tile_or_particle()
Ahmad Reza's avatar
Ahmad Reza committed
103
                return True
Karol Actun's avatar
Karol Actun committed
104

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

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

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

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

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

Karol Actun's avatar
Karol Actun committed
136
137
138
139
        if tmp_memory is not None:
            if not (hasattr(tmp_memory, '__len__')) or len(tmp_memory) > 0:
                if target.type == "particle":
                    self.world.csv_round.update_metrics(particle_read=1)
140
                    self.csv_particle_writer.write_particle(particle_read=1)
Karol Actun's avatar
Karol Actun committed
141
142
                elif target.type == "tile":
                    self.world.csv_round.update_metrics(tile_read=1)
143
                    self.csv_particle_writer.write_particle(tile_read=1)
144
145
146
                elif target.type == "location":
                    self.world.csv_round.update_metrics(location_read=1)
                    self.csv_particle_writer.write_particle(location_read=1)
147
148
                return tmp_memory
        return None
Ahmad Reza's avatar
Ahmad Reza committed
149

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

Karol Actun's avatar
Karol Actun committed
164
    def tile_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
165
        """
Karol Actun's avatar
Karol Actun committed
166
        :param direction: the direction to check if a tile is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
167
168
        :return: True: if a tile is there, False: if not
        """
169
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_tile_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
170
171
172
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
173

Karol Actun's avatar
Karol Actun committed
174
    def particle_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
175
        """
Karol Actun's avatar
Karol Actun committed
176
        :param direction: the direction to check if a particle is there
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
177
178
        :return: True: if a particle is there, False: if not
        """
179
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_particle_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
180
181
182
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
183

184
    def location_in(self, direction):
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
185
        """
186
187
        :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
188
        """
189
        if get_coordinates_in_direction(self.coordinates, direction) in self.world.get_location_map_coordinates():
Ahmad Reza Cheraghi's avatar
Ahmad Reza Cheraghi committed
190
191
192
            return True
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
193

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

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

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

216
217
218
    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
219
220
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
221

222
223
224
    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
225
226
        else:
            return False
Ahmad Reza's avatar
Ahmad Reza committed
227

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

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

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

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

        :todo: If nothing then everything should be scanned

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if not self.__isCarried:
383
384
            if self.coordinates in self.world.particle_map_coordinates:
                del self.world.particle_map_coordinates[self.coordinates]
Ahmad Reza's avatar
Ahmad Reza committed
385
            self.__isCarried = True
386
            self.coordinates = coordinates
Karol Actun's avatar
Karol Actun committed
387
            self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
388
389
390
391
            return True
        else:
            return False

392
    def drop_me(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
393
394
395
        """
        The actual particle is getting dropped

396
        :param coordinates: the given position
Ahmad Reza's avatar
Ahmad Reza committed
397
398
        :return: None
        """
399
        self.coordinates = coordinates
Karol Actun's avatar
Karol Actun committed
400
        self.world.particle_map_coordinates[coordinates] = self
Ahmad Reza's avatar
Ahmad Reza committed
401
        self.__isCarried = False
Karol Actun's avatar
Karol Actun committed
402
        self.world.vis.particle_changed(self)
Ahmad Reza's avatar
Ahmad Reza committed
403

Karol Actun's avatar
Karol Actun committed
404
    def create_tile(self):
Ahmad Reza's avatar
Ahmad Reza committed
405
406
407
        """
        Creates a tile on the particles actual position

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

Karol Actun's avatar
Karol Actun committed
421
    def create_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
422
        """
Karol Actun's avatar
Karol Actun committed
423
        Creates a tile either in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
424

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

Karol Actun's avatar
Karol Actun committed
447
    def create_tile_on(self, coordinates=None):
Ahmad Reza's avatar
Ahmad Reza committed
448
449
450
        """
        Creates a tile either on a given x,y coordinates

Karol Actun's avatar
Karol Actun committed
451
        :param coordinates: the coordinates
Ahmad Reza's avatar
Ahmad Reza committed
452
        :return: New Tile or False
Ahmad Reza's avatar
Ahmad Reza committed
453
454
455
        """

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

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

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

505
    def delete_tile_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
506
        """
507
        Deletes a tile either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
508

509
        :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
510
511
512

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

Karol Actun's avatar
Karol Actun committed
551
    def take_tile_with(self, tile_id):
Ahmad Reza's avatar
Ahmad Reza committed
552
        """
Karol Actun's avatar
Karol Actun committed
553
        Takes a tile with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
554

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

            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
579
580
            return False

Karol Actun's avatar
Karol Actun committed
581
    def take_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
582
        """
Karol Actun's avatar
Karol Actun committed
583
        Takes a tile that is in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
584

Karol Actun's avatar
Karol Actun committed
585
        :param direction: The direction on which the tile should be taken.
Ahmad Reza's avatar
Ahmad Reza committed
586
587
        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
588
589
        coordinates = get_coordinates_in_direction(self.coordinates, direction)
        return self.take_tile_on(coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
590

Karol Actun's avatar
Karol Actun committed
591
    def take_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
592
        """
Karol Actun's avatar
Karol Actun committed
593
        Takes a tile on given coordinates
Ahmad Reza's avatar
Ahmad Reza committed
594

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

Karol Actun's avatar
Karol Actun committed
608
    def take_tile(self):
Ahmad Reza's avatar
Ahmad Reza committed
609
        """
Karol Actun's avatar
Karol Actun committed
610
        Takes a tile on the actual position
Ahmad Reza's avatar
Ahmad Reza committed
611
612
613

        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
614
        return self.take_tile_on(self.coordinates)
Ahmad Reza's avatar
Ahmad Reza committed
615
616
617
618
619
620
621

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

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

624
    def drop_tile_in(self, direction):
Ahmad Reza's avatar
Ahmad Reza committed
625
        """
Karol Actun's avatar
Karol Actun committed
626
        Drops the taken tile on a given direction
Ahmad Reza's avatar
Ahmad Reza committed
627

628
         :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
629
        """
Karol Actun's avatar
Karol Actun committed
630
        return self.drop_tile_on(get_coordinates_in_direction(self.coordinates, direction))
Ahmad Reza's avatar
Ahmad Reza committed
631

Karol Actun's avatar
Karol Actun committed
632
    def drop_tile_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
633
        """
Karol Actun's avatar
Karol Actun committed
634
        Drops the taken tile on a given direction
Ahmad Reza's avatar
Ahmad Reza committed
635

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

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

Karol Actun's avatar
Karol Actun committed
677
    def create_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
678
        """
Karol Actun's avatar
Karol Actun committed
679
        Creates a particle either in a given direction
Ahmad Reza's avatar
Ahmad Reza committed
680

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

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

Karol Actun's avatar
Karol Actun committed
703
    def create_particle_on(self, coordinates):
Ahmad Reza's avatar
Ahmad Reza committed
704
        """
Karol Actun's avatar
Karol Actun committed
705
        Creates a particle either on the given coordinates
Ahmad Reza's avatar
Ahmad Reza committed
706

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

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

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

763
    def delete_particle_in(self, direction=None):
Ahmad Reza's avatar
Ahmad Reza committed
764
        """
765
        Deletes a particle either in a given directionection
Ahmad Reza's avatar
Ahmad Reza committed
766

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

Karol Actun's avatar
Karol Actun committed
781
    def delete_particle_on(self, coordinates=None):
Ahmad Reza's avatar
Ahmad Reza committed
782
783
784
        """
        Deletes a particle either on a given x,y coordinates

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

804

Karol Actun's avatar
Karol Actun committed
805
    def take_particle_with(self, particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
806
        """
Karol Actun's avatar
Karol Actun committed
807
        Takes a particle with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
808

Karol Actun's avatar
Karol Actun committed
809
        :param particle_id:  The id of the particle that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
810
811
        :return: True: successful taken; False: unsuccessful taken
        """
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
        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
            self.world.vis.particle_changed(self.carried_particle)
            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
828
        else:
Karol Actun's avatar