Емил обнови решението на 15.05.2013 07:50 (преди над 11 години)
+class WorldObject:
+ pass
+
+
+class Death(Exception):
+ pass
+
+class Food(WorldObject):
+
+ energy = 0
+
+ def __init__(self, energy):
+ self.energy = energy
+
+class Cell:
+
+ def __init__(self, contents = None):
+ if not (isinstance(contents, WorldObject) or contents == None):
+ raise TypeError
+ self.contents = contents
+
+ def is_empty(self):
+ return self.contents == None
+
+ def __repr__(self):
+ return self.contents
+
+
+class PythonPart(WorldObject):
+ def __init__(self, x, y, cell):
+ self.x = x
+ self.y = y
+ self.add_to_cell(cell)
+
+ def add_to_cell(self, cell):
+ self.cell = cell
+ self.cell.contents = self
+
+ def remove_from_cell(self):
+ self.cell.contents = None
+ self.cell = None
+
+ def __str__(self):
+ return '#'
+
+
+class PythonHead(PythonPart):
+ def __init__(self, x, y, cell):
+ super(PythonHead, self).__init__(x, y, cell)
+
+ def __str__(self):
+ return '@'
+
+
+class World:
+ def __init__(self, width):
+ self.width = width
+ self.world_map = []
+ for i in range(self.width):
+ column = []
+ for j in range(self.width):
+ column.append(Cell())
+ self.world_map.append(column)
+
+ def __len__(self):
+ return self.width
+
+ def __getitem__(self, key):
+ if key < 0 or key > self.width:
+ raise IndexError
+ return self.world_map[key]
+
+ def _print(self):
+ for i in range(self.width):
+ for column in self.world_map:
+ print(column[i].contents, end=' ')
+ print()
+
+class Vec2D:
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+ def __add__(self, vec):
+ return Vec2D(self.x + vec.x, self.y + vec.y)
+
+ def __sub__(self, vec):
+ return Vec2D(self.x - vec.x, self.y - vec.y)
+
+ def __mul__(self, i):
+ return Vec2D(self.x * i, self.y * i)
+
+ def __neg__(self):
+ return -1 * self
+
+ def __str__(self):
+ return "v(%d, %d)" % (self.x, self.y)
+
+ def __repr__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.__str__())
+
+ def get_opposite(self):
+ return Vec2D(0, 0) - self
+
+ def is_opposite_of(self, direction):
+ if self.x + direction.x == 0 and self.y + direction.y == 0:
+ return True
+ return False
+
+ def __iter__(self):
+ yield self.x
+ yield self.y
+
+
+class Python:
+ LEFT = Vec2D(-1, 0)
+ RIGHT = Vec2D(1, 0)
+ UP = Vec2D(0, -1)
+ DOWN = Vec2D(0, 1)
+
+ def __init__(self, world, coords, size, direction):
+ self.world = world
+ self.size = size
+ self.direction = direction
+ self.energy = 0
+ self.body = []
+ self.init_python(coords.x, coords.y, size, direction)
+
+ def init_python(self, x, y, size, direction):
+ self.body.insert(0, PythonHead(x, y, self.world[x][y]))
+ opposite_direction = direction.get_opposite()
+ for i in range(size):
+ x = x + opposite_direction.x
+ y = y + opposite_direction.y
+ self.body.insert(0, PythonPart(x, y, self.world[x][y]))
+
+ def move(self, direction):
+ if direction.is_opposite_of(self.direction):
+ raise ValueError
+ head = self.body.pop()
+ self.body.append(PythonPart(head.x, head.y, head.cell))
+ new_head_x = head.x + direction.x
+ new_head_y = head.y + direction.y
+ new_head_cell = None
+ try:
+ new_head_cell = self.world[new_head_x][new_head_y]
+ except IndexError:
+ raise Death
+ return
+ if isinstance(new_head_cell.contents, PythonPart):
+ raise Death
+ if isinstance(new_head_cell.contents, Food):
+ self.energy += new_head_cell.contents.energy
+ self.size += 1
+ else:
+ tail = self.body.pop(0)
+ tail.remove_from_cell()
+ new_head = PythonHead(new_head_x, new_head_y, new_head_cell)
+ self.body.append(new_head)
+ self.direction = direction