def test_mower_dont_go_out_of_lawn_by_east(self): lawn = (Point(0, 0), Point(0, 0)) mower = Mower(ini_dir=Dir.EAST, ini_pos=Point(0, 0), program=[Cmd.FWD, Cmd.LEFT]) mower.do_next_step(lawn=lawn, others=[]) mower.do_next_step(lawn=lawn, others=[]) self.assertEqual(mower.cur_pos, Point(0, 0)) self.assertEqual(mower.cur_dir, Dir.NORTH)
def test_parser_p2(self): parser = MowerProgramParser(stream=io.StringIO(p2)) self.assertEqual(parser.lawn, (Point(0, 0), Point(5, 5))) self.assertEqual(len(parser.mowers), 2) self.assertEqual(parser.mowers[0].cur_dir, Dir.NORTH) self.assertEqual(parser.mowers[0].cur_pos, Point(1, 2)) self.assertEqual(parser.mowers[1].cur_dir, Dir.EAST) self.assertEqual(parser.mowers[1].cur_pos, Point(3, 3))
def test_mower_do_next_step(self): lawn = (Point(0, 0), Point(9, 9)) mower = Mower(ini_dir=Dir.NORTH, ini_pos=Point(1, 2), program=[Cmd.RIGHT, Cmd.FWD]) mower.do_next_step(lawn=lawn, others=[]) self.assertEqual(mower.cur_pos, Point(1, 2)) self.assertEqual(mower.cur_dir, Dir.EAST) mower.do_next_step(lawn=lawn, others=[]) self.assertEqual(mower.cur_pos, Point(2, 2)) self.assertEqual(mower.cur_dir, Dir.EAST)
def test_lt(self): self.assertLess(Point(1, 1), Point(2, 2)) with self.assertRaises(AssertionError): self.assertLess(Point(1, 2), Point(2, 2)) with self.assertRaises(AssertionError): self.assertLess(Point(2, 1), Point(2, 2)) with self.assertRaises(AssertionError): self.assertLess(Point(2, 2), Point(2, 2))
def __init__(self, stream: io.TextIOBase): self.__mowers = [] stream.seek(0, io.SEEK_SET) cmdlines = stream.readlines() m = LAWN_REGEX.match(cmdlines[0]) if m is None: raise MowerProgramParseError( 'could not parse lawn upper right coords') self.__lawn = (Point(0, 0), Point(int(m.group('x')), int(m.group('y')))) cmdlen = len(cmdlines) - 1 if cmdlen % 2 != 0: raise MowerProgramParseError('odd number of mower lines') for i in range(int(cmdlen / 2)): mi = MOWER_INIT_REGEX.match(cmdlines[i * 2 + 1]) if mi is None: raise MowerProgramParseError( 'could not parse initial position/direction for mower #{}'. format(i)) mp = MOWER_PROGRAM_REGEX.match(cmdlines[i * 2 + 2]) if mp is None: raise MowerProgramParseError( 'could not parse program for mower #{}'.format(i)) ini_pos = Point(int(mi.group('x')), int(mi.group('y'))) if ini_pos >= self.__lawn[1] and ini_pos != self.__lawn[1]: raise MowerProgramParseError( 'initial position for mower #{} can\'t be out of the lawn'. format(i)) if ini_pos in [m.cur_pos for m in self.__mowers]: raise MowerProgramParseError( 'initial position for mower #{} collides with another mower' .format(i)) self.__mowers.append( Mower( ini_pos=ini_pos, ini_dir=Dir(mi.group('dir')), program=[Cmd(x) for x in mp.group('prog')], ))
def test_mower_collide_first_wins(self): lawn = (Point(0, 0), Point(2, 2)) m1 = Mower(ini_dir=Dir.EAST, ini_pos=Point(0, 1), program=[Cmd.FWD]) m2 = Mower(ini_dir=Dir.WEST, ini_pos=Point(2, 1), program=[Cmd.FWD]) m3 = Mower(ini_dir=Dir.SOUTH, ini_pos=Point(1, 2), program=[Cmd.FWD]) m1.do_next_step(lawn=lawn, others=[m2, m3]) m2.do_next_step(lawn=lawn, others=[m1, m3]) m3.do_next_step(lawn=lawn, others=[m1, m2]) self.assertEqual(m1.cur_pos, Point(1, 1)) self.assertEqual(m1.cur_dir, Dir.EAST) self.assertEqual(m2.cur_pos, Point(2, 1)) self.assertEqual(m2.cur_dir, Dir.WEST) self.assertEqual(m3.cur_pos, Point(1, 2)) self.assertEqual(m3.cur_dir, Dir.SOUTH)
def test_mower_str(self): self.assertEqual( str(Mower(ini_dir=Dir.NORTH, ini_pos=Point(1, 2), program=[])), '1 2 N' )
LeftRot = { Dir.NORTH: Dir.WEST, Dir.WEST: Dir.SOUTH, Dir.SOUTH: Dir.EAST, Dir.EAST: Dir.NORTH, } RightRot = { Dir.NORTH: Dir.EAST, Dir.EAST: Dir.SOUTH, Dir.SOUTH: Dir.WEST, Dir.WEST: Dir.NORTH, } FwdMove = { Dir.NORTH: lambda p: Point(p.x, p.y + 1), Dir.WEST: lambda p: Point(p.x - 1, p.y), Dir.SOUTH: lambda p: Point(p.x, p.y - 1), Dir.EAST: lambda p: Point(p.x + 1, p.y), } class Mower: def __init__(self, ini_dir, ini_pos, program): self.__cur_dir = ini_dir self.__cur_pos = ini_pos self.__program = program self.__cur_step = 0 @property def cur_dir(self):
def test_point_with_non_int_coords(self): with self.assertRaises(TypeError): Point(0.1, 0) with self.assertRaises(TypeError): Point('2', 0)
def test_le(self): self.assertLessEqual(Point(1, 1), Point(2, 2)) self.assertLessEqual(Point(1, 2), Point(2, 2)) self.assertLessEqual(Point(2, 1), Point(2, 2)) self.assertLessEqual(Point(2, 2), Point(2, 2))
def test_ge(self): self.assertGreaterEqual(Point(3, 3), Point(2, 2)) self.assertGreaterEqual(Point(3, 2), Point(2, 2)) self.assertGreaterEqual(Point(2, 3), Point(2, 2)) self.assertGreaterEqual(Point(2, 2), Point(2, 2))
def test_gt(self): self.assertGreater(Point(3, 3), Point(2, 2)) self.assertGreater(Point(3, 2), Point(2, 2)) self.assertGreater(Point(2, 3), Point(2, 2)) with self.assertRaises(AssertionError): self.assertGreater(Point(2, 2), Point(2, 2))
def test_not_equal(self): self.assertNotEqual(Point(1, 2), Point(2, 1))
def test_equal(self): self.assertEqual(Point(1, 2), Point(1, 2))
def test_point_with_negative_coords(self): with self.assertRaises(ValueError): Point(-1, 0)
def test_mower(self): Mower(ini_dir=Dir.NORTH, ini_pos=Point(1, 2), program=[Cmd.RIGHT, Cmd.LEFT])
def test_point_without_coords(self): with self.assertRaises(TypeError): Point()
def test_point_with_int_coords(self): p = Point(1, 2) self.assertEqual(p.x, 1) self.assertEqual(p.y, 2)