Advertisement
StefanTodorovski

(Python) AI: Lab 2 - ВИ: Лаб 2

Apr 4th, 2019
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.72 KB | None | 0 0
  1. """
  2. Implement in Python representation of the state about the problem for which, one of the possible initial states is depicted in Figure 1:
  3.  
  4. Figure 1
  5.  
  6. "The stick-man needs to arrive safely to his house. The stick-man can move to any adjacent field horizontally, vertically or diagonally. Obstacles 1, 2 and 3 are moving, with Obstacle 1 moving horizontally, Obstacle 2 moving diagonally, and Obstacle 3 moving vertically. When the stick-man doesn't move the obstacles don't move. With every step (move) the stick-man takes, each of the obstacles also makes a single field movement following its corresponding course and direction. Initially (before any move is made by the stick-man) the movement direction of Obstacle 1 is to the left, of Obstacle 2 is upward-right, and of Obstacle 3 is downward (Figure 2 gives the configuration of the table after the stick-man has moved down from his initial position). When an obstacle hits a wall (the frontier of the table) and can no longer move in its current direction, for the next movement the direction of the obstacle is switched (for example the direction of Obstacle 1 changes from left to right or vice versa). If the stick-man and an obstacle occupy the same field the stick-man is destroyed."
  7.  
  8. Figure 2
  9.  
  10. For all test examples, the look and size of the board are the same as in the images. All test cases have the same initial position and movement direction for the obstacles. Each test case has a different starting position of the man and a different position of the house.
  11.  
  12. The initial code reads the input arguments for each test case. man_row and man_column contain the row and column of the man, house_row and house_column contain the row and column of the house.
  13.  
  14. The movements need to be defined as follows:
  15.  
  16. Desno - move the man right
  17. Levo - move the man left
  18. Gore - move the man up
  19. Dolu - move the man down
  20. Your code should have one call of a function that prints the output on the standard screen output that will print the movement sequence of the man. The movement sequence is the sequence of moves that will allow the man to reach the position of the house. Use uninformed search. Use the test examples to decide which variant of uninformed search to use.
  21. """
  22.  
  23. from utils import Problem
  24. from enum import Enum
  25. from uninformed_search import breadth_first_graph_search
  26.  
  27. # write class definitions after this comment line
  28. class Actions(Enum):
  29.     RIGHT = 1
  30.     LEFT = 2
  31.     UP = 3
  32.     DOWN = 4
  33.  
  34.  
  35. class ObstacleProblem(Problem):
  36.  
  37.     def __init__(self, initial, goal):
  38.         super().__init__(initial, goal)
  39.         self.initial = initial
  40.         self.goal = goal
  41.  
  42.     def goal_test(self, state):
  43.         g = self.goal
  44.         (x, y) = state[0]
  45.         return x == g[0] and y == g[1]
  46.  
  47.     def successor(self, state):
  48.         successors = dict()
  49.  
  50.         move(Actions.RIGHT, state, successors)
  51.         move(Actions.LEFT, state, successors)
  52.         move(Actions.UP, state, successors)
  53.         move(Actions.DOWN, state, successors)
  54.  
  55.         return successors
  56.  
  57.     def actions(self, state):
  58.         return self.successor(state).keys()
  59.  
  60.     def result(self, state, action):
  61.         possible = self.successor(state)
  62.         return possible[action]
  63.  
  64.     def value(self):
  65.         pass
  66.  
  67.  
  68. def move(action, state, successors):
  69.     x, y = state[0]
  70.     o1 = state[1]
  71.     o2 = state[2]
  72.     o3 = state[3]
  73.     o1_new = update_obstacle1(o1)
  74.     o2_new = update_obstacle2(o2)
  75.     o3_new = update_obstacle3(o3)
  76.  
  77.     if action == Actions.RIGHT:
  78.         y = y + 1
  79.         action_done = "Desno"
  80.     elif action == Actions.LEFT:
  81.         y = y - 1
  82.         action_done = "Levo"
  83.     elif action == Actions.UP:
  84.         x = x - 1
  85.         action_done = "Gore"
  86.     elif action == Actions.DOWN:
  87.         x = x + 1
  88.         action_done = "Dolu"
  89.     else: action_done = "Invalid"
  90.  
  91.     if is_valid(x, y, o1_new, o2_new, o3_new):
  92.         new_man_pos = (x, y)
  93.         new_state = (new_man_pos, o1_new, o2_new, o3_new)
  94.         successors[action_done] = new_state
  95.  
  96.  
  97. def update_obstacle1(obstacle):
  98.     x = obstacle[0]
  99.     y = obstacle[1]
  100.     direction = obstacle[2]
  101.  
  102.     if (y == 0 and direction == -1) or (y == 4 and direction == 1):
  103.         direction *= -1
  104.  
  105.     y_new = y + direction
  106.     new_pos = (x, y_new, direction)
  107.     return new_pos
  108.  
  109.  
  110. def update_obstacle2(obstacle):
  111.     x = obstacle[0]
  112.     y = obstacle[1]
  113.     direction = obstacle[2]
  114.  
  115.     if (x == 5 and direction == 1) or (x == 9 and direction == -1):
  116.         direction *= -1
  117.  
  118.     x_new = x - direction
  119.     y_new = y + direction
  120.     new_pos = x_new, y_new, direction
  121.     return new_pos
  122.  
  123.  
  124. def update_obstacle3(obstacle):
  125.     x = obstacle[0]
  126.     y = obstacle[1]
  127.     direction = obstacle[2]
  128.  
  129.     if (x == 5 and direction == 1) or (x == 9 and direction == -1):
  130.         direction *= -1
  131.     x_new = x - direction
  132.     new_pos = x_new, y, direction
  133.     return new_pos
  134.  
  135.  
  136. def is_valid(x, y, o1, o2, o3):
  137.     # Map check
  138.     if x < 0 or y < 0 or x > 10 or y > 10:
  139.         return False
  140.     if y > 5 and x < 5:
  141.         return False
  142.  
  143.     # Obstacle collision check
  144.     if (x == o1[0] and y == o1[1]) or (x == o1[0] and (y == o1[1] + 1)):
  145.         return False
  146.  
  147.     if (x == o2[0] and y == o2[1]) or (x == o2[0] + 1 and y == o2[1]) \
  148.             or (x == o2[0] and y == o2[1] + 1) or (x == o2[0] + 1 and y == o2[1] + 1):
  149.         return False
  150.  
  151.     if (x == o3[0] and y == o3[1]) or (x == o3[0] + 1 and y == o3[1]):
  152.         return False
  153.  
  154.     return True
  155.  
  156.  
  157. if __name__ == '__main__':
  158.     man_row = int(input())
  159.     man_column = int(input())
  160.     house_row = int(input())
  161.     house_column = int(input())
  162.     # continue the code for solving the problem after this comment line
  163.  
  164.     goal_state = (house_row, house_column)
  165.  
  166.     man = (man_row, man_column)
  167.     obstacle1 = (2, 2, -1)  # left
  168.     obstacle2 = (7, 2, 1)  # upward-right
  169.     obstacle3 = (7, 8, -1)  # downward
  170.     initial_state = (man, obstacle1, obstacle2, obstacle3)
  171.     solution_space = ObstacleProblem(initial_state, goal_state)
  172.  
  173.     answer = breadth_first_graph_search(solution_space)
  174.     print(answer.solution())
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183. """
  184. Black or white Problem 2 (0 / 0)
  185. Implement in Python representation of a state about the problem for which one of the possible initial states is depicted in Figure 1:
  186.  
  187. Figure 1
  188.  
  189. "An N x N board consists of white and black fields. When a field is selected (clicked), the color of that field, as well as the color of all of its immediate neighbors (left, right, up, and down), is changed to the opposite one, as shown in Figure 2. The goal is to color all of the board fields in black color. The problem must be solved using the smallest number of moves i.e. by clicking the least possible number of fields."
  190.  
  191. Figure 2
  192.  
  193. For all test examples, the shape of the board is the same as the one in Figure 1. Each test case has a different size N of the board and a different distribution of the black and white fields on it.
  194.  
  195. The initial code reads the input arguments for each test case. n contains the size of the board (number of rows/columns); fields contains the color of each of the fields on the board (in the order: left to right, row by row, considering the board as a matrix), where 1 indicates that the field is colored in black, and 0 indicates that the field is colored in white.
  196.  
  197. The field selections (moves) need to be named as follows:
  198.  
  199. x: row, y: column
  200.  
  201. where row and column are integer values representing the row and column of the selected (clicked) field (considering the board as a matrix).
  202.  
  203. Your code should have one function call that prints the output on the standard screen - it should print the sequence of moves that have to be taken in order to color all the fields on the table in black. Use uninformed search. Use the test examples to decide which variant of uninformed search to use.
  204. """
  205.  
  206. from utils import Problem
  207. from enum import Enum
  208. from uninformed_search import breadth_first_graph_search
  209.  
  210. # write the code for modelling the problem after this comment
  211. class BlackWhiteProblem(Problem):
  212.  
  213.     def __init__(self, initial, goal):
  214.         super().__init__(initial, goal)
  215.         self.initial = initial
  216.         self.goal = goal
  217.  
  218.     def goal_test(self, state):
  219.         g = self.goal
  220.         return g == state
  221.  
  222.     def successor(self, state):
  223.         successors = dict()
  224.  
  225.         for i in range(0, state.__len__()):
  226.             successors["x: " + str(i // n) + ", y: " + str(i % n)] = get_new_state(i, state)
  227.  
  228.         return successors
  229.  
  230.     def actions(self, state):
  231.         return self.successor(state).keys()
  232.  
  233.     def result(self, state, action):
  234.         possible = self.successor(state)
  235.         return possible[action]
  236.  
  237.     def value(self):
  238.         pass
  239.  
  240.  
  241. def invert(num):
  242.     if num == 1:
  243.         num = 0
  244.     else:
  245.         num = 1
  246.     return num
  247.  
  248.  
  249. def get_new_state(pos, state):
  250.     state_list = list(state)
  251.  
  252.     state_list[pos] = invert(state_list[pos])
  253.     size = n*n
  254.  
  255.     if (pos+n) < size:
  256.         state_list[pos+n] = invert(state_list[pos+n])
  257.     if (pos-n) >= 0:
  258.         state_list[pos-n] = invert(state_list[pos-n])
  259.     if (pos+1) < size and (pos % n) != n - 1:
  260.         state_list[pos+1] = invert(state_list[pos+1])
  261.     if (pos-1) >= 0 and (pos % n) != 0:
  262.         state_list[pos-1] = invert(state_list[pos-1])
  263.  
  264.     return tuple(state_list)
  265.  
  266.  
  267. if __name__ == '__main__':
  268.     n = int(input())
  269.     fields = list(map(int, input().split(',')))
  270.     # solve the problem after this comment line
  271.  
  272.     goal_state = []
  273.     for i in range(0, n*n):
  274.         goal_state.append(1)
  275.     goal_state = tuple(goal_state)
  276.  
  277.     initial_state = tuple(fields)
  278.  
  279.     solution_space = BlackWhiteProblem(initial_state, goal_state)
  280.     answer = breadth_first_graph_search(solution_space)
  281.     print(answer.solution())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement