Вероника обнови решението на 14.05.2013 01:07 (преди над 11 години)
+from collections import defaultdict
+
+
+class IndexError(Exception):
+ pass
+
+
+class Death(Exception):
+ pass
+
+
+class Vec2D(tuple):
+
+ def __new__(cls, *args):
+ return tuple.__new__(cls, args)
+
+ def __add__(self, other):
+ return Vec2D(self[0] + other[0], self[1] + other[1])
+
+ def __sub__(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.__mul__(-1)
+
+
+class Cell():
+
+ contents = None
+
+ def __init__(*args):
+ if len(args) == 2:
+ if isinstance(args[1], WorldObject):
+ args[0].contents = args[1]
+ else:
+ raise TypeError("")
+
+ def is_empty(self):
+ return self.contents is None
+
+
+class IndexedDict():
+
+ def __init__(self, width):
+ self.width = width
+ self.row = defaultdict(lambda: Cell())
+
+ def __getitem__(self, index):
+ if (index < 0) or (index >= self.width):
+ raise IndexError('Index out of board!')
+ else:
+ return self.row[index]
+
+
+class World():
+
+ def __init__(self, width):
+ self.width = width
+ self.board = defaultdict(lambda: IndexedDict(width))
+
+ def __len__(self):
+ return self.width
+
+ def __getitem__(self, index):
+ if (index < 0) or (index >= self.width):
+ raise IndexError('Index out of board!')
+ else:
+ return self.board[index]
+
+
+class WorldObject():
+ pass
+
+
+class Food(WorldObject):
+ def __init__(self, energy):
+ self.energy = energy
+ energy = 0
+
+
+class PythonPart(WorldObject):
+ def __init__(self, x_coordinate, y_coordinate):
+ self.x_coordinate = x_coordinate
+ self.y_coordinate = y_coordinate
+
+
+class PythonHead(PythonPart):
+ pass
+
+
+class Python():
+
+ size_ = 0
+
+ DOWN = Vec2D(-1, 0)
+ UP = Vec2D(1, 0)
+ LEFT = Vec2D(0, -1)
+ RIGHT = Vec2D(0, 1)
+
+ def __init__(self, world, coords, size, direction):
+ self.world = world
+ self.head = PythonHead(coords[0], coords[1])
+ self.world[coords[0]][coords[1]].contents = self.head
+ self.size = size
+ self.parts_coordinates = []
+ self.direction = direction
+ self.energy = 0
+
+ for part in range(1, size+1):
+ new_x = coords[0] - direction[0] * part
+ new_y = coords[1] - direction[1] * part
+ self.world[new_x][new_y].contents = PythonPart(new_x, new_y)
+ self.world[10][11].contents = PythonPart(11, 10)
+ self.parts_coordinates.append((new_x, new_y))
+
+ def move(self, direction):
+ old_x = self.head.x_coordinate
+ old_y = self.head.y_coordinate
+ new_x = old_x + direction[0]
+ new_y = old_y + direction[1]
+
+ if (new_y < 0 or new_y < 0 or (new_x > self.world.width or
+ new_y > self.world.width)):
+ raise Death("You die in pain")
+
+ if self.world[new_x][new_y].is_empty() is False:
+ if isinstance(self.world[new_x][new_y].contents, Food) is False:
+ raise Death("You die in pain")
+ else:
+ self.energy += world[new_x][new_y].contents.energy
+ self.size += 1
+ len_ = len(parts_coordinates)
+ self.parts_coordinates += [self.parts_coordinates[len_-1]]
+
+ py_head = self.world[old_x][old_y].contents
+ py_head.x_coordinate = new_x
+ py_head.y_coordinate = new_y
+ self.world[new_x][new_y].contents = py_head
+
+ self.world[old_x][old_y].contents = PythonPart(old_x, old_y)
+
+ self.parts_coordinates = [(old_x, old_y)] + self.parts_coordinates
+ len_ = len(self.parts_coordinates)
+ last_part_coords = self.parts_coordinates.pop(len_-1)
+ self.world[last_part_coords[0]][last_part_coords[1]].contents = None
+
+ length = len(self.parts_coordinates)
+ coordinates = self.parts_coordinates
+ for i in range(0, length-1):
+ coord1 = coordinates[length-1-i][0]
+ coord2 = coordinates[length-1-i][0]
+ py_part = self.world[coord1][coord2]
+ self.world[old_x][old_y].contents = py_part
+ old_x, old_y = coord1, coord2
IndexedDict не ти позволява да правиш такива неща в момента: world[row][col] = Cell(Food(energy=5))
което ще ти струва много точки ако не го оправиш.