particle.py 43.8 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 = []
Ahmad Reza's avatar
Ahmad Reza committed
277
        for i in range(1, 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:
Karol Actun's avatar
Karol Actun committed
305
306
            scanned_list = scan_in(self.world.particle_map_coordinates, self.coordinates, hop, self.world.grid)
            scanned_list.extend(scan_in(self.world.tile_map_coordinates, self.coordinates, hop, self.world.grid))
307
            scanned_list.extend(scan_in(self.world.location_map_coordinates, self.coordinates, hop, self.world.grid))
Karol Actun's avatar
Karol Actun committed
308
        return scanned_list
Ahmad Reza's avatar
Ahmad Reza committed
309

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Karol Actun's avatar
Karol Actun committed
784
        :param coordinates
Ahmad Reza's avatar
Ahmad Reza committed
785
786
        :return: True: Deleting successful; False: Deleting unsuccessful
        """
Karol Actun's avatar
Karol Actun committed
787
        if coordinates is not None:
788
            if self.world.grid.are_valid_coordinates(coordinates):
789
                if self.world.remove_particle_on(coordinates):
Karol Actun's avatar
Karol Actun committed
790
                    logging.info("Deleted particle with particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
791
792
793
                    self.csv_particle_writer.write_particle(particle_deleted=1)
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
794
                    logging.info("Could not delet particle on coordinates %s" % str(coordinates))
Ahmad Reza's avatar
Ahmad Reza committed
795
796
797
798
799
800
                    return False
            else:
                return False
        else:
            return False

Karol Actun's avatar
Karol Actun committed
801
    def take_particle_with(self, particle_id):
Ahmad Reza's avatar
Ahmad Reza committed
802
        """
Karol Actun's avatar
Karol Actun committed
803
        Takes a particle with a given tile id
Ahmad Reza's avatar
Ahmad Reza committed
804

Karol Actun's avatar
Karol Actun committed
805
        :param particle_id:  The id of the particle that should be taken
Ahmad Reza's avatar
Ahmad Reza committed
806
807
        :return: True: successful taken; False: unsuccessful taken
        """
Karol Actun's avatar
Karol Actun committed
808
809
810
811
812
813
814
815
816
        if self.carried_tile is None and self.carried_particle is None:
            if particle_id in self.world.get_particle_map_id():
                logging.info("particle with particle id %s is in the world" % str(particle_id))
                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)
Ahmad Reza's avatar
Ahmad Reza committed
817
818
819
                    self.csv_particle_writer.write_particle(particles_taken=1)
                    return True
                else:
Karol Actun's avatar
Karol Actun committed
820
                    logging.info("particle with particle id %s could not be taken" % str(particle_id))
Ahmad Reza's avatar
Ahmad Reza committed
821
822
                    return False
            else: