def test_str_to_direction_should_parse_correctly_inputs(self): mower1 = Mower(0, 0, 0, 0, 0, 'N', None) mower2 = Mower(0, 0, 0, 0, 0, 'S', None) mower3 = Mower(0, 0, 0, 0, 0, 'E', None) mower4 = Mower(0, 0, 0, 0, 0, 'W', None) self.assertTrue(mower1.direction == Direction.NORTH) self.assertTrue(mower2.direction == Direction.SOUTH) self.assertTrue(mower3.direction == Direction.EAST) self.assertTrue(mower4.direction == Direction.WEST)
def test_move_forward_shoud_not_move_if_on_west_lawn_border(self): mower1 = Mower(0, 0, 5, 5, 5, 'W', None) pos_x_before = mower1.pos_x pos_y_before = mower1.pos_y mower1.move_forward() pos_x_after = mower1.pos_x pos_y_after = mower1.pos_y self.assertEqual(pos_x_before, pos_x_after, 'position x before and after do not match') self.assertEqual(pos_y_before, pos_y_after, 'position y before and after do not match')
def test_rotate_right_should_modify_direction_to_the_right(self): mower1 = Mower(0, 0, 0, 0, 0, 'N', None) self.assertTrue(mower1.direction == Direction.NORTH) mower1.rotate_right() self.assertTrue(mower1.direction == Direction.EAST) mower1.rotate_right() self.assertTrue(mower1.direction == Direction.SOUTH) mower1.rotate_right() self.assertTrue(mower1.direction == Direction.WEST) mower1.rotate_right() self.assertTrue(mower1.direction == Direction.NORTH)
def read_mower_status(line, line_number, up_right): """ Parse a "mower status" line in the input test file (format: "%d %d [NESW]") and returns a mower initial status. :param line: a line holding a mower status in the test file as a string :param line_number: line number in the input file (used in exception to report error) :param up_right: (int, int) tuple ==> grid lawn upper right corner coordinates :return: a tuple as ((int, int), [NESW]) giving a mower status (position, orientation) if no exception occurs """ matcher = re.match(MOWER_STATUS_PATTERN, line) if matcher and len(matcher.groups()) == 3: x = read_integer(matcher, 1, line_number) y = read_integer(matcher, 2, line_number) if x > up_right[0] or y > up_right[1]: raise Exception( 'Error line {}, coordinates should be less or equal than line 1 coordinates' .format(line_number)) else: if Mower.is_valid_orientation(matcher.group(3)): return (x, y), matcher.group(3) else: raise Exception( 'Error line {}, format expected:'.format(line_number) + '"%d %d {one char in N,E,S,W}"') else: raise Exception('Error line {}, format expected:'.format(line_number) + '"%d %d {one char in N,E,S,W}"')
def read_program(line, line_number): """ Parse a mower "program" line in the test file (should be a sequence of valid mower actions (a, G or D) as a string. :param line: line holding the mower program as a string :param line_number: line number in the input file (used in exception to report error) :return: the program as a string if no exception occurs """ for action in line: if not Mower.is_valid_moving_code(action): raise Exception( 'Error line {}: programs should be a sequence matching "[AGD]*"' .format(line_number)) return line
def open(self): """ Open and parse input test file (file_name). :return: A list of tuples (Mower, program) if no exception occurs """ with open(self._filename, 'r') as f: line = read_line(f) Mower.set_up_right_corner(read_grid_up_right_corner(line, 1)) line_number = 1 status = None self._mowers = [] line = read_line(f) while line != '': line_number += 1 if line_number % 2 == 0: status = read_mower_status(line, line_number, Mower.GRID_UP_RIGHT_CORNER) else: program = read_program(line, line_number) self._mowers.append((Mower(status[0], status[1]), program)) line = read_line(f) f.close()
def parse_input_file(file_path): if not path.exists(file_path): print('Input file not found') return f = open(file_path, 'r') content = f.readlines() if len(content) < 3: print('Input file format error: file contains:' + str(len(content)) + ' lines it should at least contains 3 lines ') return f.close # clean data for i in range(len(content)): content[i] = content[i].strip() max_grid = content[0].split(' ') if len(max_grid) != 2: print('unable to read max grid data') return i = 1 id = 1 mowers = [] while i + 1 < len(content): initial_pos = content[i].split(' ') if (len(initial_pos) != 3): print('unable to read mower' + str(id) + ' initial position') else: moves = list(content[i + 1]) m = Mower(id, initial_pos[0], initial_pos[1], max_grid[0], max_grid[1], initial_pos[2], moves) mowers.append(m) i += 2 id += 1 return mowers
def main(mowerNum): lawn = setup(mowerNum) if mowerNum == 0: mower = Mower() else: mower = mowerUser # # draw the initial mower location mowerID = canvas.create_rectangle((mower.getPosition()[0] * SQUARE_W + CORNER_OFFSET), (mower.getPosition()[1] * SQUARE_W + CORNER_OFFSET), (mower.getPosition()[2] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getPosition()[3] * SQUARE_W + CORNER_OFFSET + SQUARE_W), fill="red") mowerTriID = canvas.create_polygon((mower.getTriangle()[0] * SQUARE_W + CORNER_OFFSET), (mower.getTriangle()[1] * SQUARE_W + CORNER_OFFSET), (mower.getTriangle()[2] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getTriangle()[3] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getTriangle()[4] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getTriangle()[5] * SQUARE_W + CORNER_OFFSET + SQUARE_W), outline='black', fill='black', width=0) # drawMower(mower) # tk0.mainloop() lawn = mower.updateLawn(lawn) while not mower.isDone(lawn): # while 2 in lawn[:, :]: tk.update_idletasks() tk.update() # do stuff canvas.delete(mowerID) canvas.delete(mowerTriID) lawn = mower.updateLawn(lawn) mower.makeMove(lawn) # update lawn: for ix, iy in np.ndindex(lawn.shape): if lawn[ix][iy] == 2: canvas.create_rectangle((iy * SQUARE_W + CORNER_OFFSET), (ix * SQUARE_W + CORNER_OFFSET), (iy * SQUARE_W + CORNER_OFFSET + SQUARE_W), (ix * SQUARE_W + CORNER_OFFSET + SQUARE_W), fill=initColor) if lawn[ix][iy] == 4: canvas.create_rectangle((iy * SQUARE_W + CORNER_OFFSET), (ix * SQUARE_W + CORNER_OFFSET), (iy * SQUARE_W + CORNER_OFFSET + SQUARE_W), (ix * SQUARE_W + CORNER_OFFSET + SQUARE_W), fill="white") if lawn[ix][iy] == 1: canvas.create_rectangle((iy * SQUARE_W + CORNER_OFFSET), (ix * SQUARE_W + CORNER_OFFSET), (iy * SQUARE_W + CORNER_OFFSET + SQUARE_W), (ix * SQUARE_W + CORNER_OFFSET + SQUARE_W), fill=mowedColor) mowerID = canvas.create_rectangle((mower.getPosition()[0] * SQUARE_W + CORNER_OFFSET), (mower.getPosition()[1] * SQUARE_W + CORNER_OFFSET), (mower.getPosition()[2] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getPosition()[3] * SQUARE_W + CORNER_OFFSET + SQUARE_W), fill="red") mowerTriID = canvas.create_polygon((mower.getTriangle()[0] * SQUARE_W + CORNER_OFFSET), (mower.getTriangle()[1] * SQUARE_W + CORNER_OFFSET), (mower.getTriangle()[2] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getTriangle()[3] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getTriangle()[4] * SQUARE_W + CORNER_OFFSET + SQUARE_W), (mower.getTriangle()[5] * SQUARE_W + CORNER_OFFSET + SQUARE_W), outline='black', fill='black', width=0)
import argparse from tkinter import * import time import numpy as np from mower import Mower_User from mower import Mower tk = Tk() canvas = Canvas(tk, width=500, height=400) MAX_WIDTH = 20 MAX_HEIGHT = 30 homeTL = [-1, -1] mowerUser = Mower() # Change this to switch between user and AI CORNER_OFFSET = 5 tl_x = CORNER_OFFSET tl_y = CORNER_OFFSET SQUARE_W = 20 mowedColor = '#%02x%02x%02x' % (41, 138, 10) initColor = '#%02x%02x%02x' % (48, 220, 0) fwd = 0 back = 1 left = 2 right = 3 diagL = 4 diagR = 5 def setup(mowerNum): initlawn = np.zeros([MAX_HEIGHT * 2, MAX_WIDTH * 2])
from lawn import Lawn from mower import Mower lawn = Lawn(width=5, length=5) lawn.render_grid() mower1 = Mower(position=[1, 2], orientation="N", directions=list("LFLFLFLFF"), lawn=lawn) mower2 = Mower(position=[3, 3], orientation="E", directions=list("FFRFFRFRRF"), lawn=lawn) mower1.move() print(f"final mower1 position: {mower1.get_position()}") print(f"final mower1 orientation: {mower1.get_orientation()}") mower2.move() print(f"final mower2 position: {mower2.get_position()}") print(f"final mower2 orientation: {mower2.get_orientation()}")
from state import State from mower import Mower from reader import reader if __name__ == '__main__': settings = reader("setting_file.txt") initial_states = [] mowers = [] for s in settings: initial_state = State(x=s["x_ini"], y=s["y_ini"], orientation=s["orientation_ini"], x_max=s["x_max"], y_max=s["y_max"]) mowers.append( Mower(state=initial_state, instructions=s["instructions"], name=s["name"])) objective_states = ["13W", "25N"] for m, mower in enumerate(mowers): mower.sequence_move() assert str( mower.state) == objective_states[m], \ "wrong state %r, should be %r" % mower.name % objective_states[m] print("passed test for", mower.name)
def test_str_to_direction_should_return_unknown(self): mower = Mower(0, 0, 0, 0, 0, '@', None) self.assertTrue(mower.direction == Direction.UNKNOWN)
def test_str_to_direction_should_not_be_case_sensitive(self): mower1 = Mower(0, 0, 0, 0, 0, 'N', None) mower2 = Mower(0, 0, 0, 0, 0, 'n', None) self.assertTrue(mower1.direction == Direction.NORTH) self.assertTrue(mower2.direction == Direction.NORTH)