| … | … | @@ -9,6 +9,7 @@ import math |
| 9 | 9 | import signal |
| 10 | 10 | from contextlib import contextmanager |
| 11 | 11 | |
| 12 | |
| 12 | 13 | @contextmanager |
| 13 | 14 | def timeout(time): |
| 14 | 15 | # Register a function to raise a TimeoutError on the signal. |
| … | … | @@ -24,180 +25,254 @@ def timeout(time): |
| 24 | 25 | # if the timeout is not reached. |
| 25 | 26 | signal.signal(signal.SIGALRM, signal.SIG_IGN) |
| 26 | 27 | |
| 28 | |
| 27 | 29 | def raise_timeout(signum, frame): |
| 28 | 30 | raise TimeoutError |
| 29 | 31 | |
| 32 | |
| 30 | 33 | def drawBlock(x, y, z, type): |
| 31 | 34 | return """<DrawBlock x='{0}' y='{1}' z='{2}' type='{3}'/>""".format(x, y, z, type) |
| 32 | 35 | |
| 36 | |
| 33 | 37 | def GenCuboid(x1, y1, z1, x2, y2, z2, blocktype): |
| 34 | | return '<DrawCuboid x1="' + str(x1) + '" y1="' + str(y1) + '" z1="' + str(z1) + '" x2="' + str(x2) + '" y2="' + str(y2) + '" z2="' + str(z2) + '" type="' + blocktype + '"/>' |
| 38 | return ( |
| 39 | '<DrawCuboid x1="' |
| 40 | + str(x1) |
| 41 | + '" y1="' |
| 42 | + str(y1) |
| 43 | + '" z1="' |
| 44 | + str(z1) |
| 45 | + '" x2="' |
| 46 | + str(x2) |
| 47 | + '" y2="' |
| 48 | + str(y2) |
| 49 | + '" z2="' |
| 50 | + str(z2) |
| 51 | + '" type="' |
| 52 | + blocktype |
| 53 | + '"/>' |
| 54 | ) |
| 55 | |
| 35 | 56 | |
| 36 | 57 | def drawLine(x1, y1, z1, x2, y2, z2, blocktype, face): |
| 37 | | return '<DrawLine x1="' + str(x1) + '" y1="' + str(y1) + '" z1="' + str(z1) + '" x2="' + str(x2) + '" y2="' + str(y2) + '" z2="' + str(z2) + '" type="' + blocktype + '" face="' + face +'"/>' |
| 58 | return ( |
| 59 | '<DrawLine x1="' |
| 60 | + str(x1) |
| 61 | + '" y1="' |
| 62 | + str(y1) |
| 63 | + '" z1="' |
| 64 | + str(z1) |
| 65 | + '" x2="' |
| 66 | + str(x2) |
| 67 | + '" y2="' |
| 68 | + str(y2) |
| 69 | + '" z2="' |
| 70 | + str(z2) |
| 71 | + '" type="' |
| 72 | + blocktype |
| 73 | + '" face="' |
| 74 | + face |
| 75 | + '"/>' |
| 76 | ) |
| 77 | |
| 38 | 78 | |
| 39 | 79 | def build_house(x, y, z, width, length, height, blocktype): |
| 40 | 80 | x_front = x |
| 41 | | x_back = x + length if x >= 0 else x-length |
| 42 | | z_left = z + width if z >= 0 else z-width |
| 81 | x_back = x + length if x >= 0 else x - length |
| 82 | z_left = z + width if z >= 0 else z - width |
| 43 | 83 | z_right = z |
| 44 | 84 | |
| 45 | 85 | genstring = "" |
| 46 | 86 | y_cur = y |
| 47 | 87 | for i in range(height): |
| 48 | | z_cur = z |
| 49 | | x_cur = x |
| 50 | | for j in range(width): |
| 51 | | genstring = genstring + drawBlock(x_front, y_cur, z_cur, "glass") + "\n" |
| 52 | | genstring = genstring + drawBlock(x_back, y_cur, z_cur, "diamond_block") + "\n" |
| 53 | | genstring = genstring + drawBlock(x_back-1, y_cur, z_cur, blocktype) + "\n" |
| 54 | | z_cur = z_cur + 1 if z_cur >= 0 else z_cur-1 |
| 55 | | |
| 56 | | for k in range(length): |
| 57 | | if k % 2 == 0: |
| 58 | | genstring = genstring + drawBlock(x_cur, y_cur, z_left, "glass") + "\n" |
| 59 | | genstring = genstring + drawBlock(x_cur, y_cur, z_right, "glass") + "\n" |
| 60 | | else: |
| 61 | | genstring = genstring + drawBlock(x_cur, y_cur, z_left, blocktype) + "\n" |
| 62 | | genstring = genstring + drawBlock(x_cur, y_cur, z_right, blocktype) + "\n" |
| 63 | | x_cur = x_cur + 1 if x_cur >= 0 else x_cur-1 |
| 88 | z_cur = z |
| 89 | x_cur = x |
| 90 | for j in range(width): |
| 91 | genstring = genstring + drawBlock(x_front, y_cur, z_cur, "glass") + "\n" |
| 92 | genstring = ( |
| 93 | genstring + drawBlock(x_back, y_cur, z_cur, "diamond_block") + "\n" |
| 94 | ) |
| 95 | genstring = ( |
| 96 | genstring + drawBlock(x_back - 1, y_cur, z_cur, blocktype) + "\n" |
| 97 | ) |
| 98 | z_cur = z_cur + 1 if z_cur >= 0 else z_cur - 1 |
| 99 | |
| 100 | for k in range(length): |
| 101 | if k % 2 == 0: |
| 102 | genstring = genstring + drawBlock(x_cur, y_cur, z_left, "glass") + "\n" |
| 103 | genstring = genstring + drawBlock(x_cur, y_cur, z_right, "glass") + "\n" |
| 104 | else: |
| 105 | genstring = ( |
| 106 | genstring + drawBlock(x_cur, y_cur, z_left, blocktype) + "\n" |
| 107 | ) |
| 108 | genstring = ( |
| 109 | genstring + drawBlock(x_cur, y_cur, z_right, blocktype) + "\n" |
| 110 | ) |
| 111 | x_cur = x_cur + 1 if x_cur >= 0 else x_cur - 1 |
| 112 | |
| 113 | y_cur = y_cur + 1 if y_cur >= 0 else y_cur - 1 |
| 64 | 114 | |
| 65 | | y_cur = y_cur + 1 if y_cur >= 0 else y_cur-1 |
| 66 | | |
| 67 | 115 | # floor |
| 68 | | genstring = genstring + GenCuboid(x_back + 1 if x_back >= 0 else x_back - 1, y, z_left + 1 if z_left >= 0 else z_left - 1, x - 1 if x >= 0 else x + 1, y, z - 1 if x >= 0 else z + 1, blocktype ) |
| 116 | genstring = genstring + GenCuboid( |
| 117 | x_back + 1 if x_back >= 0 else x_back - 1, |
| 118 | y, |
| 119 | z_left + 1 if z_left >= 0 else z_left - 1, |
| 120 | x - 1 if x >= 0 else x + 1, |
| 121 | y, |
| 122 | z - 1 if x >= 0 else z + 1, |
| 123 | blocktype, |
| 124 | ) |
| 69 | 125 | # ceiling |
| 70 | | genstring = genstring + GenCuboid(x_back + 1 if x_back >= 0 else x_back - 1, y_cur, z_left + 1 if z_left >= 0 else z_left - 1, x - 1 if x >= 0 else x + 1, y_cur, z - 1 if x >= 0 else z + 1, blocktype ) |
| 71 | | |
| 126 | genstring = genstring + GenCuboid( |
| 127 | x_back + 1 if x_back >= 0 else x_back - 1, |
| 128 | y_cur, |
| 129 | z_left + 1 if z_left >= 0 else z_left - 1, |
| 130 | x - 1 if x >= 0 else x + 1, |
| 131 | y_cur, |
| 132 | z - 1 if x >= 0 else z + 1, |
| 133 | blocktype, |
| 134 | ) |
| 135 | |
| 72 | 136 | return genstring |
| 73 | 137 | |
| 74 | | # Initialize the location coordinates |
| 138 | |
| 139 | # Initialize the location coordinates |
| 75 | 140 | agent_x, agent_y, agent_z, agent_yaw = 19, 230, -2, 90 |
| 76 | 141 | key_x, key_y, key_z = 7, 228, -10 |
| 77 | 142 | door_x, door_y, door_z = -4, 228, -3 |
| 78 | 143 | diamond_x, diamond_y, diamond_z = -18, 228, -3 |
| 79 | | start_x, start_y, start_z, width, length, height = -4, 226, -1,6,15,5 |
| 144 | start_x, start_y, start_z, width, length, height = -4, 226, -1, 6, 15, 5 |
| 80 | 145 | holds_key = False |
| 81 | 146 | |
| 82 | | # relocates the agent to the starting point |
| 147 | # relocates the agent to the starting point |
| 83 | 148 | def relocate_agent(agent): |
| 84 | | print("Agent relocated to original place") |
| 85 | | agent.sendCommand("tp {} {} {}".format(agent_x, agent_y, agent_z)) |
| 86 | | agent.sendCommand("setYaw {}".format(agent_yaw)) |
| 87 | | time.sleep(0.2) |
| 149 | print("Agent relocated to original place") |
| 150 | agent.sendCommand("tp {} {} {}".format(agent_x, agent_y, agent_z)) |
| 151 | agent.sendCommand("setYaw {}".format(agent_yaw)) |
| 152 | time.sleep(0.2) |
| 153 | |
| 88 | 154 | |
| 89 | | # stop the agent |
| 155 | # stop the agent |
| 90 | 156 | def stop_condition(agent, blocktype, sec=10): |
| 91 | | print("Moving to the {}".format(blocktype)) |
| 92 | | def stop(agent, blocktype): |
| 93 | | done = False |
| 157 | print("Moving to the {}".format(blocktype)) |
| 158 | |
| 159 | def stop(agent, blocktype): |
| 160 | done = False |
| 161 | world_state = agent.peekWorldState() |
| 162 | while not done: |
| 163 | world_state = agent.peekWorldState() |
| 164 | if world_state.number_of_observations_since_last_state > 0: |
| 165 | ob = json.loads(world_state.observations[-1].text) |
| 166 | if blocktype in ob["BlocksInFront"]: |
| 167 | print("reached at {}".format(blocktype)) |
| 168 | agent.sendCommand("move 0") |
| 169 | done = True |
| 170 | |
| 171 | with timeout(sec): |
| 172 | try: |
| 173 | stop(agent, blocktype) |
| 174 | return True |
| 175 | except TimeoutError: |
| 176 | print("*********** Time out **************") |
| 177 | agent.sendCommand("move 0") |
| 178 | relocate_agent(agent) |
| 179 | return False |
| 180 | |
| 181 | |
| 182 | # Get realtime location coordinates |
| 183 | def get_curr_loc(agent): |
| 184 | loc = (agent_x, agent_y, agent_z) |
| 94 | 185 | world_state = agent.peekWorldState() |
| 95 | | while not done: |
| 96 | | world_state = agent.peekWorldState() |
| 97 | | if world_state.number_of_observations_since_last_state > 0: |
| 186 | # while world_state.is_mission_running: |
| 187 | # world_state = agent.peekWorldState() |
| 188 | if world_state.number_of_observations_since_last_state > 0: |
| 98 | 189 | ob = json.loads(world_state.observations[-1].text) |
| 99 | | if blocktype in ob["BlocksInFront"]: |
| 100 | | print("reached at {}".format(blocktype)) |
| 101 | | agent.sendCommand("move 0") |
| 102 | | done = True |
| 103 | | |
| 104 | | with timeout(sec): |
| 105 | | try: |
| 106 | | stop(agent, blocktype) |
| 107 | | return True |
| 108 | | except TimeoutError: |
| 109 | | print("*********** Time out **************") |
| 110 | | agent.sendCommand("move 0") |
| 111 | | relocate_agent(agent) |
| 112 | | return False |
| 190 | loc = (int(ob[u"XPos"]), int(ob[u"YPos"]), int(ob[u"ZPos"])) |
| 113 | 191 | |
| 114 | | # Get realtime location coordinates |
| 115 | | def get_curr_loc(agent): |
| 116 | | loc = (agent_x, agent_y, agent_z) |
| 117 | | world_state = agent.peekWorldState() |
| 118 | | # while world_state.is_mission_running: |
| 119 | | # world_state = agent.peekWorldState() |
| 120 | | if world_state.number_of_observations_since_last_state > 0: |
| 121 | | ob = json.loads(world_state.observations[-1].text) |
| 122 | | loc = (int(ob[u'XPos']), int(ob[u'YPos']), int(ob[u'ZPos'])) |
| 123 | | |
| 124 | | return loc |
| 125 | | |
| 126 | | # Turns the agent towards the location given |
| 192 | return loc |
| 193 | |
| 194 | |
| 195 | # Turns the agent towards the location given |
| 127 | 196 | def turn_to(agent, x1, y1, z1, x2, y2, z2): |
| 128 | | def get_angle(x1, y1, z1, x2, y2, z2): |
| 129 | | x_dist = abs(x1 - x2) |
| 130 | | z_dist = abs(z1 - z2) |
| 131 | | h = math.sqrt(x_dist**2 + z_dist**2) |
| 132 | | return math.degrees(z_dist/h) if h != 0 else 0 |
| 133 | | |
| 134 | | angle = get_angle(x1, y1, z1, x2, y2, z2) |
| 135 | | yaw = 90 if x1 > x2 else -90 |
| 136 | | if yaw > 0: |
| 137 | | angle = yaw - angle if z1 < z2 else yaw + angle |
| 138 | | else: |
| 139 | | angle = yaw + angle if z1 < z2 else yaw - angle |
| 140 | | agent.sendCommand("setYaw {}".format(angle)) |
| 197 | def get_angle(x1, y1, z1, x2, y2, z2): |
| 198 | x_dist = abs(x1 - x2) |
| 199 | z_dist = abs(z1 - z2) |
| 200 | h = math.sqrt(x_dist ** 2 + z_dist ** 2) |
| 201 | return math.degrees(z_dist / h) if h != 0 else 0 |
| 202 | |
| 203 | angle = get_angle(x1, y1, z1, x2, y2, z2) |
| 204 | yaw = 90 if x1 > x2 else -90 |
| 205 | if yaw > 0: |
| 206 | angle = yaw - angle if z1 < z2 else yaw + angle |
| 207 | else: |
| 208 | angle = yaw + angle if z1 < z2 else yaw - angle |
| 209 | agent.sendCommand("setYaw {}".format(angle)) |
| 210 | |
| 141 | 211 | |
| 142 | 212 | def is_mission_running(agent): |
| 143 | | world_state = agent.peekWorldState() |
| 144 | | return world_state.is_mission_running |
| 213 | world_state = agent.peekWorldState() |
| 214 | return world_state.is_mission_running |
| 215 | |
| 145 | 216 | |
| 146 | 217 | # Move the agent towards the key |
| 147 | | # reward=0 |
| 218 | # reward=0 |
| 148 | 219 | def go_to_the_key(agent): |
| 149 | | global holds_key |
| 150 | | curr_x, curr_y, curr_z = get_curr_loc(agent) |
| 151 | | turn_to(agent,curr_x, curr_y, curr_z, key_x, key_y, key_z) |
| 152 | | time.sleep(0.2) |
| 153 | | agent.sendCommand("move 1") |
| 154 | | action_complete = stop_condition(agent, 'tripwire_hook') |
| 155 | | if action_complete: |
| 156 | | agent.sendCommand("hotbar.2 1") |
| 157 | | observation = {"observation":["holds_key"]} |
| 158 | | holds_key = True |
| 159 | | else: |
| 160 | | observation = [] |
| 161 | | reward = 0 |
| 162 | | return observation, reward, is_mission_running |
| 220 | global holds_key |
| 221 | curr_x, curr_y, curr_z = get_curr_loc(agent) |
| 222 | turn_to(agent, curr_x, curr_y, curr_z, key_x, key_y, key_z) |
| 223 | time.sleep(0.2) |
| 224 | agent.sendCommand("move 1") |
| 225 | action_complete = stop_condition(agent, "tripwire_hook") |
| 226 | if action_complete: |
| 227 | agent.sendCommand("hotbar.2 1") |
| 228 | observation = {"observation": ["holds_key"]} |
| 229 | holds_key = True |
| 230 | else: |
| 231 | observation = [] |
| 232 | reward = 0 |
| 233 | return observation, reward, is_mission_running |
| 234 | |
| 163 | 235 | |
| 164 | 236 | # Move the agent towards the house and enter the house. |
| 165 | 237 | # reward = 0 |
| 166 | 238 | def go_to_the_house(agent): |
| 167 | | curr_x, curr_y, curr_z = get_curr_loc(agent) |
| 168 | | turn_to(agent, curr_x, curr_y, curr_z, door_x, door_y, door_z) |
| 169 | | time.sleep(0.2) |
| 170 | | agent.sendCommand("move 1") |
| 171 | | action_complete = stop_condition(agent, 'dark_oak_door') |
| 172 | | if action_complete: |
| 173 | | observation = {"observation":[]} |
| 174 | | if holds_key: |
| 175 | | agent.sendCommand("tp {} {} {}".format(door_x, door_y, door_z)) |
| 176 | | observation["observation"].append("inside_the_house") |
| 177 | | observation["observation"].append("holds_key") |
| 239 | curr_x, curr_y, curr_z = get_curr_loc(agent) |
| 240 | turn_to(agent, curr_x, curr_y, curr_z, door_x, door_y, door_z) |
| 241 | time.sleep(0.2) |
| 242 | agent.sendCommand("move 1") |
| 243 | action_complete = stop_condition(agent, "dark_oak_door") |
| 244 | if action_complete: |
| 245 | observation = {"observation": []} |
| 246 | if holds_key: |
| 247 | agent.sendCommand("tp {} {} {}".format(door_x, door_y, door_z)) |
| 248 | observation["observation"].append("inside_the_house") |
| 249 | observation["observation"].append("holds_key") |
| 250 | else: |
| 251 | observation["observation"].append("nextto_closed_door") |
| 252 | |
| 178 | 253 | else: |
| 179 | | observation["observation"].append("nextto_closed_door") |
| 254 | observation = [] |
| 255 | reward = 0 |
| 256 | return observation, reward, is_mission_running |
| 180 | 257 | |
| 181 | | else: |
| 182 | | observation = [] |
| 183 | | reward = 0 |
| 184 | | return observation, reward, is_mission_running |
| 185 | 258 | |
| 186 | 259 | # Move the agent towards the diamond and collect it. |
| 187 | 260 | # reward = 1 |
| 188 | 261 | def go_to_the_diamonds(agent): |
| 189 | | curr_x, curr_y, curr_z = get_curr_loc(agent) |
| 190 | | turn_to(agent,curr_x, curr_y, curr_z, diamond_x, diamond_y, diamond_z) |
| 191 | | time.sleep(0.2) |
| 192 | | agent.sendCommand("move 1") |
| 193 | | action_complete = stop_condition(agent, 'diamond_block') |
| 194 | | if action_complete: |
| 195 | | reward = 1 |
| 196 | | else: |
| 197 | | reward = 0 |
| 198 | | return [], reward, is_mission_running |
| 262 | curr_x, curr_y, curr_z = get_curr_loc(agent) |
| 263 | turn_to(agent, curr_x, curr_y, curr_z, diamond_x, diamond_y, diamond_z) |
| 264 | time.sleep(0.2) |
| 265 | agent.sendCommand("move 1") |
| 266 | action_complete = stop_condition(agent, "diamond_block") |
| 267 | if action_complete: |
| 268 | reward = 1 |
| 269 | else: |
| 270 | reward = 0 |
| 271 | return [], reward, is_mission_running |
| 272 | |
| 199 | 273 | |
| 200 | | missionXML = ''' |
| 274 | missionXML = ( |
| 275 | """ |
| 201 | 276 | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> |
| 202 | 277 | <Mission xmlns="http://ProjectMalmo.microsoft.com" |
| 203 | 278 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
| … | … | @@ -218,10 +293,20 @@ missionXML = ''' |
| 218 | 293 | <ServerHandlers> |
| 219 | 294 | <FlatWorldGenerator generatorString="3;7,220*1,5*3,2;1;biome_1"/> |
| 220 | 295 | <DrawingDecorator> |
| 221 | | '''+build_house(start_x, start_y, start_z, width, length, height,"planks")+''' |
| 222 | | '''+drawLine(door_x, door_y-1, door_z, door_x, door_y, door_z, "dark_oak_door", "EAST")+''' |
| 223 | | '''+drawBlock(key_x, key_y-1, key_z, "command_block")+''' |
| 224 | | '''+drawBlock(key_x, key_y, key_z, "tripwire_hook")+''' |
| 296 | """ |
| 297 | + build_house(start_x, start_y, start_z, width, length, height, "planks") |
| 298 | + """ |
| 299 | """ |
| 300 | + drawLine( |
| 301 | door_x, door_y - 1, door_z, door_x, door_y, door_z, "dark_oak_door", "EAST" |
| 302 | ) |
| 303 | + """ |
| 304 | """ |
| 305 | + drawBlock(key_x, key_y - 1, key_z, "command_block") |
| 306 | + """ |
| 307 | """ |
| 308 | + drawBlock(key_x, key_y, key_z, "tripwire_hook") |
| 309 | + """ |
| 225 | 310 | |
| 226 | 311 | </DrawingDecorator> |
| 227 | 312 | <ServerQuitFromTimeUp description="" timeLimitMs="1000000"/> |
| … | … | @@ -232,7 +317,11 @@ missionXML = ''' |
| 232 | 317 | <AgentSection mode="Survival"> |
| 233 | 318 | <Name>Cog Agent</Name> |
| 234 | 319 | <AgentStart> |
| 235 | | '''+'<Placement x="{}" y="{}" z="{}" yaw="{}"/>'.format(agent_x, agent_y, agent_z, agent_yaw)+''' |
| 320 | """ |
| 321 | + '<Placement x="{}" y="{}" z="{}" yaw="{}"/>'.format( |
| 322 | agent_x, agent_y, agent_z, agent_yaw |
| 323 | ) |
| 324 | + """ |
| 236 | 325 | <Inventory> |
| 237 | 326 | <InventoryItem slot="0" type="diamond_pickaxe"/> |
| 238 | 327 | <InventoryItem slot="1" type="tripwire_hook"/> |
| … | … | @@ -258,7 +347,8 @@ missionXML = ''' |
| 258 | 347 | |
| 259 | 348 | </Mission> |
| 260 | 349 | |
| 261 | | ''' |
| 350 | """ |
| 351 | ) |
| 262 | 352 | |
| 263 | 353 | if __name__ == "__main__": |
| 264 | 354 | """ |
| … | … | @@ -275,25 +365,25 @@ if __name__ == "__main__": |
| 275 | 365 | rw, ob, done = malmoWrapper.restart() |
| 276 | 366 | total_reward = 0 |
| 277 | 367 | agent = malmoWrapper.agent_host |
| 278 | | _, rw, _= go_to_the_key(agent) |
| 368 | _, rw, _ = go_to_the_key(agent) |
| 279 | 369 | print(ob) |
| 280 | 370 | total_reward += rw |
| 281 | 371 | world_state = agent.getWorldState() |
| 282 | 372 | while world_state.is_mission_running: |
| 283 | | world_state = agent.getWorldState() |
| 284 | | if world_state.number_of_rewards_since_last_state > 0: |
| 285 | | total_reward += world_state.rewards[-1].getValue() |
| 286 | | print("total reward minecraft = {}".format(total_reward)) |
| 373 | world_state = agent.getWorldState() |
| 374 | if world_state.number_of_rewards_since_last_state > 0: |
| 375 | total_reward += world_state.rewards[-1].getValue() |
| 376 | print("total reward minecraft = {}".format(total_reward)) |
| 287 | 377 | |
| 288 | | ob, rw, _ = go_to_the_house(agent) |
| 289 | | print(ob) |
| 290 | | total_reward += rw |
| 378 | ob, rw, _ = go_to_the_house(agent) |
| 379 | print(ob) |
| 380 | total_reward += rw |
| 291 | 381 | |
| 292 | | ob, rw, _ = go_to_the_diamonds(agent) |
| 293 | | print(ob) |
| 294 | | total_reward += rw |
| 382 | ob, rw, _ = go_to_the_diamonds(agent) |
| 383 | print(ob) |
| 384 | total_reward += rw |
| 295 | 385 | |
| 296 | | time.sleep(2) |
| 297 | | print("total reward = {}".format(total_reward)) |
| 386 | time.sleep(2) |
| 387 | print("total reward = {}".format(total_reward)) |
| 298 | 388 | print() |
| 299 | 389 | print("Mission ended") |