-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsimulator.py
124 lines (98 loc) · 2.9 KB
/
simulator.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
"""
This script will send things to simulator.jar.
When ran, it lets a human play a level.
"""
import subprocess
import json
from pathlib import Path
import torch
import numpy as np
from vae import VAEMario
from mario_utils.levels import tensor_to_sim_level, clean_level
Tensor = torch.Tensor
filepath = Path(__file__).parent.resolve()
JARFILE_PATH = f"{filepath}/simulator.jar"
def test_level_from_decoded_tensor(
level: Tensor,
human_player: bool = False,
max_time: int = 30,
visualize: bool = False,
) -> dict:
if len(level.shape) < 4:
level = level.view(1, *level.shape)
level = tensor_to_sim_level(level)[0]
level = str(level)
return run_level(
level, human_player=human_player, max_time=max_time, visualize=visualize
)
def test_level_from_int_tensor(
level: Tensor,
human_player: bool = False,
max_time: int = 45,
visualize: bool = False,
) -> dict:
level = clean_level(level.detach().numpy())
level = str(level)
return run_level(
level, human_player=human_player, visualize=visualize, max_time=max_time
)
def test_level_from_int_array(
level: np.ndarray,
human_player: bool = False,
max_time: int = 45,
visualize: bool = False,
) -> dict:
level = clean_level(level)
level = str(level)
return run_level(
level, human_player=human_player, max_time=max_time, visualize=visualize
)
def run_level(
level: str,
human_player: bool = False,
max_time: int = 30,
visualize: bool = False,
) -> dict:
# Run the simulator.jar file with the given level
if human_player:
java = subprocess.Popen(
["java", "-cp", JARFILE_PATH, "geometry.PlayLevel", level],
stdout=subprocess.PIPE,
)
else:
java = subprocess.Popen(
[
"java",
"-cp",
JARFILE_PATH,
"geometry.EvalLevel",
level,
str(max_time),
str(visualize).lower(),
],
stdout=subprocess.PIPE,
)
lines = java.stdout.readlines()
res = lines[-1]
res = json.loads(res.decode("utf8"))
res["level"] = level
return res
def test_level_from_z(z: Tensor, vae: VAEMario, human_player: bool = False) -> dict:
"""
Passes the level that z generates
through the simulator and returns
a dict with results.
These results are defined in
simulator.jar <- EvaluationInfo.
"""
# Get the level from the VAE
res = vae.decode(z.view(1, -1)).probs.argmax(dim=-1)
level = res[0]
return test_level_from_decoded_tensor(level, human_player=human_player)
if __name__ == "__main__":
human_player = False
vae = VAEMario()
vae.load_state_dict(torch.load("./models/example.pt"))
random_z = 3.0 * torch.randn((2,))
res = test_level_from_z(random_z, vae, human_player=human_player)
print(res)