Деян обнови решението на 10.05.2013 17:50 (преди над 11 години)
+class Vec2D:
+ def __init__(self, x, y):
+ self._x = x
+ self._y = y
+
+ def getx(self):
+ return self._x
+
+ def gety(self):
+ return self._y
+
+ def __add__(self, param):
+ return Vec2D(self._x + param.getx(), self._y + param.gety())
+
+ def __sub__(self, param):
+ return Vec2D(self._x - param.getx(), self._y - param.gety())
+
+ def __mul__(self, number):
+ return Vec2D(self._x * number, self._y * number)
+
+ def __eq__(self, vector):
+ return type(vector) is Vec2D and (self._x, self._y) == vector
+
+ def __iter__(self):
+ return iter([self._x, self._y])
+
+
+class Death(Exception):
+ pass
+
+
+class World:
+ def __init__(self, width):
+ self.width = width
+ self._cells = [[Cell() for y in range(0, width)]
+ for x in range(0, width)]
+
+ def __len__(self):
+ return self.width
+
+ def __getitem__(self, x):
+ if type(x) is Vec2D:
+ if not all(map(lambda n: n in range(0, self.width), x)):
+ raise IndexError
+ return self._cells[x.getx()][x.gety()]
+ if x not in range(0, self.width):
+ raise IndexError
+
+ col = self._cells[x]
+ width = self.width
+
+ # generate a class which modifies this column
+ class WorldColumn:
+ def __getitem__(self, y):
+ if y not in range(0, width):
+ raise IndexError
+ return col[y]
+
+ def __setitem__(self, y, value):
+ if y not in range(0, width):
+ raise IndexError
+ col[y] = value
+
+ return WorldColumn()
+
+ def __setitem__(self, x, value):
+ if x not in range(0, self.width):
+ raise IndexError
+ if type(x) is Vec2D:
+ if not all(map(lambda n: n in range(0, self.width), x)):
+ raise IndexError
+ self._cells[x.getx()][x.gety()] = value
+ else:
+ raise KeyError
+
+
+class Cell:
+ def __init__(self, contents=None):
+ if contents is None or isinstance(contents, (WorldObject, PythonPart)):
+ self.contents = contents
+ else:
+ raise TypeError
+
+ def is_empty(self):
+ return self.contents is None
+
+
+class WorldObject:
+ pass
+
+
+class Food(WorldObject):
+ def __init__(self, energy):
+ self.energy = energy
+
+
+class PythonPart:
+ def __init__(self, python):
+ pass
+
+
+class PythonHead(PythonPart):
+ pass
+
+
+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.coords = coords
+ self.direction = direction
+ self.prev_direction = direction
+ self.energy = 0
+
+ self.head = PythonHead(self)
+ world[coords].contents = self.head
+ self.tail = []
+ for i in range(size, 0, -1):
+ cell = coords - direction * i
+ self.tail.append(cell)
+ world[cell].contents = PythonPart(self)
+
+ def move(self, direction):
+ if direction * (-1) == self.prev_direction:
+ raise ValueError
+
+ self.prev_direction = direction
+ newpos = self.coords + direction
+ try:
+ found = self.world[newpos].contents
+ except IndexError: # hit wall
+ raise Death
+
+ if isinstance(found, PythonPart):
+ raise Death
+ if isinstance(found, Food):
+ self.energy += found.energy
+ else:
+ last_part = self.tail.pop(0)
+ self.world[last_part].contents = None
+ self.world[newpos].contents = self.head # move the head
+ self.world[self.coords].contents = PythonPart(self)
+ self.tail.append(self.coords)
+ self.coords = newpos
Здравей,
Добро решение, но моля те добави отрицание на Vec2D, за да:
>>> Vec2D(1, 1) == -Vec2D(-1, -1)
True
Знам че го нямаше в условието, но чупи един от тестовете, пък и ред 128 ще ти стане по-красив :)
Освен това е по-добре Vec2D да използваш вместо getx(), gety() декораторът @property
. Така ще можеш да пишеш vector.x, а и .x ще бъде immutable.
@property
def x(self)
return self._x