-
Notifications
You must be signed in to change notification settings - Fork 0
/
defense_robots.py
172 lines (130 loc) · 4.97 KB
/
defense_robots.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
"""
Ejercicio: Robots defensivos secretos.
Se poseen dos robots para custodiar un centro de investigación secreto. Los robots
permanecen almacenados en espera, y frente a alguna emergencia deben reaccionar
ubicándose en posiciones defensivas. El centro de investigación posee habitaciones en
forma de grilla, pero algunas de ellas no son accesibles para los robots, por riesgo de
contaminación. Los robots sólo pueden moverse entre habitaciones adyacentes.
Se debe resolver la “puesta en defensiva” como un problema de búsqueda, con el objetivo
de encontrar el camino más óptimo.
------+-----+-----+-----+-----+
| |R1 R2| X | | O |
------+-----+-----+-----+-----+
| | | | X | |
------+-----+-----+-----+-----+
| | X | | | |
------+-----+-----+-----+-----+
| | | O | | |
------+-----+-----+-----+-----+
R1: Robot1
R2: Robot2
X: Habitación no accesible por los Robots
O: Ubicación objetivo
"""
from itertools import product
from simpleai.search import SearchProblem, breadth_first, depth_first, uniform_cost
from simpleai.search.viewers import WebViewer, ConsoleViewer
INITIAL_STATE = (
(0, 1), # Position of first robot
(0, 1), # Position of second robot
)
RESTRICTED_AREAS = {
(0, 2),
(1, 3),
(2, 1),
}
OBJECTIVE_AREAS = {
(0, 4),
(3, 2),
}
ROWS = 4
COLUMNS = 5
class DefenseRobots(SearchProblem):
def is_goal(self, state):
# in sets the elements doesn't have order so this works for any robot to be
# in any objective.
# return set(state) == OBJECTIVE_AREAS
# This other solution is a bit larger and less efficient but it can be more
# explicit
for objective in OBJECTIVE_AREAS:
if objective not in state:
return False
return True
def _get_adjacent_positions(self, position):
row, column = position
all_adjacent_positions = [
(row, column - 1), # move to the left
(row, column + 1), # move to the right
(row - 1, column), # move up
(row + 1, column), # move down
]
valid_adjacent_positions = [
position for position in all_adjacent_positions
if -1 not in position
and position[0] < ROWS
and position[1] < COLUMNS
]
return valid_adjacent_positions
def actions(self, state):
actions_for_each_robot = []
reached_obj = []
for robot_position in state:
if robot_position in OBJECTIVE_AREAS and robot_position not in reached_obj:
# don't move the robot if it is the first to arrive to an objective area
robot_actions = [robot_position]
reached_obj.append(robot_position)
else:
robot_actions = [
position
for position in self._get_adjacent_positions(robot_position)
if position not in RESTRICTED_AREAS
]
actions_for_each_robot.append(robot_actions)
return product(*actions_for_each_robot)
def result(self, state, action):
return action
def cost(self, state1, action, state2):
movements = 0
for robot, original_position in enumerate(state1):
if state2[robot] != original_position:
movements += 1
return movements
def cost2(self, state1, action, state2):
movement_costs = [
1
for original_position, final_position
in zip(state1, state2)
if original_position != final_position
]
return sum(movement_costs)
def print_state_representation(self, state):
robot = "R"
restricted_area = "X"
objective_area = "O"
matrix = []
position_size = 5
for row in range(ROWS):
row_elements = []
for column in range(COLUMNS):
position = (row, column)
elements_in_position = []
for robot_position in state:
if robot_position == position:
elements_in_position.append(robot)
if position in RESTRICTED_AREAS:
elements_in_position.append(restricted_area)
if position in OBJECTIVE_AREAS:
elements_in_position.append(objective_area)
row_elements.append(elements_in_position)
matrix.append(row_elements)
row_separation = "\n" + ("+" + ("-" * position_size)) * COLUMNS + "+" + "\n"
column_separation = "|"
representation = row_separation
for row in matrix:
representation += column_separation
for position in row:
elements = "".join(position).center(position_size)
representation += elements + column_separation
representation += row_separation
print(representation)
# return representation