Красимира обнови решението на 15.05.2013 00:24 (преди над 11 години)
+class WorldObject():
+ pass
+
+
+class Food(WorldObject):
+
+ def __init__(self, energy=0):
+ self.energy = energy
+
+
+class PythonPart(WorldObject):
+ pass
+
+
+class PythonHead(PythonPart):
+ pass
+
+
+class Death(Exception):
+ pass
+
+
+class World():
+
+ def __init__(self, width):
+ self.width = width
+ self.world = [Row(width) for index in range(width)]
+
+ def __len__(self):
+ return self.width
+
+ def __getitem__(self, index):
+ if index < 0 or index >= self.width:
+ raise IndexError
+ return self.world[index]
+
+ def get_by_vec(self, vec):
+ return self.world[vec[0]][vec[1]]
+
+
+class Cell():
+
+ def __init__(self, contents=None):
+ if contents:
+ if not isinstance(contents, WorldObject):
+ raise TypeError
+ self.contents = contents
+
+ def is_empty(self):
+ return self.contents is None
+
+
+class Row():
+
+ def __init__(self, length):
+ self.length = length
+ self.row = [Cell() for repeat in range(length)]
+
+ def __getitem__(self, index):
+ if index < 0 or index >= self.length:
+ raise IndexError
+ return self.row[index]
+
+ def __setitem__(self, index, cell):
+ if index < 0 or index >= self.length:
+ raise IndexError
+ self.row[index] = cell
+
+
+class Vec2D(tuple):
+
+ def __new__(klass, x, y):
+ return tuple.__new__(klass, (x, y))
+
+ def __add__(self, vec2):
+ return Vec2D(self[0] + vec2[0], self[1] + vec2[1])
+
+ def __sub__(self, vec2):
+ return Vec2D(self[0] - vec2[0], self[1] - vec2[1])
+
+ def __mul__(self, scalar):
+ return Vec2D(self[0]*scalar, self[1]*scalar)
+
+ def __neg__(self):
+ return Vec2D(-self[0], -self[1])
+
+
+class Python():
+
+ LEFT = Vec2D(0, -1)
+ UP = Vec2D(-1, 0)
+ RIGHT = Vec2D(0, 1)
+ DOWN = Vec2D(1, 0)
+
+ def __init__(self, world, coords, size, direction):
+ self.world = world
+ self.size = size
+ self.direction = direction
+ self.energy = 0
+ self.body = []
+ self._place_head(coords)
+ self._place_body(coords)
+
+ def move(self, direction):
+ if direction == -self.direction:
+ raise ValueError
+
+ new = self.head + self.direction
+ try:
+ world_new = self.world.get_by_vec(new)
+ except IndexError:
+ raise Death
+
+ self.direction = direction
+ new_cell_contents = world_new.contents
+ if isinstance(new_cell_contents, PythonPart):
+ raise Death
+
+ self.body.insert(0, self.head)
+ self.world.get_by_vec(self.head).contents = PythonPart()
+
+ if isinstance(new_cell_contents, Food):
+ self.energy += new_cell_contents.energy
+ self.size += 1
+ else:
+ self._delete_tail()
+
+ self.world.get_by_vec(new).contents = PythonHead()
+ self.head = new
+
+ def _delete_tail(self):
+ self.world.get_by_vec(self.body[-1]).contents = None
+ del(self.body[-1])
+
+ def _place_head(self, coords):
+ self.head = coords
+ self.world.get_by_vec(coords).contents = PythonHead()
+
+ def _place_body(self, coords):
+ for i in range(self.size):
+ coords -= self.direction
+ self.world.get_by_vec(coords).contents = PythonPart()
+ self.body.append(coords)