forked from Farama-Foundation/ViZDoom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
multiple_instances_advance.py
executable file
·161 lines (119 loc) · 4.07 KB
/
multiple_instances_advance.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
#!/usr/bin/env python3
import os
# For multiplayer game use process (ZDoom's multiplayer sync mechanism prevents threads to work as expected).
from multiprocessing import Process, cpu_count
from random import choice, random
from time import sleep, time
import vizdoom as vzd
# For singleplayer games threads can also be used.
# from threading import Thread
# Config
episodes = 1
timelimit = 1 # minutes
players = 8 # number of players
skip = 4
mode = vzd.Mode.PLAYER # or Mode.ASYNC_PLAYER
ticrate = 2 * vzd.DEFAULT_TICRATE # for Mode.ASYNC_PLAYER
random_sleep = True
const_sleep_time = 0.005
window = True
resolution = vzd.ScreenResolution.RES_320X240
args = ""
console = False
config = os.path.join(vzd.scenarios_path, "cig.cfg")
def setup_player():
game = vzd.DoomGame()
game.load_config(config)
game.set_mode(mode)
game.add_game_args(args)
game.set_screen_resolution(resolution)
game.set_console_enabled(console)
game.set_window_visible(window)
game.set_ticrate(ticrate)
actions = [
[1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0],
]
return game, actions
def player_action(game, player_sleep_time, actions, player_skip):
if random_sleep:
sleep(random() * 0.005 + 0.001)
elif player_sleep_time > 0:
sleep(player_sleep_time)
game.make_action(choice(actions), player_skip)
if game.is_player_dead():
game.respawn_player()
def player_host(p):
game, actions = setup_player()
game.add_game_args(
"-host "
+ str(p)
+ " -netmode 0 -deathmatch +timelimit "
+ str(timelimit)
+ " +sv_spawnfarthest 1 +name Player0 +colorset 0"
)
game.add_game_args(args)
game.init()
action_count = 0
player_sleep_time = const_sleep_time
player_skip = skip
for i in range(episodes):
print("Episode #" + str(i + 1))
episode_start_time = None
while not game.is_episode_finished():
if episode_start_time is None:
episode_start_time = time()
state = game.get_state()
print("Player0:", state.number, action_count, game.get_episode_time())
player_action(game, player_sleep_time, actions, player_skip)
action_count += 1
print("Player0 frags:", game.get_game_variable(vzd.GameVariable.FRAGCOUNT))
print("Host: Episode finished!")
player_count = int(game.get_game_variable(vzd.GameVariable.PLAYER_COUNT))
for i in range(1, player_count + 1):
print(
"Host: Player" + str(i) + ":",
game.get_game_variable(
eval("vzd.GameVariable.PLAYER" + str(i) + "_FRAGCOUNT")
),
)
print("Host: Episode processing time:", time() - episode_start_time)
# Starts a new episode. All players have to call new_episode() in multiplayer mode.
game.new_episode()
game.close()
def player_join(p):
game, actions = setup_player()
game.add_game_args("-join 127.0.0.1 +name Player" + str(p) + " +colorset " + str(p))
game.add_game_args(args)
game.init()
action_count = 0
player_sleep_time = const_sleep_time
player_skip = skip
for i in range(episodes):
while not game.is_episode_finished():
state = game.get_state()
print(
"Player" + str(p) + ":",
state.number,
action_count,
game.get_episode_time(),
)
player_action(game, player_sleep_time, actions, player_skip)
action_count += 1
print(
"Player" + str(p) + " frags:",
game.get_game_variable(vzd.GameVariable.FRAGCOUNT),
)
game.new_episode()
game.close()
if __name__ == "__main__":
print("Players:", players)
print("CPUS:", cpu_count())
processes = []
for i in range(1, players):
p_join = Process(target=player_join, args=(i,))
p_join.start()
processes.append(p_join)
player_host(players)
print("Done")