diff --git a/.gitignore b/.gitignore index 72c6435b0..a36b61bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -77,7 +77,7 @@ src/vizdoom/wadsrc_wad src/vizdoom/zdoom_docs src/vizdoom/zlib/x64/ -# Game wads, scenarios backups, demos and personal configurations +# Game wads, scenarios backups, logs, demos and personal configurations **.bak **/doom2.wad **/doom.wad @@ -86,6 +86,7 @@ src/vizdoom/zlib/x64/ **/freedm.wad **.bcp **.lmp +**.log # CLion & PyCharm **.idea diff --git a/examples/c++/CIG.cpp b/examples/c++/CIG.cpp index fdf6ab77e..248ff59fd 100644 --- a/examples/c++/CIG.cpp +++ b/examples/c++/CIG.cpp @@ -24,8 +24,10 @@ int main(){ // Join existing game. game->addGameArgs("-join 127.0.0.1"); // Connect to a host for a multiplayer game. - // Name Your AI. - game->addGameArgs("+name AI"); + // Name your agent and select color + // colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue + game->addGameArgs("+name AI +colorset 0"); + game->setMode(ASYNC_PLAYER); // Multiplayer requires the use of asynchronous modes. game->init(); diff --git a/examples/c++/CIGBots.cpp b/examples/c++/CIGBots.cpp index c53e0130c..52601f18d 100644 --- a/examples/c++/CIGBots.cpp +++ b/examples/c++/CIGBots.cpp @@ -25,37 +25,54 @@ int main(){ game->addGameArgs("-host 1 -deathmatch +timelimit 10.0 " "+sv_forcerespawn 1 +sv_noautoaim 1 +sv_respawnprotect 1 +sv_spawnfarthest 1"); - // Name Your AI. - game->addGameArgs("+name AI"); + // Name your agent and select color + // colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue + game->addGameArgs("+name AI +colorset 0"); // Multiplayer requires the use of asynchronous modes, but when playing only with bots, synchronous modes can also be used. game->setMode(ASYNC_PLAYER); game->init(); - // Add bots (file examples/bots.cfg must be placed in the same directory as the Doom executable file). - for(int i=0; i < 7; ++i) { - game->sendGameCommand("addbot"); - } - while(!game->isEpisodeFinished()){ // Play until the game (episode) is over. + int bots = 7; // Play with this many bots + int episodes = 10; // Run this many episodes + + for(int i = 0; i < episodes; ++i) { - if(game->isPlayerDead()){ - game->respawnPlayer(); // Use this to respawn immediately after death, new state will be available. + std::cout << "Episode #" << i + 1 << "\n"; - // Or observe the game until automatic respawn. - //game->advanceAction(); - //continue; + // Add specific number of bots + // (file examples/bots.cfg must be placed in the same directory as the Doom executable file, + // edit this file to adjust bots). + game->sendGameCommand("removebots"); + for (int b = 0; b < bots; ++b) { + game->sendGameCommand("addbot"); } - GameState state = game->getState(); - // Analyze the state. + while (!game->isEpisodeFinished()) { // Play until the game (episode) is over. + + if (game->isPlayerDead()) { // Check if player is dead + game->respawnPlayer(); // Use this to respawn immediately after death, new state will be available. + + // Or observe the game until automatic respawn. + //game->advanceAction(); + //continue; + } - std::vector action(game->getAvailableButtonsSize()); - // Set your action. + GameState state = game->getState(); + // Analyze the state. - game->makeAction(action); + std::vector action(game->getAvailableButtonsSize()); + // Set your action. + + game->makeAction(action); + + std::cout << game->getEpisodeTime() << " Frags: " << game->getGameVariable(FRAGCOUNT) << std::endl; + } - std::cout << game->getEpisodeTime() << " Frags: " << game->getGameVariable(FRAGCOUNT) << std::endl; + std::cout << "Episode finished.\n"; + std::cout << "Total reward: " << game->getTotalReward() << "\n"; + std::cout << "************************\n"; } game->close(); diff --git a/examples/c++/CIGHost.cpp b/examples/c++/CIGHost.cpp index 6b3850fc5..4597a70f4 100644 --- a/examples/c++/CIGHost.cpp +++ b/examples/c++/CIGHost.cpp @@ -31,8 +31,10 @@ int main(){ "+sv_spawnfarthest 1 " // Players will be spawned as far as possible from any other players. "+vizdoom_nocheat 1"); // Disables depth buffer and the ability to use commands that could interfere with multiplayer game. - // Name Your AI. - game->addGameArgs("+name AI"); + // Name your agent and select color + // colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue + game->addGameArgs("+name AI +colorset 0"); + game->setMode(ASYNC_PLAYER); // Multiplayer requires the use of asynchronous modes. game->init(); diff --git a/examples/java/CIG.java b/examples/java/CIG.java index f8c2d2c2b..35580466b 100644 --- a/examples/java/CIG.java +++ b/examples/java/CIG.java @@ -25,8 +25,9 @@ public static void main (String[] args) { // Join existing game. game.addGameArgs("-join 127.0.0.1"); // Connect to a host for a multiplayer game. - // Name Your AI. - game.addGameArgs("+name AI"); + // Name your agent and select color + // colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue + game.addGameArgs("+name AI +colorset 0"); game.setMode(Mode.ASYNC_PLAYER); // Multiplayer requires the use of asynchronous modes. game.init(); diff --git a/examples/java/CIGBots.java b/examples/java/CIGBots.java index ba1acf156..970b8b4cc 100644 --- a/examples/java/CIGBots.java +++ b/examples/java/CIGBots.java @@ -11,7 +11,6 @@ public static void main (String[] args) { System.out.println("\n\nCIG BOTS EXAMPLE\n"); - // Use CIG example config or Your own. game.loadConfig("../../examples/config/cig.cfg"); @@ -25,35 +24,52 @@ public static void main (String[] args) { // Start multiplayer game only with Your AI (with options that will be used in the competition, details in CIGHost example). game.addGameArgs("-host 1 -deathmatch +timelimit 10.0 +sv_forcerespawn 1 +sv_noautoaim 1 +sv_respawnprotect 1 +sv_spawnfarthest 1"); - // Name Your AI. - game.addGameArgs("+name AI"); + // Name your agent and select color + // colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue + game.addGameArgs("+name AI +colorset 0"); - game.setMode(Mode.ASYNC_PLAYER); // Multiplayer requires the use of asynchronous modes. + game.setMode(Mode.ASYNC_PLAYER); // Multiplayer requires the use of asynchronous modes. game.init(); - for(int i=0; i < 7; ++i) { - game.sendGameCommand("addbot"); - } - while(!game.isEpisodeFinished()){ // Play until the game (episode) is over. + int bots = 7; // Play with this many bots + int episodes = 10; // Run this many episodes - if(game.isPlayerDead()){ // Check if player is dead - game.respawnPlayer(); // Use this to respawn immediately after death, new state will be available. + for(int i = 0; i < episodes; ++i){ - // Or observe the game until automatic respawn. - //game.advanceAction(); - //continue; + System.out.println("Episode #" + (i + 1)); + + // Add specific number of bots + // (file examples/bots.cfg must be placed in the same directory as the Doom executable file, + // edit this file to adjust bots). + game.sendGameCommand("removebots"); + for(int b = 0; b < bots; ++b) { + game.sendGameCommand("addbot"); } - GameState state = game.getState(); - // Analyze the state. + while(!game.isEpisodeFinished()){ // Play until the game (episode) is over. + + if(game.isPlayerDead()){ // Check if player is dead + game.respawnPlayer(); // Use this to respawn immediately after death, new state will be available. - int[] action= new int[game.getAvailableButtonsSize()]; - // Set your action. + // Or observe the game until automatic respawn. + //game.advanceAction(); + //continue; + } - game.makeAction(action); + GameState state = game.getState(); + // Analyze the state. + + int[] action= new int[game.getAvailableButtonsSize()]; + // Set your action. + + game.makeAction(action); + + System.out.println(game.getEpisodeTime() + " Frags: " + game.getGameVariable(GameVariable.FRAGCOUNT)); + } - System.out.println(game.getEpisodeTime() + " Frags: " + game.getGameVariable(GameVariable.FRAGCOUNT)); + System.out.println("Episode finished."); + System.out.println("************************"); } game.close(); diff --git a/examples/java/CIGHost.java b/examples/java/CIGHost.java index 1841906d9..5c453d1e8 100644 --- a/examples/java/CIGHost.java +++ b/examples/java/CIGHost.java @@ -32,16 +32,17 @@ public static void main (String[] args) { +"+sv_spawnfarthest 1 " // Players will be spawned as far as possible from any other players. +"+vizdoom_nocheat 1"); // Disables depth buffer and the ability to use commands that could interfere with multiplayer game. - // Name Your AI. - game.addGameArgs("+name AI"); + // Name your agent and select color + // colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue + game.addGameArgs("+name AI +colorset 0"); game.setMode(Mode.ASYNC_PLAYER); // Multiplayer requires the use of asynchronous modes. game.init(); while(!game.isEpisodeFinished()){ // Play until the game (episode) is over. - if(game.isPlayerDead()){ // Check if player is dead - game.respawnPlayer(); // Use this to respawn immediately after death, new state will be available. + if(game.isPlayerDead()){ // Check if player is dead + game.respawnPlayer(); // Use this to respawn immediately after death, new state will be available. // Or observe the game until automatic respawn. //game.advanceAction(); diff --git a/examples/python/cig.py b/examples/python/cig.py index 21c13e578..0093d4757 100755 --- a/examples/python/cig.py +++ b/examples/python/cig.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import print_function from vizdoom import * @@ -6,10 +6,10 @@ game = DoomGame() -# Use CIG example config or Your own. +# Use CIG example config or your own. game.load_config("../../examples/config/cig.cfg") -# Select game and map You want to use. +# Select game and map you want to use. game.set_doom_game_path("../../scenarios/freedoom2.wad") #game.set_doom_game_path("../../scenarios/doom2.wad") # Not provided with environment due to licences @@ -19,13 +19,14 @@ # Join existing game. game.add_game_args("-join 127.0.0.1") # Connect to a host for a multiplayer game. -# Name Your AI. -game.add_game_args("+name AI") +# Name your agent and select color +# colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue +game.add_game_args("+name AI +colorset 0") # Multiplayer requires the use of asynchronous modes. -game.set_mode(Mode.ASYNC_PLAYER) +game.set_mode(Mode.ASYNC_SPECTATOR) -# game.set_window_visible(false) +#game.set_window_visible(false) game.init() diff --git a/examples/python/cig_bots.py b/examples/python/cig_bots.py index a030bcc5f..35cd0c536 100755 --- a/examples/python/cig_bots.py +++ b/examples/python/cig_bots.py @@ -1,62 +1,84 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import print_function from vizdoom import * from random import choice +from time import sleep game = DoomGame() game.set_vizdoom_path("../../bin/vizdoom") -# Use CIG example config or Your own. +# Use CIG example config or your own. game.load_config("../../examples/config/cig.cfg") -# Select game and map You want to use. +# Select game and map you want to use. game.set_doom_game_path("../../scenarios/freedoom2.wad") #game.set_doom_game_path("../../scenarios/doom2.wad") # Not provided with environment due to licences game.set_doom_map("map01") # Limited deathmatch. #game.set_doom_map("map02") # Full deathmatch. -# Start multiplayer game only with Your AI (with options that will be used in the competition, details in cig_host example). -game.add_game_args("-host 1 -deathmatch +timelimit 10.0 " +# Start multiplayer game only with your AI (with options that will be used in the competition, details in cig_host example). +game.add_game_args("-host 1 -deathmatch +timelimit 1.0 " "+sv_forcerespawn 1 +sv_noautoaim 1 +sv_respawnprotect 1 +sv_spawnfarthest 1") -# Name Your AI. -game.add_game_args("+name AI") +# Name your agent and select color +# colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue +game.add_game_args("+name AI +colorset 0") + # Multiplayer requires the use of asynchronous modes, but when playing only with bots, synchronous modes can also be used. -game.set_mode(Mode.PLAYER) +game.set_mode(Mode.ASYNC_PLAYER) -# game.set_window_visible(false) +# game.set_window_visible(False) game.init() # Three example sample actions 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]] -# Add bots (file examples/bots.cfg must be placed in the same directory as the Doom executable file). -bots_number = 7 -for i in range(bots_number): - game.send_game_command("addbot") +# Play with this many bots +bots = 7 + +# Run this many episodes +episodes = 10 + +for i in range(episodes): + + print("Episode #" + str(i+1)) + + # Add specific number of bots + # (file examples/bots.cfg must be placed in the same directory as the Doom executable file, + # edit this file to adjust bots). + game.send_game_command("removebots") + for i in range(bots): + game.send_game_command("addbot") + + # Play until the game (episode) is over. + while not game.is_episode_finished(): + + if game.is_player_dead(): + # Use this to respawn immediately after death, new state will be available. + game.respawn_player() + + # Or observe the game until automatic respawn. + #game.advance_action(); + #continue; -# Play until the game (episode) is over. -while not game.is_episode_finished(): + s = game.get_state() + # Analyze the state. - if game.is_player_dead(): - # Use this to respawn immediately after death, new state will be available. - game.respawn_player() + game.make_action(choice(actions)) + # Make your action. - # Or observe the game until automatic respawn. - #game.advance_action(); - #continue; + print("Frags:", game.get_game_variable(GameVariable.FRAGCOUNT)) - s = game.get_state() - # Analyze the state. + print("Episode finished.") + print("************************") - game.make_action(choice(actions)) - # Make your action. + # Starts a new episode. All players have to call new_episode() in multiplayer mode. + game.new_episode() - print("Frags:", game.get_game_variable(GameVariable.FRAGCOUNT)) game.close() diff --git a/examples/python/cig_host.py b/examples/python/cig_host.py index 01651b84e..9600e5dc1 100755 --- a/examples/python/cig_host.py +++ b/examples/python/cig_host.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import print_function from vizdoom import * @@ -6,10 +6,10 @@ game = DoomGame() -# Use CIG example config or Your own. +# Use CIG example config or your own. game.load_config("../../examples/config/cig.cfg") -# Select game and map You want to use. +# Select game and map you want to use. game.set_doom_game_path("../../scenarios/freedoom2.wad") #game.set_doom_game_path("../../scenarios/doom2.wad") # Not provided with environment due to licences @@ -17,7 +17,6 @@ #game.set_doom_map("map02") # Full deathmatch. # Host game with options that will be used in the competition. -# game.add_game_args("-host 2 " # This machine will function as a host for a multiplayer game with this many players (including this machine). It will wait for other machines to connect using the -join parameter and then start the game when everyone is connected. "-deathmatch " # Deathmatch rules are used for the game. "+timelimit 10.0 " # The game (episode) will end after this many minutes have elapsed. @@ -27,11 +26,12 @@ "+sv_spawnfarthest 1 " # Players will be spawned as far as possible from any other players. "+vizdoom_nocheat 1") # Disables depth buffer and the ability to use commands that could interfere with multiplayer game. -# Name Your AI. -game.add_game_args("+name AI") +# Name your agent and select color +# colors: 0 - green, 1 - gray, 2 - brown, 3 - red, 4 - light gray, 5 - light brown, 6 - light red, 7 - light blue +game.add_game_args("+name AI +colorset 0") # Multiplayer requires the use of asynchronous modes. -game.set_mode(Mode.ASYNC_PLAYER) +game.set_mode(Mode.ASYNC_SPECTATOR) # game.set_window_visible(false) diff --git a/examples/python/multiple_instances.py b/examples/python/multiple_instances.py index 3a05209d5..934146606 100755 --- a/examples/python/multiple_instances.py +++ b/examples/python/multiple_instances.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import print_function from vizdoom import * @@ -10,6 +10,9 @@ # For singleplayer games threads can also be used. #from threading import Thread +# Run this many episodes +episodes = 10 + def player1(): game = DoomGame() @@ -17,19 +20,29 @@ def player1(): # or game.load_config('../config/multi_duel.cfg') game.add_game_args("-host 2 -deathmatch +timelimit 1.0 +sv_spawnfarthest 1") - game.add_game_args("+name Player1") + game.add_game_args("+name Player1 +colorset 0") game.init() actions = [[True,False,False],[False,True,False],[False,False,True]] - while not game.is_episode_finished(): - if game.is_player_dead(): - game.respawn_player() + for i in range(episodes): + + print("Episode #" + str(i+1)) + + while not game.is_episode_finished(): + if game.is_player_dead(): + game.respawn_player() + + game.make_action(choice(actions)) - game.make_action(choice(actions)) + print("Episode finished!") print("Player1 frags:", game.get_game_variable(GameVariable.FRAGCOUNT)) + # Starts a new episode. All players have to call new_episode() in multiplayer mode. + game.new_episode() + + game.close() def player2(): @@ -39,18 +52,22 @@ def player2(): # or game.load_config('../config/multi_duel.cfg') game.add_game_args("-join 127.0.0.1") - game.add_game_args("+name Player2") + game.add_game_args("+name Player2 +colorset 3") game.init() actions = [[True,False,False],[False,True,False],[False,False,True]] - while not game.is_episode_finished(): - if game.is_player_dead(): - game.respawn_player() + for i in range(episodes): + + while not game.is_episode_finished(): + if game.is_player_dead(): + game.respawn_player() + + game.make_action(choice(actions)) - game.make_action(choice(actions)) print("Player2 frags:", game.get_game_variable(GameVariable.FRAGCOUNT)) + game.new_episode() game.close() @@ -60,4 +77,4 @@ def player2(): p1 = Process(target = player1) p1.start() -player2() \ No newline at end of file +player2() diff --git a/src/lib/ViZDoomController.cpp b/src/lib/ViZDoomController.cpp index 541c88782..6da270540 100644 --- a/src/lib/ViZDoomController.cpp +++ b/src/lib/ViZDoomController.cpp @@ -264,7 +264,6 @@ namespace vizdoom { this->input->BT_AVAILABLE[USE] = true; do { - this->sendCommand(std::string("+use")); this->MQDoomSend(MSG_CODE_TIC); @@ -272,14 +271,13 @@ namespace vizdoom { } while (!this->gameVariables->MAP_END && this->gameVariables->PLAYER_DEAD ); + this->sendCommand(std::string("-use")); this->MQDoomSend(MSG_CODE_UPDATE); this->waitForDoomWork(); this->input->BT_AVAILABLE[USE] = useAvailable; - this->mapLastTic = this->gameVariables->MAP_TIC; - } else this->restartMap(); } @@ -334,26 +332,42 @@ namespace vizdoom { this->resetButtons(); - int restartingTics = 0; + int restartTics = 0; + + bool useAvailable; + if(this->gameVariables->NET_GAME){ + useAvailable = this->input->BT_AVAILABLE[USE]; + this->input->BT_AVAILABLE[USE] = true; + + this->sendCommand(std::string("-use")); + } do { - ++restartingTics; + ++restartTics; + + if(this->gameVariables->NET_GAME){ + if(restartTics % 2) this->sendCommand(std::string("+use")); + else this->sendCommand(std::string("-use")); + } + this->MQDoomSend(MSG_CODE_TIC); this->waitForDoomWork(); - if(this->gameVariables->NET_GAME) this->sendCommand(std::string("+use")); - - if (!this->gameVariables->NET_GAME && restartingTics > 3) { + if (!this->gameVariables->NET_GAME && restartTics > 3) { this->sendCommand(std::string("map ") + this->map); - restartingTics = 0; + restartTics = 0; } } while (this->gameVariables->MAP_END || this->gameVariables->PLAYER_DEAD || this->gameVariables->MAP_TIC > this->mapLastTic); - this->waitForDoomMapStartTime(); + if(this->gameVariables->NET_GAME){ + this->sendCommand(std::string("-use")); + this->input->BT_AVAILABLE[USE] = useAvailable; + } + this->waitForDoomMapStartTime(); this->MQDoomSend(MSG_CODE_UPDATE); this->waitForDoomWork();