Add test solution for n1 and n2
This commit is contained in:
		
							parent
							
								
									69a4c89e59
								
							
						
					
					
						commit
						279d211d9a
					
				| 
						 | 
				
			
			@ -0,0 +1,268 @@
 | 
			
		|||
import requests
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Cell:
 | 
			
		||||
    def __init__(self, x, y):
 | 
			
		||||
        self.x = x
 | 
			
		||||
        self.y = y
 | 
			
		||||
        self.walls = {'N': None, 'E': None, 'S': None, 'W': None}
 | 
			
		||||
        self.visited = False
 | 
			
		||||
 | 
			
		||||
    def get_wall_code(self):
 | 
			
		||||
        up = self.walls['N']
 | 
			
		||||
        right = self.walls['E']
 | 
			
		||||
        down = self.walls['S']
 | 
			
		||||
        left = self.walls['W']
 | 
			
		||||
        walls = (
 | 
			
		||||
            1 if up else 0,
 | 
			
		||||
            1 if right else 0,
 | 
			
		||||
            1 if down else 0,
 | 
			
		||||
            1 if left else 0
 | 
			
		||||
        )
 | 
			
		||||
        walls_to_code = {
 | 
			
		||||
            (0, 0, 0, 0): 0,
 | 
			
		||||
            (0, 0, 0, 1): 1,
 | 
			
		||||
            (1, 0, 0, 0): 2,
 | 
			
		||||
            (0, 1, 0, 0): 3,
 | 
			
		||||
            (0, 0, 1, 0): 4,
 | 
			
		||||
            (0, 0, 1, 1): 5,
 | 
			
		||||
            (0, 1, 1, 0): 6,
 | 
			
		||||
            (1, 1, 0, 0): 7,
 | 
			
		||||
            (1, 0, 0, 1): 8,
 | 
			
		||||
            (0, 1, 0, 1): 9,
 | 
			
		||||
            (1, 0, 1, 0): 10,
 | 
			
		||||
            (1, 1, 1, 0): 11,
 | 
			
		||||
            (1, 1, 0, 1): 12,
 | 
			
		||||
            (1, 0, 1, 1): 13,
 | 
			
		||||
            (0, 1, 1, 1): 14,
 | 
			
		||||
            (1, 1, 1, 1): 15
 | 
			
		||||
        }
 | 
			
		||||
        return walls_to_code.get(walls, 0)
 | 
			
		||||
 | 
			
		||||
# Класс для представления лабиринта
 | 
			
		||||
class Maze:
 | 
			
		||||
    class ExitDFS(Exception):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.size = 16
 | 
			
		||||
        self.restart()
 | 
			
		||||
        
 | 
			
		||||
    def restart(self):
 | 
			
		||||
        self.grid = [[Cell(x, y) for y in range(self.size)] for x in range(self.size)]
 | 
			
		||||
        self.start_x = 0
 | 
			
		||||
        self.start_y = 0
 | 
			
		||||
 | 
			
		||||
    def get_cell(self, x, y):
 | 
			
		||||
        return self.grid[x][y]
 | 
			
		||||
 | 
			
		||||
    def is_within_bounds(self, x, y):
 | 
			
		||||
        return 0 <= x < self.size and 0 <= y < self.size
 | 
			
		||||
 | 
			
		||||
    def to_array(self):
 | 
			
		||||
        maze_array = []
 | 
			
		||||
        for y in range(self.size - 1, -1, -1):
 | 
			
		||||
            row = []
 | 
			
		||||
            for x in range(self.size):
 | 
			
		||||
                cell = self.get_cell(x, y)
 | 
			
		||||
                row.append(cell.get_wall_code())
 | 
			
		||||
            maze_array.append(row)
 | 
			
		||||
        return maze_array
 | 
			
		||||
 | 
			
		||||
# Класс для управления роботом
 | 
			
		||||
class Robot:
 | 
			
		||||
    def __init__(self, token: str, maze: Maze):
 | 
			
		||||
        self.token = token
 | 
			
		||||
        self.api_url = 'http://127.0.0.1:8801/api/v1'
 | 
			
		||||
        self.maze = maze
 | 
			
		||||
        self.restart()
 | 
			
		||||
 | 
			
		||||
    def restart(self):
 | 
			
		||||
        self.x = self.maze.start_x
 | 
			
		||||
        self.y = self.maze.start_y
 | 
			
		||||
        self.orientation = 'N'  # 'N', 'E', 'S', 'W'
 | 
			
		||||
        self.visited_cells = set()
 | 
			
		||||
        self.move_count = 0
 | 
			
		||||
 | 
			
		||||
    def get_sensor_data(self):
 | 
			
		||||
        response = requests.get(f'{self.api_url}/robot-cells/sensor-data', params={'token': self.token})
 | 
			
		||||
        return response.json()
 | 
			
		||||
 | 
			
		||||
    def move_forward(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/forward', params={'token': self.token})
 | 
			
		||||
        self.update_position('forward')
 | 
			
		||||
 | 
			
		||||
    def turn_left(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/left', params={'token': self.token})
 | 
			
		||||
        self.update_orientation('left')
 | 
			
		||||
 | 
			
		||||
    def turn_right(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/right', params={'token': self.token})
 | 
			
		||||
        self.update_orientation('right')
 | 
			
		||||
 | 
			
		||||
    def move_backward(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/backward', params={'token': self.token})
 | 
			
		||||
        self.update_position('backward')
 | 
			
		||||
 | 
			
		||||
    def update_orientation(self, turn):
 | 
			
		||||
        directions = ['N', 'E', 'S', 'W']
 | 
			
		||||
        idx = directions.index(self.orientation)
 | 
			
		||||
        if turn == 'left':
 | 
			
		||||
            self.orientation = directions[(idx - 1) % 4]
 | 
			
		||||
        elif turn == 'right':
 | 
			
		||||
            self.orientation = directions[(idx + 1) % 4]
 | 
			
		||||
 | 
			
		||||
    def update_position(self, move):
 | 
			
		||||
        dx, dy = 0, 0
 | 
			
		||||
        if self.orientation == 'N':
 | 
			
		||||
            dy = 1 if move == 'forward' else -1
 | 
			
		||||
        elif self.orientation == 'E':
 | 
			
		||||
            dx = 1 if move == 'forward' else -1
 | 
			
		||||
        elif self.orientation == 'S':
 | 
			
		||||
            dy = -1 if move == 'forward' else 1
 | 
			
		||||
        elif self.orientation == 'W':
 | 
			
		||||
            dx = -1 if move == 'forward' else 1
 | 
			
		||||
        self.x += dx
 | 
			
		||||
        self.y += dy
 | 
			
		||||
        self.move_count += 1
 | 
			
		||||
 | 
			
		||||
    def explore(self):
 | 
			
		||||
        try:
 | 
			
		||||
            self._dfs(self.x, self.y)
 | 
			
		||||
        except self.maze.ExitDFS:
 | 
			
		||||
            pass
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def _dfs(self, x, y):
 | 
			
		||||
        if len(self.visited_cells) == self.maze.size ** 2:
 | 
			
		||||
            raise self.maze.ExitDFS()
 | 
			
		||||
        
 | 
			
		||||
        cell = self.maze.get_cell(x, y)
 | 
			
		||||
        cell.visited = True
 | 
			
		||||
        self.visited_cells.add((x, y))
 | 
			
		||||
        sensor_data = self.get_sensor_data()
 | 
			
		||||
        threshold = 100
 | 
			
		||||
 | 
			
		||||
        walls = {}
 | 
			
		||||
        walls[self.orientation_to_dir('N')] = sensor_data['front_distance'] < threshold
 | 
			
		||||
        walls[self.orientation_to_dir('E')] = sensor_data['right_side_distance'] < threshold
 | 
			
		||||
        walls[self.orientation_to_dir('W')] = sensor_data['left_side_distance'] < threshold
 | 
			
		||||
        walls[self.orientation_to_dir('S')] = sensor_data['back_distance'] < threshold
 | 
			
		||||
 | 
			
		||||
        cell.walls.update(walls)
 | 
			
		||||
 | 
			
		||||
        for direction in ['N', 'E', 'S', 'W']:
 | 
			
		||||
            if not cell.walls[direction]:
 | 
			
		||||
                nx, ny = self.get_next_position(x, y, direction)
 | 
			
		||||
                if self.maze.is_within_bounds(nx, ny) and (nx, ny) not in self.visited_cells:
 | 
			
		||||
                    self.move_to(direction)
 | 
			
		||||
                    try:
 | 
			
		||||
                        self._dfs(nx, ny)
 | 
			
		||||
                    except self.maze.ExitDFS as e:
 | 
			
		||||
                        raise e
 | 
			
		||||
                    self.move_to(self.opposite_direction(direction))  # Возвращаемся назад
 | 
			
		||||
 | 
			
		||||
    def get_next_position(self, x, y, direction):
 | 
			
		||||
        dx, dy = 0, 0
 | 
			
		||||
        if direction == 'N':
 | 
			
		||||
            dy = 1
 | 
			
		||||
        elif direction == 'E':
 | 
			
		||||
            dx = 1
 | 
			
		||||
        elif direction == 'S':
 | 
			
		||||
            dy = -1
 | 
			
		||||
        elif direction == 'W':
 | 
			
		||||
            dx = -1
 | 
			
		||||
        return x + dx, y + dy
 | 
			
		||||
 | 
			
		||||
    def move_to(self, direction):
 | 
			
		||||
        turns = self.calculate_turns(self.orientation, direction)
 | 
			
		||||
        for turn in turns:
 | 
			
		||||
            if turn == 'left':
 | 
			
		||||
                self.turn_left()
 | 
			
		||||
            elif turn == 'right':
 | 
			
		||||
                self.turn_right()
 | 
			
		||||
        self.move_forward()
 | 
			
		||||
 | 
			
		||||
    def calculate_turns(self, current_orientation, target_orientation):
 | 
			
		||||
        directions = ['N', 'E', 'S', 'W']
 | 
			
		||||
        idx_current = directions.index(current_orientation)
 | 
			
		||||
        idx_target = directions.index(target_orientation)
 | 
			
		||||
        if idx_current == idx_target:
 | 
			
		||||
            return []
 | 
			
		||||
        elif (idx_current + 1) % 4 == idx_target:
 | 
			
		||||
            return ['right']
 | 
			
		||||
        elif (idx_current - 1) % 4 == idx_target:
 | 
			
		||||
            return ['left']
 | 
			
		||||
        else:
 | 
			
		||||
            return ['left', 'left']
 | 
			
		||||
 | 
			
		||||
    def opposite_direction(self, direction):
 | 
			
		||||
        opposites = {'N': 'S', 'E': 'W', 'S': 'N', 'W': 'E'}
 | 
			
		||||
        return opposites[direction]
 | 
			
		||||
 | 
			
		||||
    def orientation_to_dir(self, relative_direction):
 | 
			
		||||
        directions = ['N', 'E', 'S', 'W']
 | 
			
		||||
        idx = directions.index(self.orientation)
 | 
			
		||||
        if relative_direction == 'N':
 | 
			
		||||
            return directions[idx]
 | 
			
		||||
        elif relative_direction == 'E':
 | 
			
		||||
            return directions[(idx + 1) % 4]
 | 
			
		||||
        elif relative_direction == 'S':
 | 
			
		||||
            return directions[(idx + 2) % 4]
 | 
			
		||||
        elif relative_direction == 'W':
 | 
			
		||||
            return directions[(idx - 1) % 4]
 | 
			
		||||
        
 | 
			
		||||
    def restart_maze(self):
 | 
			
		||||
        response = requests.post(f"{self.api_url}/maze/restart", params={'token': self.token})
 | 
			
		||||
        if response.status_code == 200:
 | 
			
		||||
            print("Лабиринт перезапущен.")
 | 
			
		||||
        else:
 | 
			
		||||
            print(f"Ошибка при перезапуске лабиринта: {response.text}")
 | 
			
		||||
 | 
			
		||||
def restart(robot: Robot, maze: Maze):
 | 
			
		||||
    robot.restart()
 | 
			
		||||
    robot.restart_maze()
 | 
			
		||||
    maze.restart()
 | 
			
		||||
 | 
			
		||||
def start_once(robot: Robot, matrix_check: bool=False, score_check: bool=True):
 | 
			
		||||
    robot.explore()
 | 
			
		||||
    print_results(robot=robot, matrix_check=matrix_check, score_check=score_check)
 | 
			
		||||
    restart(robot=robot, maze=robot.maze)
 | 
			
		||||
 | 
			
		||||
def print_results(robot:Robot, matrix_check: bool=False, score_check: bool=True):
 | 
			
		||||
    maze_array = robot.maze.to_array()
 | 
			
		||||
    if matrix_check:
 | 
			
		||||
        for row in maze_array:
 | 
			
		||||
            print(row)
 | 
			
		||||
 | 
			
		||||
    response = requests.post(
 | 
			
		||||
        f'{robot.api_url}/matrix/send',
 | 
			
		||||
        params={'token': robot.token},
 | 
			
		||||
        json=maze_array
 | 
			
		||||
    )
 | 
			
		||||
    if response.status_code == 200:
 | 
			
		||||
        response_data = response.json()
 | 
			
		||||
        score = response_data.get('Score')
 | 
			
		||||
        if score is not None:
 | 
			
		||||
            print('Отправка матрицы завершена' + f', Score: {score}' * score_check)
 | 
			
		||||
        else:
 | 
			
		||||
            print('Отправка матрицы завершена, но Score отсутствует в ответе:', response_data)
 | 
			
		||||
    else:
 | 
			
		||||
        print('Ошибка при отправке матрицы, статус код:', response.status_code)
 | 
			
		||||
    
 | 
			
		||||
def main(num_att=1):
 | 
			
		||||
    token = 'token'
 | 
			
		||||
    maze = Maze()
 | 
			
		||||
    robot = Robot(token=token, maze=maze)
 | 
			
		||||
    times = time.time()
 | 
			
		||||
    for i in range(num_att):
 | 
			
		||||
        start_time = time.time()
 | 
			
		||||
        print(f'Попытка {i + 1}')
 | 
			
		||||
        start_once(robot=robot)
 | 
			
		||||
        print(f'Время {time.time() - start_time} секунд')
 | 
			
		||||
    print(f'Общее время {time.time() - times} секунд (лимит - {60 * 15})')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main(num_att=3)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,287 @@
 | 
			
		|||
import requests
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
class Cell:
 | 
			
		||||
    def __init__(self, x, y):
 | 
			
		||||
        self.x = x
 | 
			
		||||
        self.y = y
 | 
			
		||||
        self.walls = {'N': None, 'E': None, 'S': None, 'W': None}
 | 
			
		||||
        self.visited = False
 | 
			
		||||
 | 
			
		||||
    def get_wall_code(self):
 | 
			
		||||
        up = self.walls['N']
 | 
			
		||||
        right = self.walls['E']
 | 
			
		||||
        down = self.walls['S']
 | 
			
		||||
        left = self.walls['W']
 | 
			
		||||
        walls = (
 | 
			
		||||
            1 if up else 0,
 | 
			
		||||
            1 if right else 0,
 | 
			
		||||
            1 if down else 0,
 | 
			
		||||
            1 if left else 0
 | 
			
		||||
        )
 | 
			
		||||
        walls_to_code = {
 | 
			
		||||
            (0, 0, 0, 0): 0,
 | 
			
		||||
            (0, 0, 0, 1): 1,
 | 
			
		||||
            (1, 0, 0, 0): 2,
 | 
			
		||||
            (0, 1, 0, 0): 3,
 | 
			
		||||
            (0, 0, 1, 0): 4,
 | 
			
		||||
            (0, 0, 1, 1): 5,
 | 
			
		||||
            (0, 1, 1, 0): 6,
 | 
			
		||||
            (1, 1, 0, 0): 7,
 | 
			
		||||
            (1, 0, 0, 1): 8,
 | 
			
		||||
            (0, 1, 0, 1): 9,
 | 
			
		||||
            (1, 0, 1, 0): 10,
 | 
			
		||||
            (1, 1, 1, 0): 11,
 | 
			
		||||
            (1, 1, 0, 1): 12,
 | 
			
		||||
            (1, 0, 1, 1): 13,
 | 
			
		||||
            (0, 1, 1, 1): 14,
 | 
			
		||||
            (1, 1, 1, 1): 15
 | 
			
		||||
        }
 | 
			
		||||
        return walls_to_code.get(walls, 0)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_center(self):
 | 
			
		||||
        return 7 <= self.x <= 8 and 7 <= self.y <= 8
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Maze:
 | 
			
		||||
    class ExitDFS(Exception):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.size = 16
 | 
			
		||||
        self.restart()
 | 
			
		||||
        
 | 
			
		||||
    def restart(self):
 | 
			
		||||
        self.grid = [[Cell(x, y) for y in range(self.size)] for x in range(self.size)]
 | 
			
		||||
        self.start_x = 0
 | 
			
		||||
        self.start_y = 0
 | 
			
		||||
 | 
			
		||||
    def get_cell(self, x, y):
 | 
			
		||||
        return self.grid[x][y]
 | 
			
		||||
 | 
			
		||||
    def is_within_bounds(self, x, y):
 | 
			
		||||
        return 0 <= x < self.size and 0 <= y < self.size
 | 
			
		||||
 | 
			
		||||
    def to_array(self):
 | 
			
		||||
        maze_array = []
 | 
			
		||||
        for y in range(self.size - 1, -1, -1):
 | 
			
		||||
            row = []
 | 
			
		||||
            for x in range(self.size):
 | 
			
		||||
                cell = self.get_cell(x, y)
 | 
			
		||||
                row.append(cell.get_wall_code())
 | 
			
		||||
            maze_array.append(row)
 | 
			
		||||
        return maze_array
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Robot:
 | 
			
		||||
    def __init__(self, token: str, maze: Maze):
 | 
			
		||||
        self.token = token
 | 
			
		||||
        self.api_url = 'http://127.0.0.1:8801/api/v1'
 | 
			
		||||
        self.maze = maze
 | 
			
		||||
        self.restart()
 | 
			
		||||
 | 
			
		||||
    def restart(self):
 | 
			
		||||
        self.x = self.maze.start_x
 | 
			
		||||
        self.y = self.maze.start_y
 | 
			
		||||
        self.orientation = 'N'  # 'N', 'E', 'S', 'W'
 | 
			
		||||
        self.visited_cells = set()
 | 
			
		||||
        self.move_count = 0
 | 
			
		||||
 | 
			
		||||
    def get_sensor_data(self):
 | 
			
		||||
        response = requests.get(f'{self.api_url}/robot-cells/sensor-data', params={'token': self.token})
 | 
			
		||||
        return response.json()
 | 
			
		||||
 | 
			
		||||
    def move_forward(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/forward', params={'token': self.token})
 | 
			
		||||
        self.update_position('forward')
 | 
			
		||||
 | 
			
		||||
    def turn_left(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/left', params={'token': self.token})
 | 
			
		||||
        self.update_orientation('left')
 | 
			
		||||
 | 
			
		||||
    def turn_right(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/right', params={'token': self.token})
 | 
			
		||||
        self.update_orientation('right')
 | 
			
		||||
 | 
			
		||||
    def move_backward(self):
 | 
			
		||||
        requests.post(f'{self.api_url}/robot-cells/backward', params={'token': self.token})
 | 
			
		||||
        self.update_position('backward')
 | 
			
		||||
 | 
			
		||||
    def update_orientation(self, turn):
 | 
			
		||||
        directions = ['N', 'E', 'S', 'W']
 | 
			
		||||
        idx = directions.index(self.orientation)
 | 
			
		||||
        if turn == 'left':
 | 
			
		||||
            self.orientation = directions[(idx - 1) % 4]
 | 
			
		||||
        elif turn == 'right':
 | 
			
		||||
            self.orientation = directions[(idx + 1) % 4]
 | 
			
		||||
 | 
			
		||||
    def update_position(self, move):
 | 
			
		||||
        dx, dy = 0, 0
 | 
			
		||||
        if self.orientation == 'N':
 | 
			
		||||
            dy = 1 if move == 'forward' else -1
 | 
			
		||||
        elif self.orientation == 'E':
 | 
			
		||||
            dx = 1 if move == 'forward' else -1
 | 
			
		||||
        elif self.orientation == 'S':
 | 
			
		||||
            dy = -1 if move == 'forward' else 1
 | 
			
		||||
        elif self.orientation == 'W':
 | 
			
		||||
            dx = -1 if move == 'forward' else 1
 | 
			
		||||
        self.x += dx
 | 
			
		||||
        self.y += dy
 | 
			
		||||
        self.move_count += 1
 | 
			
		||||
 | 
			
		||||
    def explore(self):
 | 
			
		||||
        try:
 | 
			
		||||
            self._dfs(self.x, self.y)
 | 
			
		||||
        except self.maze.ExitDFS:
 | 
			
		||||
            pass
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def _dfs(self, x, y):
 | 
			
		||||
        cell = self.maze.get_cell(x, y)
 | 
			
		||||
        if cell.is_center:
 | 
			
		||||
            print(f"Робот достиг центра лабиринта на позиции ({x}, {y})")
 | 
			
		||||
            raise self.maze.ExitDFS()
 | 
			
		||||
 | 
			
		||||
        cell.visited = True
 | 
			
		||||
        self.visited_cells.add((x, y))
 | 
			
		||||
        sensor_data = self.get_sensor_data()
 | 
			
		||||
        threshold = 100
 | 
			
		||||
 | 
			
		||||
        walls = {}
 | 
			
		||||
        walls[self.orientation_to_dir('N')] = sensor_data['front_distance'] < threshold
 | 
			
		||||
        walls[self.orientation_to_dir('E')] = sensor_data['right_side_distance'] < threshold
 | 
			
		||||
        walls[self.orientation_to_dir('W')] = sensor_data['left_side_distance'] < threshold
 | 
			
		||||
        walls[self.orientation_to_dir('S')] = sensor_data['back_distance'] < threshold
 | 
			
		||||
 | 
			
		||||
        cell.walls.update(walls)
 | 
			
		||||
 | 
			
		||||
        possible_directions = []
 | 
			
		||||
        for direction in ['N', 'E', 'S', 'W']:
 | 
			
		||||
            if not cell.walls[direction]:
 | 
			
		||||
                nx, ny = self.get_next_position(x, y, direction)
 | 
			
		||||
                if self.maze.is_within_bounds(nx, ny) and (nx, ny) not in self.visited_cells:
 | 
			
		||||
                    possible_directions.append(direction)
 | 
			
		||||
 | 
			
		||||
        possible_directions.sort(key=lambda dir: self.distance_to_center(*self.get_next_position(x, y, dir)))
 | 
			
		||||
 | 
			
		||||
        for direction in possible_directions:
 | 
			
		||||
            nx, ny = self.get_next_position(x, y, direction)
 | 
			
		||||
            self.move_to(direction)
 | 
			
		||||
            try:
 | 
			
		||||
                self._dfs(nx, ny)
 | 
			
		||||
            except self.maze.ExitDFS as e:
 | 
			
		||||
                raise e
 | 
			
		||||
            self.move_to(self.opposite_direction(direction))
 | 
			
		||||
 | 
			
		||||
    def distance_to_center(self, x, y):
 | 
			
		||||
        center_x, center_y = 7.5, 7.5
 | 
			
		||||
        return abs(x - center_x) + abs(y - center_y)
 | 
			
		||||
 | 
			
		||||
    def get_next_position(self, x, y, direction):
 | 
			
		||||
        dx, dy = 0, 0
 | 
			
		||||
        if direction == 'N':
 | 
			
		||||
            dy = 1
 | 
			
		||||
        elif direction == 'E':
 | 
			
		||||
            dx = 1
 | 
			
		||||
        elif direction == 'S':
 | 
			
		||||
            dy = -1
 | 
			
		||||
        elif direction == 'W':
 | 
			
		||||
            dx = -1
 | 
			
		||||
        return x + dx, y + dy
 | 
			
		||||
 | 
			
		||||
    def move_to(self, direction):
 | 
			
		||||
        turns = self.calculate_turns(self.orientation, direction)
 | 
			
		||||
        for turn in turns:
 | 
			
		||||
            if turn == 'left':
 | 
			
		||||
                self.turn_left()
 | 
			
		||||
            elif turn == 'right':
 | 
			
		||||
                self.turn_right()
 | 
			
		||||
        self.move_forward()
 | 
			
		||||
 | 
			
		||||
    def calculate_turns(self, current_orientation, target_orientation):
 | 
			
		||||
        directions = ['N', 'E', 'S', 'W']
 | 
			
		||||
        idx_current = directions.index(current_orientation)
 | 
			
		||||
        idx_target = directions.index(target_orientation)
 | 
			
		||||
        delta = (idx_target - idx_current) % 4
 | 
			
		||||
        if delta == 0:
 | 
			
		||||
            return []
 | 
			
		||||
        elif delta == 1:
 | 
			
		||||
            return ['right']
 | 
			
		||||
        elif delta == 2:
 | 
			
		||||
            return ['right', 'right']
 | 
			
		||||
        elif delta == 3:
 | 
			
		||||
            return ['left']
 | 
			
		||||
 | 
			
		||||
    def opposite_direction(self, direction):
 | 
			
		||||
        opposites = {'N': 'S', 'E': 'W', 'S': 'N', 'W': 'E'}
 | 
			
		||||
        return opposites[direction]
 | 
			
		||||
 | 
			
		||||
    def orientation_to_dir(self, relative_direction):
 | 
			
		||||
        directions = ['N', 'E', 'S', 'W']
 | 
			
		||||
        idx = directions.index(self.orientation)
 | 
			
		||||
        if relative_direction == 'N':
 | 
			
		||||
            return directions[idx]
 | 
			
		||||
        elif relative_direction == 'E':
 | 
			
		||||
            return directions[(idx + 1) % 4]
 | 
			
		||||
        elif relative_direction == 'S':
 | 
			
		||||
            return directions[(idx + 2) % 4]
 | 
			
		||||
        elif relative_direction == 'W':
 | 
			
		||||
            return directions[(idx - 1) % 4]
 | 
			
		||||
        
 | 
			
		||||
    def restart_maze(self):
 | 
			
		||||
        response = requests.post(f"{self.api_url}/maze/restart", params={'token': self.token})
 | 
			
		||||
        if response.status_code == 200:
 | 
			
		||||
            print("Лабиринт перезапущен.")
 | 
			
		||||
        else:
 | 
			
		||||
            print(f"Ошибка при перезапуске лабиринта: {response.text}")
 | 
			
		||||
 | 
			
		||||
def restart(robot: Robot, maze: Maze):
 | 
			
		||||
    robot.restart()
 | 
			
		||||
    robot.restart_maze()
 | 
			
		||||
    maze.restart()
 | 
			
		||||
 | 
			
		||||
def start_once(robot: Robot, matrix_check: bool=False, score_check: bool=True):
 | 
			
		||||
    robot.explore()
 | 
			
		||||
    print_results(robot=robot, matrix_check=matrix_check, score_check=score_check)
 | 
			
		||||
    restart(robot=robot, maze=robot.maze)
 | 
			
		||||
 | 
			
		||||
def print_results(robot: Robot, matrix_check: bool=False, score_check: bool=True):
 | 
			
		||||
    maze_array = robot.maze.to_array()
 | 
			
		||||
    if matrix_check:
 | 
			
		||||
        for row in maze_array:
 | 
			
		||||
            print(row)
 | 
			
		||||
    
 | 
			
		||||
    if not score_check:
 | 
			
		||||
        return
 | 
			
		||||
    
 | 
			
		||||
    response = requests.post(
 | 
			
		||||
        f'{robot.api_url}/matrix/send',
 | 
			
		||||
        params={'token': robot.token},
 | 
			
		||||
        json=maze_array
 | 
			
		||||
    )
 | 
			
		||||
    if response.status_code == 200:
 | 
			
		||||
        response_data = response.json()
 | 
			
		||||
        score = response_data.get('Score')
 | 
			
		||||
        if score is not None:
 | 
			
		||||
            print('Отправка матрицы завершена' + f', Score: {score}')
 | 
			
		||||
        else:
 | 
			
		||||
            print('Отправка матрицы завершена, но Score отсутствует в ответе:', response_data)
 | 
			
		||||
    else:
 | 
			
		||||
        print('Ошибка при отправке матрицы, статус код:', response.status_code)
 | 
			
		||||
    
 | 
			
		||||
def main(num_att=1):
 | 
			
		||||
    token = 'token'
 | 
			
		||||
    maze = Maze()
 | 
			
		||||
    robot = Robot(token=token, maze=maze)
 | 
			
		||||
    times = time.time()
 | 
			
		||||
    for i in range(num_att):
 | 
			
		||||
        start_time = time.time()
 | 
			
		||||
        print(f'Попытка {i + 1}')
 | 
			
		||||
        start_once(robot=robot, score_check=False)
 | 
			
		||||
        print(f'Время {time.time() - start_time} секунд')
 | 
			
		||||
    print(f'Общее время {time.time() - times} секунд (лимит - {60 * 15})')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main(num_att=3)
 | 
			
		||||
		Loading…
	
		Reference in New Issue