Добринка обнови решението на 12.05.2013 19:06 (преди над 11 години)
+class WorldLine(dict):
+
+ def __init__(self, width):
+ dict.__init__(self)
+ self.width = width
+
+ def __getitem__(self, row):
+ if row < 0 or row >= self.width:
+ raise IndexError(Exception)
+ return self.get(row, Cell())
+
+
+class World():
+
+ def __init__(self, width):
+ self.width = width
+ self.world = {}
+ for i in range(width):
+ world_line = WorldLine(width)
+ self.world[i] = world_line
+
+ def __str__(self):
+ result = ""
+ for i in range(self.width):
+ for j in range(self.width):
+ world_object = self.world[i][j].contents
+ result += self.__render_world_object(world_object)
+ result += "\n"
+ return result
+
+ def __render_world_object(self, world_object):
+ if world_object is None:
+ return ".."
+ elif type(world_object) == Food:
+ return "<3"
+ elif type(world_object) == PythonPart:
+ return "##"
+ elif type(world_object) == PythonHead:
+ return "@@"
+
+ def __getitem__(self, row):
+ if row < 0 or row >= self.width:
+ raise IndexError(Exception)
+ return self.world[row]
+
+ def __len__(self):
+ return self.width
+
+
+class WorldObject:
+ pass
+
+
+class Food(WorldObject):
+
+ def __init__(self, energy=0):
+ self.energy = energy
+
+
+class PythonPart(WorldObject):
+ def __init__(self, coords=None):
+ self.coords = coords
+
+
+class PythonHead(PythonPart):
+ pass
+
+
+class Cell:
+
+ def __init__(self, world_object=None):
+ self.contents = world_object
+ if world_object and not isinstance(world_object, WorldObject):
+ raise TypeError(Exception)
+
+ def is_empty(self):
+ return (self.contents is None)
+
+
+class Vec2D(tuple):
+ def __new__(self, x, y):
+ return tuple.__new__(self, (x, y))
+
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+ def __add__(self, other):
+ return Vec2D(self[0] + other[0], self[1] + other[1])
+
+ def __mul__(self, scalar):
+ return Vec2D(self[0]*scalar, self[1]*scalar)
+
+ def __neg__(self):
+ return self*-1
+
+
+class Python:
+
+ LEFT = Vec2D(0, -1)
+ RIGHT = Vec2D(0, 1)
+ UP = Vec2D(-1, 0)
+ DOWN = Vec2D(1, 0)
+
+ def __init__(self, world, coords, size, direction):
+ self.world = world
+ if not self.are_coords_valid(coords):
+ raise Death(Exception)
+
+ self.size = size
+ self.direction = direction
+ self.head = PythonHead(coords)
+ self.world[coords.x][coords.y] = Cell(self.head)
+
+ self.py = [self.head]
+ for i in range(size):
+ py_part_coords = self.py[i].coords+(direction*-1)
+ if not self.are_coords_valid(py_part_coords):
+ raise Death(Exception)
+ py_part = PythonPart(py_part_coords)
+ self.py.append(py_part)
+ self.world[py_part_coords.x][py_part_coords.y] = Cell(py_part)
+
+ def are_coords_valid(self, coords):
+ if ((coords.x < 0) or (coords.y < 0) or
+ (coords.x >= len(self.world)) or
+ (coords.y >= len(self.world)) or
+ (not self.world[coords.x][coords.y].is_empty() and
+ type(self.world[coords.x][coords.y].contents) != Food)):
+ return False
+ return True
+
+ def move(self, direction):
+ if self.direction == -direction:
+ raise Death(Exception)
+
+ self.direction = direction
+ head_new_coords = self.head.coords+direction
+ if not self.are_coords_valid(head_new_coords):
+ raise Death(Exception)
+
+ head_old_coords = self.head.coords
+ new_py_part = PythonPart(Vec2D(head_old_coords.x, head_old_coords.y))
+ self.py.insert(1, new_py_part)
+ self.world[head_old_coords.x][head_old_coords.y] = Cell(new_py_part)
+ contents = self.world[head_new_coords.x][head_new_coords.y].contents
+ if (type(contents) == Food):
+ self.size += 1
+ else:
+ last_part_coords = self.py.pop().coords
+ self.world[last_part_coords.x][last_part_coords.y] = Cell()
+
+ self.head.coords = head_new_coords
+ self.world[head_new_coords.x][head_new_coords.y] = Cell(self.head)
+
+
+class IndexError(Exception):
+ pass
+
+
+class Death(Exception):
+ pass
+1 точка за това, че не съхраняваш празни клетки!
Не си имплементирала изваждане на вектори. Това може да ти струва доста точки.
Ох да, забравила съм го това изискване. Благодаря, че каза.