diff --git a/setup.py b/setup.py index 6f791c4..647538e 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ def run_cmake(): new_dir = op.join(op.split(__file__)[0], 'build') dd.mkpath(new_dir) os.chdir(new_dir) - cmake_args = ' -DBUILD_EXAMPLES=OFF -DBUILD_PYTHON=ON' + cmake_args = '-DUSE_SDL=ON -DBUILD_EXAMPLES=OFF -DBUILD_PYTHON=ON' cores_to_use = max(1, multiprocessing.cpu_count() - 1) try: diff --git a/src/environment/Settings.cxx b/src/environment/Settings.cxx index d5acb50..3f77dd8 100644 --- a/src/environment/Settings.cxx +++ b/src/environment/Settings.cxx @@ -1,8 +1,8 @@ //============================================================================ // -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa // SSSS tt ee ee ll ll aa // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" // SS SS tt ee ll ll aa aa @@ -329,19 +329,33 @@ void Settings::setDefaultSettings() { // Game-Specific Settings - // Mortal Kombat - boolSettings.emplace(std::make_pair("MK_random_position", true)); + // Mortal Kombat + boolSettings.emplace(std::make_pair("MK_random_position", false)); stringSettings.emplace(std::make_pair("MK_difficulty", "medium")); stringSettings.emplace(std::make_pair("MK_player1_character", "cage")); stringSettings.emplace(std::make_pair("MK_player2_character", "scorpion")); intSettings.emplace(std::make_pair("MK_opponent_character", 0)); - // Super Mario Kart - stringSettings.emplace(std::make_pair("SUPER_MARIO_KART_player1_character", "bowser")); - //Super Double Dragon - stringSettings.emplace(std::make_pair("DDRAGON_reward_strategy", "score")); - +// Streets of Rage + boolSettings.emplace(std::make_pair("SOR_verbose", false)); + boolSettings.emplace(std::make_pair("SOR_test", false)); + intSettings.emplace(std::make_pair("SOR_start_level", 2)); + intSettings.emplace(std::make_pair("SOR_end_level", 2)); + intSettings.emplace(std::make_pair("SOR_difficulty", 1)); + intSettings.emplace(std::make_pair("SOR_lives", 3)); + stringSettings.emplace(std::make_pair("SOR_player_1_character", "axel")); + stringSettings.emplace(std::make_pair("SOR_player_2_character", "blaze")); + boolSettings.emplace(std::make_pair("SOR_round_clear", false)); + boolSettings.emplace(std::make_pair("SOR_2p_terminal_both_win", true)); + + + // Super Mario Kart + stringSettings.emplace(std::make_pair("SUPER_MARIO_KART_player1_character", "bowser")); + + //Super Double Dragon + stringSettings.emplace(std::make_pair("DDRAGON_reward_strategy", "score")); + for (map::iterator it = stringSettings.begin(); it != stringSettings.end(); it++) { this->setString(it->first, it->second); diff --git a/src/environment/retro_environment.cpp b/src/environment/retro_environment.cpp index 2c0c926..63c6f86 100644 --- a/src/environment/retro_environment.cpp +++ b/src/environment/retro_environment.cpp @@ -1,8 +1,8 @@ /* ***************************************************************************** * A.L.E (Arcade Learning Environment) - * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and * the Reinforcement Learning and Artificial Intelligence Laboratory - * Released under the GNU General Public License; see License.txt for details. + * Released under the GNU General Public License; see License.txt for details. * * Based on: Stella -- "An Atari 2600 VCS Emulator" * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team @@ -12,7 +12,7 @@ * * A class that wraps around the Stella core to provide users with a typical * reinforcement learning environment interface. - * + * **************************************************************************** */ #include "retro_environment.hpp" @@ -117,9 +117,21 @@ void RetroEnvironment::reset() { // m_rlesystem->p_display_screen->display_screen(); } m_settings->startingOperations(*m_rlesystem); + + startingActions = m_settings->getExtraActions(*m_rlesystem); + for (size_t i = 0; i < startingActions.size(); i++){ + if((startingActions[i] & PLAYER_B) > 0){ + emulateStart(JOYPAD_NOOP, startingActions[i]); + }else{ + emulateStart(startingActions[i], PLAYER_B | JOYPAD_NOOP); + } + + m_rlesystem->getRetroAgent()->audioEnable(audio); } +} + /** Save/restore the environment state. */ void RetroEnvironment::save() { // Store the current state into a new object @@ -275,4 +287,3 @@ void RetroEnvironment::processScreen() { memcpy((uint8_t*)m_screen.getArray() + i*width *Bpp , buffer + i*pitch, width * Bpp); } } - diff --git a/src/games/RomSettings.cpp b/src/games/RomSettings.cpp index 3462ee3..a8e021e 100644 --- a/src/games/RomSettings.cpp +++ b/src/games/RomSettings.cpp @@ -1,8 +1,8 @@ /* ***************************************************************************** * A.L.E (Arcade Learning Environment) - * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and * the Reinforcement Learning and Artificial Intelligence Laboratory - * Released under the GNU General Public License; see License.txt for details. + * Released under the GNU General Public License; see License.txt for details. * * Based on: Stella -- "An Atari 2600 VCS Emulator" * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team @@ -29,7 +29,9 @@ ActionVect RomSettings::getStartingActions() { return ActionVect(); } - +ActionVect RomSettings::getExtraActions() { + return ActionVect(); +} ActionVect RomSettings::getMinimalActionSet() { ActionVect actions; for (unsigned a = 0; a < AllActionsVector.size(); a++) { diff --git a/src/games/RomSettings.hpp b/src/games/RomSettings.hpp index b033259..5c36a33 100644 --- a/src/games/RomSettings.hpp +++ b/src/games/RomSettings.hpp @@ -15,9 +15,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************** * A.L.E (Arcade Learning Environment) - * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and * the Reinforcement Learning and Artificial Intelligence Laboratory - * Released under the GNU General Public License; see License.txt for details. + * Released under the GNU General Public License; see License.txt for details. * * Based on: Stella -- "An Atari 2600 VCS Emulator" * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team @@ -107,6 +107,10 @@ struct RomSettings { // Optionally perform starting operations such as modifying the game's RAM virtual void startingOperations(RleSystem& system){}; + // Optionall get extra starting actions AFTER modifying the game's RAM + virtual ActionVect getExtraActions(); + virtual ActionVect getExtraActions(const RleSystem& system){ return getExtraActions();} + // below functions used to belong to RomUtils // reads a byte at a memory location virtual int readRam(const RleSystem* system, int offset); diff --git a/src/games/Roms.cpp b/src/games/Roms.cpp index a5bdee6..910e353 100644 --- a/src/games/Roms.cpp +++ b/src/games/Roms.cpp @@ -40,6 +40,12 @@ // genesis games #include "supported/SonicTheHedgehog.hpp" +#include "supported/StreetsOfRage.hpp" +#include "supported/StreetsOfRage2Players.hpp" +#include "supported/StreetsOfRageII.hpp" +#include "supported/StreetsOfRageII2Players.hpp" +#include "supported/StreetsOfRageIII.hpp" +#include "supported/StreetsOfRageIII2Players.hpp" // Atari Games //#include "supported/Breakout.hpp" @@ -182,8 +188,15 @@ static const RomSettings *roms[] = { new AladdinSettings(), new StreetFighterIISettings(), new BustAMoveSettings(), -// Genesis games - new SonicTheHedgehogSettings() + + //Genesis games + new SonicTheHedgehogSettings(), + new StreetsOfRageSettings(), + new StreetsOfRage2PlayersSettings(), + new StreetsOfRageIISettings(), + new StreetsOfRageII2PlayersSettings(), + new StreetsOfRageIIISettings(), + new StreetsOfRageIII2PlayersSettings(), }; diff --git a/src/games/supported/StreetsOfRage.cpp b/src/games/supported/StreetsOfRage.cpp new file mode 100644 index 0000000..ecba617 --- /dev/null +++ b/src/games/supported/StreetsOfRage.cpp @@ -0,0 +1,182 @@ +/* ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ +#include "../RomUtils.hpp" +#include + +#include "../RomUtils.hpp" + +#include "RleSystem.hxx" +#include "RleException.h" + +#include "StreetsOfRage.hpp" +#include + + +using namespace rle; + + +StreetsOfRageSettings::StreetsOfRageSettings() { + reset(); + + minimalActions = {JOYPAD_NOOP, + JOYPAD_DOWN, //Walk down + JOYPAD_UP, // Walk up + JOYPAD_LEFT, // Walk left + JOYPAD_RIGHT, // Walk right + + JOYPAD_GENESIS_C, // Jump + JOYPAD_GENESIS_C | JOYPAD_LEFT, // Jump left + JOYPAD_GENESIS_C | JOYPAD_RIGHT, // Jump right + + JOYPAD_GENESIS_A, // Special attack + JOYPAD_LEFT | JOYPAD_GENESIS_A, + JOYPAD_RIGHT |JOYPAD_GENESIS_A, + + JOYPAD_GENESIS_B, // Regular attack + JOYPAD_GENESIS_B | JOYPAD_GENESIS_C, // Rear attack or Super slam + JOYPAD_GENESIS_B | JOYPAD_LEFT,//Blitz attack or + JOYPAD_GENESIS_B | JOYPAD_RIGHT, + + }; +} + + +/* create a new instance of the rom */ +RomSettings* StreetsOfRageSettings::clone() const { + RomSettings* rval = new StreetsOfRageSettings(); + *rval = *this; + return rval; +} + + +void StreetsOfRageSettings::step(const RleSystem& system) { +// Read out current score, health, lives, stage progress + reward_t score = 0; + reward_t health = readRam(&system, 0xB832); + reward_t screen = readRam(&system, 0xFF00); + reward_t distance = getDecimalScore(0xB810, &system); + m_lives = readRam(&system, 0xFF21); + +// update the reward + m_reward = score; + +// Update terminal status + if ((m_lives == 0) && (health == 0) && (screen == 22)){ + std::cout << "fail" << std::endl; + m_terminal = true; + } + + // Get level information + m_current_level = readRam(&system, 0xFF02) + 1; + int m_end_level = system.settings()->getInt("SOR_end_level"); + + // Update terminal status + if ((m_current_level == m_end_level) && (screen == 24)){ + m_terminal=true; + } +} +/* reset the state of the game */ +void StreetsOfRageSettings::reset(){ + m_reward = 0; +// m_score = 0; + m_terminal = false; + m_distance = 0; +} + + +/* saves the state of the rom settings */ +void StreetsOfRageSettings::saveState( Serializer & ser ) { + ser.putInt(m_reward); + ser.putInt(m_score); + ser.putBool(m_terminal); +} + + +// loads the state of the rom settings +void StreetsOfRageSettings::loadState( Deserializer & des ) { + m_reward = des.getInt(); + m_score = des.getInt(); + m_terminal = des.getBool(); +} + + +ActionVect StreetsOfRageSettings::getStartingActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// wait for intro to end + INSERT_NOPS(5*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(0.4*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + + + // select 1 player + INSERT_NOPS(1*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(4*num_of_nops) + + +// choose character + string player_1_character = system.settings()->getString("SOR_player_1_character"); + if("adam" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("axel" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("blaze" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_LEFT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + } + + INSERT_NOPS(0.5 * num_of_nops) + + return startingActions; +} + + + +void StreetsOfRageSettings::startingOperations(RleSystem& system){ + //set number of lives (Can be 1, 3, 5, or 7) + int num_lives = system.settings()->getInt("SOR_lives"); + writeRam(&system, 0xFFCA, ((num_lives - 1) / 2 ) * 0x1); + + //set difficulty + int difficulty = system.settings()->getInt("SOR_difficulty"); + if(1 == difficulty){ + writeRam(&system, 0xFFC6, 0x0); + }else if(2 == difficulty){ + writeRam(&system, 0xFFC6, 0x1); + }else if(3 == difficulty){ + writeRam(&system, 0xFFC6, 0x2); + }else if(4 == difficulty){ + writeRam(&system, 0xFFC6, 0x3); + } + + //set start level + int start_level = system.settings()->getInt("SOR_start_level"); + writeRam(&system, 0xFF02, (start_level-1)* 0x1); + +} + +ActionVect StreetsOfRageSettings::getExtraActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// wait for level to begin + INSERT_NOPS(4.5 * num_of_nops) + + + return startingActions; +} \ No newline at end of file diff --git a/src/games/supported/StreetsOfRage.hpp b/src/games/supported/StreetsOfRage.hpp new file mode 100644 index 0000000..873c597 --- /dev/null +++ b/src/games/supported/StreetsOfRage.hpp @@ -0,0 +1,80 @@ +/* ***************************************************************************** + * The line 67 is based on Xitari's code, from Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ + +#ifndef __STREETS_OF_RAGE_SETTINGS_HPP__ +#define __STREETS_OF_RAGE_SETTINGS_HPP__ +/* RL wrapper for AtariCollection settings */ + +#include "../GenesisSettings.hpp" +#include + +namespace rle { + +class StreetsOfRageSettings : public GenesisSettings { + + public: + + StreetsOfRageSettings(); + + // reset + void reset(); + + // the rom-name + const char* rom() const { return "streets_of_rage"; } + + // create a new instance of the rom + RomSettings* clone() const; + + // process the latest information from ALE + void step(const RleSystem& system); + + + // saves the state of the rom settings + void saveState( Serializer & ser ); + + + // loads the state of the rom settings + void loadState( Deserializer & des ); + + + virtual const int lives() { return 0; } + + virtual ActionVect getStartingActions(const RleSystem& system); + + virtual ActionVect getExtraActions(const RleSystem& system); + + void startingOperations(RleSystem& system); + private: + int m_lives; + int m_current_level; + int m_distance; + int delta_distance; +}; + +} // namespace rle + +#endif // __STREETS_OF_RAGE_SETTINGS_HPP__ diff --git a/src/games/supported/StreetsOfRage2Players.cpp b/src/games/supported/StreetsOfRage2Players.cpp new file mode 100644 index 0000000..70b4c6f --- /dev/null +++ b/src/games/supported/StreetsOfRage2Players.cpp @@ -0,0 +1,223 @@ +/* ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ +#include "../RomUtils.hpp" +#include + +#include "../RomUtils.hpp" + +#include "RleSystem.hxx" +#include "RleException.h" + +#include "StreetsOfRage2Players.hpp" +#include + + +using namespace rle; + + +StreetsOfRage2PlayersSettings::StreetsOfRage2PlayersSettings() { + reset(); + + minimalActions = {JOYPAD_NOOP, + JOYPAD_DOWN, //Walk down + JOYPAD_UP, // Walk up + JOYPAD_LEFT, // Walk left + JOYPAD_RIGHT, // Walk right + + JOYPAD_GENESIS_C, // Jump + JOYPAD_GENESIS_C | JOYPAD_LEFT, // Jump left + JOYPAD_GENESIS_C | JOYPAD_RIGHT, // Jump right + + JOYPAD_GENESIS_A, // Special attack + JOYPAD_LEFT | JOYPAD_GENESIS_A, + JOYPAD_RIGHT |JOYPAD_GENESIS_A, + + JOYPAD_GENESIS_B, // Regular attack + JOYPAD_GENESIS_B | JOYPAD_GENESIS_C, // Rear attack or Super slam + JOYPAD_GENESIS_B | JOYPAD_LEFT,//Blitz attack or + JOYPAD_GENESIS_B | JOYPAD_RIGHT, + + }; +} + + +/* create a new instance of the rom */ +RomSettings* StreetsOfRage2PlayersSettings::clone() const { + RomSettings* rval = new StreetsOfRage2PlayersSettings(); + *rval = *this; + return rval; +} + + +void StreetsOfRage2PlayersSettings::step(const RleSystem& system) { +// Read out current score, health, lives, stage progress + reward_t score = 0; + player_1_health = readRam(&system, 0xB832); + player_2_health = readRam(&system, 0xB8B2); + player_1_lives = readRam(&system, 0xFF21); + player_2_lives = readRam(&system, 0xFF22); + screen = readRam(&system, 0xFF00); + distance = getDecimalScore(0xB810, &system); + + + // Update terminal status + if (system.settings()->getBool("SOR_2p_terminal_both_win") == true){ + if( ((player_1_health == 0) && (player_1_lives == 0))|| ((player_2_health == 0) && (player_2_lives == 0))){ + m_terminal = true; + } + }else{ + if((player_1_health == 0) && (player_1_lives == 0) && (player_2_health == 0) && (player_2_lives == 0)){ + m_terminal = true; + } + } + + // Get level information + m_current_level = readRam(&system, 0xFF02) + 1; + int m_end_level = system.settings()->getInt("SOR_end_level"); + + // Update terminal status + if ((m_current_level == m_end_level) && (screen == 24)){ + m_terminal=true; + } +} + +/* reset the state of the game */ +void StreetsOfRage2PlayersSettings::reset(){ + +// m_score = 0; + m_terminal = false; + distance = 0; +} + + +/* saves the state of the rom settings */ +void StreetsOfRage2PlayersSettings::saveState( Serializer & ser ) { + + ser.putInt(m_score); + ser.putBool(m_terminal); +} + + +// loads the state of the rom settings +void StreetsOfRage2PlayersSettings::loadState( Deserializer & des ) { + + m_score = des.getInt(); + m_terminal = des.getBool(); +} + + +ActionVect StreetsOfRage2PlayersSettings::getStartingActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// wait for intro to end + INSERT_NOPS(5*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(0.4*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + + + // select 1 player + INSERT_NOPS(1 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_DOWN) + INSERT_NOPS(1 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(4*num_of_nops) + + +// choose character + string player_1 = system.settings()->getString("SOR_player_1_character"); + string player_2 = system.settings()->getString("SOR_player_2_character"); + + if((player_1 == "adam") && (player_2 == "blaze")){ + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if((player_1 == "adam") && (player_2 == "axel")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if((player_1 == "axel") && (player_2 == "adam")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if ((player_1 == "axel") && (player_2 == "blaze")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if ((player_1 == "blaze") && (player_2 == "adam")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + } else if ((player_1 == "blaze") && (player_2 == "axel")){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + } + + INSERT_NOPS(0.5 * num_of_nops) + + return startingActions; +} + + + +void StreetsOfRage2PlayersSettings::startingOperations(RleSystem& system){ + //set number of lives (Can be 1, 3, 5, or 7) + int num_lives = system.settings()->getInt("SOR_lives"); + writeRam(&system, 0xFFCA, ((num_lives - 1) / 2 ) * 0x1); + + //set difficulty + int difficulty = system.settings()->getInt("SOR_difficulty"); + if(1 == difficulty){ + writeRam(&system, 0xFFC6, 0x0); + }else if(2 == difficulty){ + writeRam(&system, 0xFFC6, 0x1); + }else if(3 == difficulty){ + writeRam(&system, 0xFFC6, 0x2); + }else if(4 == difficulty){ + writeRam(&system, 0xFFC6, 0x3); + } + + //set start level + int start_level = system.settings()->getInt("SOR_start_level"); + writeRam(&system, 0xFF02, (start_level-1)* 0x1); + +} + +ActionVect StreetsOfRage2PlayersSettings::getExtraActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// wait for level to begin + INSERT_NOPS(4.5 * num_of_nops) + + + return startingActions; +} \ No newline at end of file diff --git a/src/games/supported/StreetsOfRage2Players.hpp b/src/games/supported/StreetsOfRage2Players.hpp new file mode 100644 index 0000000..6d33ba2 --- /dev/null +++ b/src/games/supported/StreetsOfRage2Players.hpp @@ -0,0 +1,83 @@ +/* ***************************************************************************** + * The line 67 is based on Xitari's code, from Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ + +#ifndef __STREETS_OF_RAGE_TWO_PLAYERS_SETTINGS_HPP__ +#define __STREETS_OF_RAGE_TWO_PLAYERS_SETTINGS_HPP__ +/* RL wrapper for AtariCollection settings */ + +#include "../GenesisSettings.hpp" +#include + +namespace rle { + +class StreetsOfRage2PlayersSettings : public GenesisSettings { + + public: + + StreetsOfRage2PlayersSettings(); + + // reset + void reset(); + + // the rom-name + const char* rom() const { return "streets_of_rage_2_players"; } + + // create a new instance of the rom + RomSettings* clone() const; + + // process the latest information from ALE + void step(const RleSystem& system); + + + // saves the state of the rom settings + void saveState( Serializer & ser ); + + + // loads the state of the rom settings + void loadState( Deserializer & des ); + + + virtual const int lives() { return 0; } + + virtual ActionVect getStartingActions(const RleSystem& system); + + virtual ActionVect getExtraActions(const RleSystem& system); + + void startingOperations(RleSystem& system); + private: + reward_t player_1_health; + reward_t player_2_health; + int player_1_lives; + int player_2_lives; + int m_current_level; + int distance; + int screen; +}; + +} // namespace rle + +#endif // __STREETS_OF_RAGE_TWO_PLAYERS_SETTINGS_HPP__ diff --git a/src/games/supported/StreetsOfRageII.cpp b/src/games/supported/StreetsOfRageII.cpp new file mode 100644 index 0000000..a7df733 --- /dev/null +++ b/src/games/supported/StreetsOfRageII.cpp @@ -0,0 +1,280 @@ +/* ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ +#include "../RomUtils.hpp" +#include + +#include "../RomUtils.hpp" + +#include "RleSystem.hxx" +#include "RleException.h" + +#include "StreetsOfRageII.hpp" +#include + + +using namespace rle; + + +StreetsOfRageIISettings::StreetsOfRageIISettings() { + reset(); + + minimalActions = {JOYPAD_NOOP, + JOYPAD_DOWN, //Walk down + JOYPAD_UP, // Walk up + JOYPAD_LEFT, // Walk left + JOYPAD_RIGHT, // Walk right + + JOYPAD_GENESIS_C, // Jump + JOYPAD_GENESIS_C | JOYPAD_LEFT, // Jump left + JOYPAD_GENESIS_C | JOYPAD_RIGHT, // Jump right + + JOYPAD_GENESIS_A, // Special attack + JOYPAD_LEFT | JOYPAD_GENESIS_A, + JOYPAD_RIGHT |JOYPAD_GENESIS_A, + + JOYPAD_GENESIS_B, // Regular attack + JOYPAD_GENESIS_B | JOYPAD_GENESIS_C, // Rear attack or Super slam + JOYPAD_GENESIS_B | JOYPAD_LEFT,//Blitz attack or + JOYPAD_GENESIS_B | JOYPAD_RIGHT, + + }; +} + + +/* create a new instance of the rom */ +RomSettings* StreetsOfRageIISettings::clone() const { + RomSettings* rval = new StreetsOfRageIISettings(); + *rval = *this; + return rval; +} + + +void StreetsOfRageIISettings::step(const RleSystem& system) { +// Begin code for testing + if(system.settings()->getBool("SOR_test") == true){ + // Fix Agent health + writeRam(&system, 0xEF80, 0x68); + // Make invincible + writeRam(&system, 0xEF50, 0x14); + // Freeze Time + //writeRam(&system, 0xFC3C, 0x99); + } + +// This setting gives all enemies minimal health + if((system.settings()->getBool("SOR_test") == true) || system.settings()->getInt("SOR_difficulty") == 0){ + // Fix enemy health + writeRam(&system, 0xF180, 0x0); + writeRam(&system, 0xF280, 0x0); + writeRam(&system, 0xF380, 0x0); + writeRam(&system, 0xF480, 0x0); + writeRam(&system, 0xF580, 0x0); + writeRam(&system, 0xF680, 0x0); +} + +// End code for testing + +// Read out current score (Score set to 0. Will read score from RAM in rle/gym wrapper) + reward_t score = 0; //getDecimalScore(0xEF99, 0xEF96, &system); + m_lives = readRam(&system, 0xEF82); + m_health = readRam(&system, 0xEF80); + +// Update the reward + m_reward = score - m_score; + m_score = score; + +// Update terminal status + if (m_lives == 255){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Game over! Restarting." << std::endl; + } + m_terminal = true; + } + // Get level information + m_current_level = (readRam(&system, 0xFC42) / 2) + 1; + m_end_level = system.settings()->getInt("SOR_end_level"); + +// int screen = readRam(&system, 0xFC02); + int m_progress_1 = readRam(&system, 0xFC44); + int m_progress_2 = readRam(&system, 0xFCCE); + + // Get boss information + int boss_health = readRam(&system, 0xF180); + int boss_lives = readRam(&system, 0xF182); + + if ((system.settings()->getBool("SOR_round_clear") == true) || (m_end_level == 8)){ + if (((m_current_level - 1) == m_end_level) && (m_progress_1 == 0) && (m_progress_2 > 10)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Round "<< m_end_level << " clear!" << std::endl; + } + m_terminal = true; + } + }// Level 1 + else if ((m_end_level == 1) && (m_current_level == 1)) { + if ((m_progress_1 == 12) && (m_progress_2 == 12) && ((boss_health + boss_lives) == 0)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 2 + else if ((m_end_level == 2) && (m_current_level == 2) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 12) && (m_progress_2 == 12)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 3 + else if ((m_end_level == 3) && (m_current_level == 3) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 16) && (m_progress_2 == 16)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 4 + else if ((m_end_level == 4) && (m_current_level == 4) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 22) && (m_progress_2 == 22)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 5 + else if ((m_end_level == 5) && (m_current_level == 5) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 10) && (m_progress_2 == 10)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 6 + else if ((m_end_level == 6) && (m_current_level == 6) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 10) && (m_progress_2 == 10)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 7 + else if ((m_end_level == 7) && (m_current_level == 7) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 18) && (m_progress_2 == 18)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + } // Level 8 (see above) +} + +/* reset the state of the game */ +void StreetsOfRageIISettings::reset() { + m_reward = 0; + m_score = 0; + m_terminal = false; +} + + +/* saves the state of the rom settings */ +void StreetsOfRageIISettings::saveState( Serializer & ser ) { + ser.putInt(m_reward); + ser.putInt(m_score); + ser.putBool(m_terminal); +} + + +// loads the state of the rom settings +void StreetsOfRageIISettings::loadState( Deserializer & des ) { + m_reward = des.getInt(); + m_score = des.getInt(); + m_terminal = des.getBool(); +} + + +ActionVect StreetsOfRageIISettings::getStartingActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + + // wait for intro to end + INSERT_NOPS(5 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(0.4*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(0.5*num_of_nops) + + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(3 * num_of_nops) + // + string player_1_character = system.settings()->getString("SOR_player_1_character"); + if("axel" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("max" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_LEFT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("blaze" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("skate" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + } + + return startingActions; +} + + void StreetsOfRageIISettings::startingOperations(RleSystem& system){ + //set difficulty + m_difficulty = system.settings()->getInt("SOR_difficulty"); + if(0 == m_difficulty){ + // Also setting enemy health low (see above). + writeRam(&system, 0xFD04, 0x0); + }else if(1 == m_difficulty){ + writeRam(&system, 0xFD04, 0x0); + }else if(2 == m_difficulty){ + writeRam(&system, 0xFD04, 0x2); + }else if(3 == m_difficulty){ + writeRam(&system, 0xFD04, 0x4); + }else if(4 == m_difficulty){ + writeRam(&system, 0xFD04, 0x6); + }else if(5 == m_difficulty){ + writeRam(&system, 0xFD04, 0x8); + }else if(6 == m_difficulty){ + writeRam(&system, 0xFD04, 0x0A); + } + + // Set number of continues. By Default continues set to zero. + writeRam(&system,0xEFA4, 0x0); + + // Set start level + m_start_level = system.settings()->getInt("SOR_start_level"); + writeRam(&system, 0xFD0E, (m_start_level-1) * 0x1); + + // Set number of lives + m_lives = system.settings()->getInt("SOR_lives"); + writeRam(&system, 0xFD06, (m_lives-1) * 0x1); + } + + +ActionVect StreetsOfRageIISettings::getExtraActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// wait for level to begin + INSERT_NOPS(4 * num_of_nops) + + return startingActions; +} diff --git a/src/games/supported/StreetsOfRageII.hpp b/src/games/supported/StreetsOfRageII.hpp new file mode 100644 index 0000000..c77748d --- /dev/null +++ b/src/games/supported/StreetsOfRageII.hpp @@ -0,0 +1,82 @@ +/* ***************************************************************************** + * The line 67 is based on Xitari's code, from Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ + +#ifndef __STREETS_OF_RAGE_II_SETTINGS_HPP__ +#define __STREETS_OF_RAGE_II_SETTINGS_HPP__ +/* RL wrapper for AtariCollection settings */ + +#include "../GenesisSettings.hpp" +#include + +namespace rle { + +class StreetsOfRageIISettings : public GenesisSettings { + + public: + + StreetsOfRageIISettings(); + + // reset + void reset(); + + // the rom-name + const char* rom() const { return "streets_of_rage_ii"; } + + // create a new instance of the rom + RomSettings* clone() const; + + // process the latest information from ALE + void step(const RleSystem& system); + + + // saves the state of the rom settings + void saveState( Serializer & ser ); + + + // loads the state of the rom settings + void loadState( Deserializer & des ); + + virtual const int lives() { return 0; } + + virtual ActionVect getStartingActions(const RleSystem& system); + + virtual ActionVect getExtraActions(const RleSystem& system); + + void startingOperations(RleSystem& system); + private: + reward_t m_score; + int m_start_level; + int m_end_level; + int m_current_level; + int m_lives; + int m_health; + int m_difficulty; +}; + +} // namespace rle + +#endif // __STREETS_OF_RAGE_2_SETTINGS_HPP__ diff --git a/src/games/supported/StreetsOfRageII2Players.cpp b/src/games/supported/StreetsOfRageII2Players.cpp new file mode 100644 index 0000000..04ea9af --- /dev/null +++ b/src/games/supported/StreetsOfRageII2Players.cpp @@ -0,0 +1,359 @@ +/* ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ +#include "../RomUtils.hpp" +#include + +#include "../RomUtils.hpp" + +#include "RleSystem.hxx" +#include "RleException.h" + +#include "StreetsOfRageII2Players.hpp" +#include + + +using namespace rle; + + +StreetsOfRageII2PlayersSettings::StreetsOfRageII2PlayersSettings() { + reset(); + + minimalActions = {JOYPAD_NOOP, + JOYPAD_DOWN, //Walk down + JOYPAD_UP, // Walk up + JOYPAD_LEFT, // Walk left + JOYPAD_RIGHT, // Walk right + + JOYPAD_GENESIS_C, // Jump + JOYPAD_GENESIS_C | JOYPAD_LEFT, // Jump left + JOYPAD_GENESIS_C | JOYPAD_RIGHT, // Jump right + + JOYPAD_GENESIS_A, // Special attack + JOYPAD_LEFT | JOYPAD_GENESIS_A, + JOYPAD_RIGHT |JOYPAD_GENESIS_A, + + JOYPAD_GENESIS_B, // Regular attack + JOYPAD_GENESIS_B | JOYPAD_GENESIS_C, // Rear attack or Super slam + JOYPAD_GENESIS_B | JOYPAD_LEFT,//Blitz attack or + JOYPAD_GENESIS_B | JOYPAD_RIGHT, + + }; +} + + +/* create a new instance of the rom */ +RomSettings* StreetsOfRageII2PlayersSettings::clone() const { + RomSettings* rval = new StreetsOfRageII2PlayersSettings(); + *rval = *this; + return rval; +} + + +void StreetsOfRageII2PlayersSettings::step(const RleSystem& system) { +// Begin code for testing + if(system.settings()->getBool("SOR_test") == true){ + // Fix Agent health + writeRam(&system, 0xEF80, 0x68); + // Make invincible + writeRam(&system, 0xEF50, 0x14); + writeRam(&system, 0xF050, 0x14); + // Freeze Time + writeRam(&system, 0xFC3C, 0x99); + } + +// This setting gives all enemies minimal health + if((system.settings()->getBool("SOR_test") == true) || system.settings()->getInt("SOR_difficulty") == 0){ + // Fix enemy health + writeRam(&system, 0xF180, 0x0); + writeRam(&system, 0xF280, 0x0); + writeRam(&system, 0xF380, 0x0); + writeRam(&system, 0xF480, 0x0); + writeRam(&system, 0xF580, 0x0); + writeRam(&system, 0xF680, 0x0); +} +// End code for testing + +// Read out current score (Score set to 0. Will read score from RAM in rle/gym wrapper) + reward_t score = 0; //getDecimalScore(0xEF99, 0xEF96, &system); + player_1_lives = readRam(&system, 0xEF82); + player_2_lives = readRam(&system, 0xF082); + +// Update the reward + m_reward = score - m_score; + m_score = score; + +// Update terminal status + if (system.settings()->getBool("SOR_2p_terminal_both_win") == true){ + if((player_1_lives == 255) || (player_2_lives == 255)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Game over! Restarting." << std::endl; + } + m_terminal = true; + } + }else{ + if((player_1_lives == 255) && (player_2_lives == 255)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Game over! Restarting." << std::endl; + } + m_terminal = true; + } + } + + // Get level information + m_current_level = (readRam(&system, 0xFC42) / 2) + 1; + m_end_level = system.settings()->getInt("SOR_end_level"); + +// int screen = readRam(&system, 0xFC02); + int m_progress_1 = readRam(&system, 0xFC44); + int m_progress_2 = readRam(&system, 0xFCCE); + + // Get boss information + int boss_health = readRam(&system, 0xF180); + int boss_lives = readRam(&system, 0xF182); + + if ((system.settings()->getBool("SOR_round_clear") == true) || (m_end_level == 8)){ + if (((m_current_level - 1) == m_end_level) && (m_progress_1 == 0) && (m_progress_2 > 10)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Round "<< m_end_level << " clear!" << std::endl; + } + m_terminal = true; + } + }// Level 1 + else if ((m_end_level == 1) && (m_current_level == 1)) { + if ((m_progress_1 == 12) && (m_progress_2 == 12) && ((boss_health + boss_lives) == 0)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 2 + else if ((m_end_level == 2) && (m_current_level == 2) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 12) && (m_progress_2 == 12)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 3 + else if ((m_end_level == 3) && (m_current_level == 3) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 16) && (m_progress_2 == 16)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 4 + else if ((m_end_level == 4) && (m_current_level == 4) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 22) && (m_progress_2 == 22)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 5 + else if ((m_end_level == 5) && (m_current_level == 5) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 10) && (m_progress_2 == 10)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 6 + else if ((m_end_level == 6) && (m_current_level == 6) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 10) && (m_progress_2 == 10)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 7 + else if ((m_end_level == 7) && (m_current_level == 7) && ((boss_health + boss_lives) == 0) ){ + if ((m_progress_1 == 18) && (m_progress_2 == 18)){ + if (system.settings()->getBool("SOR_verbose") == true){ + std::cout << "Beat level " << m_end_level << std::endl; + } + m_terminal = true; + } + }// Level 8 (see above) +} + +/* reset the state of the game */ +void StreetsOfRageII2PlayersSettings::reset() { + m_reward = 0; + m_score = 0; + m_terminal = false; +} + + +/* saves the state of the rom settings */ +void StreetsOfRageII2PlayersSettings::saveState( Serializer & ser ) { + ser.putInt(m_reward); + ser.putInt(m_score); + ser.putBool(m_terminal); +} + + +// loads the state of the rom settings +void StreetsOfRageII2PlayersSettings::loadState( Deserializer & des ) { + m_reward = des.getInt(); + m_score = des.getInt(); + m_terminal = des.getBool(); +} + + +ActionVect StreetsOfRageII2PlayersSettings::getStartingActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + + // wait for intro to end + INSERT_NOPS(5 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(0.4*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(0.5*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_DOWN) + INSERT_NOPS(0.5*num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(3 * num_of_nops) + // + string player_1 = system.settings()->getString("SOR_player_1_character"); + string player_2 = system.settings()->getString("SOR_player_2_character"); + + if(("axel" == player_1) && ("blaze" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("axel" == player_1) && ("skate" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("axel" == player_1) && ("max" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("blaze" == player_1) && ("skate" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + }else if(("blaze" == player_1) && ("max" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + }else if(("blaze" == player_1) && ("axel" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("max" == player_1) && ("blaze" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("max" == player_1) && ("axel" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("max" == player_1) && ("skate" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("skate" == player_1) && ("blaze" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("skate" == player_1) && ("axel" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + }else if(("skate" == player_1) && ("max" == player_2)){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_START, B) + } + return startingActions; +} + + void StreetsOfRageII2PlayersSettings::startingOperations(RleSystem& system){ + //set difficulty + m_difficulty = system.settings()->getInt("SOR_difficulty"); + if(0 == m_difficulty){ + // Also setting enemy health low (see above). + writeRam(&system, 0xFD04, 0x0); + }else if(1 == m_difficulty){ + writeRam(&system, 0xFD04, 0x0); + }else if(2 == m_difficulty){ + writeRam(&system, 0xFD04, 0x2); + }else if(3 == m_difficulty){ + writeRam(&system, 0xFD04, 0x4); + }else if(4 == m_difficulty){ + writeRam(&system, 0xFD04, 0x6); + }else if(5 == m_difficulty){ + writeRam(&system, 0xFD04, 0x8); + }else if(6 == m_difficulty){ + writeRam(&system, 0xFD04, 0x0A); + } + + // Set number of continues. By Default continues set to zero. + writeRam(&system,0xEFA4, 0x0); + writeRam(&system, 0xF0A4, 0x0); + + // Set start level + m_start_level = system.settings()->getInt("SOR_start_level"); + writeRam(&system, 0xFD0E, (m_start_level-1) * 0x1); + + // Set number of lives + m_lives = system.settings()->getInt("SOR_lives"); + writeRam(&system, 0xFD06, (m_lives-1) * 0x1); + } + + +ActionVect StreetsOfRageII2PlayersSettings::getExtraActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// wait for level to begin + INSERT_NOPS(4 * num_of_nops) + + return startingActions; +} diff --git a/src/games/supported/StreetsOfRageII2Players.hpp b/src/games/supported/StreetsOfRageII2Players.hpp new file mode 100644 index 0000000..0ac53f5 --- /dev/null +++ b/src/games/supported/StreetsOfRageII2Players.hpp @@ -0,0 +1,84 @@ +/* ***************************************************************************** + * The line 67 is based on Xitari's code, from Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ + +#ifndef __STREETS_OF_RAGE_II_TWO_PLAYERS_SETTINGS_HPP__ +#define __STREETS_OF_RAGE_II_TWO_PLAYERS_SETTINGS_HPP__ +/* RL wrapper for AtariCollection settings */ + +#include "../GenesisSettings.hpp" +#include + +namespace rle { + +class StreetsOfRageII2PlayersSettings : public GenesisSettings { + + public: + + StreetsOfRageII2PlayersSettings(); + + // reset + void reset(); + + // the rom-name + const char* rom() const { return "streets_of_rage_ii_2_players"; } + + // create a new instance of the rom + RomSettings* clone() const; + + // process the latest information from ALE + void step(const RleSystem& system); + + + // saves the state of the rom settings + void saveState( Serializer & ser ); + + + // loads the state of the rom settings + void loadState( Deserializer & des ); + + virtual const int lives() { return 0; } + + virtual ActionVect getStartingActions(const RleSystem& system); + + virtual ActionVect getExtraActions(const RleSystem& system); + + void startingOperations(RleSystem& system); + private: + reward_t m_score; + int m_difficulty; + int m_lives; + int m_start_level; + int m_end_level; + int m_current_level; + int player_1_lives; + int player_2_lives; + +}; + +} // namespace rle + +#endif // __STREETS_OF_RAGE_II_TWO_PLAYERS_SETTINGS_HPP__ diff --git a/src/games/supported/StreetsOfRageIII.cpp b/src/games/supported/StreetsOfRageIII.cpp new file mode 100644 index 0000000..9c41ceb --- /dev/null +++ b/src/games/supported/StreetsOfRageIII.cpp @@ -0,0 +1,361 @@ +/* ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ +#include "../RomUtils.hpp" +#include + +#include "../RomUtils.hpp" + +#include "RleSystem.hxx" +#include "RleException.h" + +#include "StreetsOfRageIII.hpp" +#include + + +using namespace rle; + + +StreetsOfRageIIISettings::StreetsOfRageIIISettings() { + reset(); + + minimalActions = {JOYPAD_NOOP, + JOYPAD_DOWN, //Walk down + JOYPAD_UP, // Walk up + JOYPAD_LEFT, // Walk left + JOYPAD_RIGHT, // Walk right + + JOYPAD_GENESIS_C, // Jump + JOYPAD_GENESIS_C | JOYPAD_LEFT, // Jump left + JOYPAD_GENESIS_C | JOYPAD_RIGHT, // Jump right + + JOYPAD_GENESIS_A, // Special attack + JOYPAD_LEFT | JOYPAD_GENESIS_A, + JOYPAD_RIGHT |JOYPAD_GENESIS_A, + + JOYPAD_GENESIS_B, // Regular attack + JOYPAD_GENESIS_B | JOYPAD_GENESIS_C, // Rear attack or Super slam + JOYPAD_GENESIS_B | JOYPAD_LEFT,//Blitz attack or + JOYPAD_GENESIS_B | JOYPAD_RIGHT, + + }; +} + + +/* create a new instance of the rom */ +RomSettings* StreetsOfRageIIISettings::clone() const { + RomSettings* rval = new StreetsOfRageIIISettings(); + *rval = *this; + return rval; +} + + +void StreetsOfRageIIISettings::step(const RleSystem& system) { +// if (readRam(&system, 0xFB00) != 14){ +// m_terminal = true; +// } + +// Begin code for testing + if(system.settings()->getBool("SOR_test") == true){ + + // Fix Agent health + writeRam(&system, 0xDF6D, 0x34); + + // Make invincible + writeRam(&system, 0xDF5D, 0xFF); + + // Freeze Time + // writeRam(&system, 0xFC3C, 0x99); +} + +// This setting gives all enemies minimal health and lives + if((system.settings()->getBool("SOR_test") == true) || system.settings()->getInt("SOR_difficulty") == 0){ + // Fix enemy health and lives + + writeRam(&system, 0xE16D, 0x0); + writeRam(&system, 0xE26D, 0x0); + writeRam(&system, 0xE36D, 0x0); + writeRam(&system, 0xE46D, 0x0); + writeRam(&system, 0xE56D, 0x0); + writeRam(&system, 0xE66D, 0x0); + + // writeRam(&system, 0xE18B, 0x0); + // writeRam(&system, 0xE28B, 0x0); + // writeRam(&system, 0xE38B, 0x0); + // writeRam(&system, 0xE48B, 0x0); + // writeRam(&system, 0xE58B, 0x0); + + } +// End code for testing + +// Read out current score, health, lives, kills +// Score set to 0. Will read score from rle/gym wrapper + reward_t score = 0; //getDecimalScore(0xEF99, 0xEF96, &system); + +// update the reward + m_reward = score - m_score; + m_score = score; + + + if ((readRam(&system, 0xDFA1) == 255) && readRam(&system, 0xFB00) == 14){ + // m_screen = 2; + std::cout << "LOST GAME" << std::endl; + m_terminal = true; + } + + // Get level information + m_current_level = readRam(&system, 0xFB04) + 1; + m_end_level = system.settings()->getInt("SOR_end_level"); + + // Get information on agent position + int m_position = 256 * readRam(&system, 0xDF41) + readRam(&system, 0xDF40); + int scene = readRam(&system, 0xFB02); + m_screen = readRam(&system, 0xFB00); + + // Get boss information + int boss_1_ID = readRam(&system, 0xE10C); + int boss_present = readRam(&system, 0xE10C) + readRam(&system, 0xE20C) + readRam(&system, 0xE30C); + int boss_1_health = readRam(&system, 0xE16D); + int boss_2_health = readRam(&system, 0xE26D); + int boss_3_health = readRam(&system, 0xE36D); + int boss_health = boss_1_health + boss_2_health + boss_3_health; + int boss_1_lives = readRam(&system, 0xE18A); + int boss_lives = readRam(&system, 0xE18A) + readRam(&system, 0xE28A) + readRam(&system, 0xE38A); + + // Win if we accidentily go past the end level + if(m_end_level < m_current_level){ + std::cout << "ADVANCED TO NEXT LEVEL" << std::endl; + m_terminal = true; + } + // Win if round clear + if ((system.settings()->getBool("SOR_round_clear") == true) && ((m_current_level != 7) || (m_current_level != 8))){ + if ((m_end_level == m_current_level) && (readRam(&system, 0xFB00) == 46)){ + std::cout << "ROUND CLEAR!" << std::endl; + m_terminal = true; + } + }else{ + // Win if agent is in right place, with bosses present, and bosses dead + if((m_end_level == 1) && (m_current_level == 1)){ + if ((scene == 2) && (m_position > 456) && (boss_present > 0) && ((boss_1_health + boss_1_lives == 0))){ + m_terminal = true; + } + }else if ((m_end_level == 2) && (m_current_level == 2)){ + if ((scene == 2) && (m_position > 100) && (boss_present > 0) && ((boss_health + boss_lives) == 0) ){ + std::cout << " won game!" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 3) && (m_current_level == 3)){ + if ((scene == 2) && (m_position > 400) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 4) && (m_current_level == 4)){ + if ((scene == 2) && (m_position> 300) && (boss_present > 0) && ((boss_1_health + boss_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 5) && (m_current_level == 5)){ + if ((scene == 7) && (m_position > 30) && (boss_1_ID == 56) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 6) && (m_current_level == 6)){ + if ((scene == 7) && (m_position > 50) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 7) && (m_current_level == 7)){ + if ((scene == 4) && (m_position > 30) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 8) && (m_current_level == 8)){ + if ((scene == 3) && (m_position > 30) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + } + + } +} + + +/* reset the state of the game */ +void StreetsOfRageIIISettings::reset() { + m_reward = 0; + m_score = 0; + m_terminal = false; +} + + +/* saves the state of the rom settings */ +void StreetsOfRageIIISettings::saveState( Serializer & ser ) { + ser.putInt(m_reward); + ser.putInt(m_score); + ser.putBool(m_terminal); +} + + +// loads the state of the rom settings +void StreetsOfRageIIISettings::loadState( Deserializer & des ) { + m_reward = des.getInt(); + m_score = des.getInt(); + m_terminal = des.getBool(); +} + + +ActionVect StreetsOfRageIIISettings::getStartingActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// Wait for intro to end + INSERT_NOPS((3 - readRam(&system, 0xFB00)) * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + +// // // // Choose Player 1 character + string player_1_character = system.settings()->getString("SOR_player_1_character"); + if("axel" == player_1_character){ + //INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("zan" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_LEFT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + // INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("blaze" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + // INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if("skate" == player_1_character){ + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + INSERT_ACTION_SINGLE_A(JOYPAD_RIGHT) + INSERT_ACTION_SINGLE_A(JOYPAD_NOOP) + // INSERT_ACTION_SINGLE_A(JOYPAD_START) + } + INSERT_NOPS(1 * num_of_nops) + +return startingActions; +} + + +void StreetsOfRageIIISettings::startingOperations(RleSystem& system){ + /*This function sets the difficulty, number of continues, starting level, + and number of lives by writing directly to RAM*/ + + //set difficulty + m_difficulty = system.settings()->getInt("SOR_difficulty"); + // Also setting enemy health low (see above). + if(0 == m_difficulty){ + writeRam(&system, 0xFF08, 0x2); + }else if(1 == m_difficulty){ + writeRam(&system, 0xFF08, 0x2); + }else if(2 == m_difficulty){ + writeRam(&system, 0xFF08, 0x4); + }else if(3 == m_difficulty){ + writeRam(&system, 0xFF08, 0x6); + }else if(4 == m_difficulty){ + writeRam(&system, 0xFF08, 0x8); + }else if(5 == m_difficulty){ + writeRam(&system, 0xFF08, 0x0A); + } + + //set number of continues. By Default continues set to zero. + writeRam(&system, 0xDFA0, 0x1); + + // //set start level for testing or to access Levels 7 and 8 + m_start_level = system.settings()->getInt("SOR_start_level"); + if(m_start_level == 1){ + writeRam(&system, 0xFB04, 0x0); + }else if(m_start_level == 2){ + writeRam(&system, 0xFB04, 0x1); + }else if(m_start_level == 3){ + writeRam(&system, 0xFB04, 0x2); + }else if(m_start_level == 4){ + writeRam(&system, 0xFB04, 0x3); + }else if (m_start_level == 5){ + writeRam(&system, 0xFB04, 0x4); + }else if (m_start_level == 6){ + writeRam(&system, 0xFB04, 0x5); + }else if(m_start_level == 7){ + writeRam(&system, 0xFB04, 0x6); + writeRam(&system, 0xFB02, 0x1); + }else if (m_start_level == 8){ + writeRam(&system, 0xFB04, 0x7); + writeRam(&system, 0xFB02, 0x1); + } + + if(system.settings()->getBool("SOR_test") == true){ + // Max out the difficulty + writeRam(&system, 0xFF08, 0x0A); + // Go to the last scene of the chosen level + if(m_start_level == 1){ + writeRam(&system, 0xFB02, 0x2); + }else if(m_start_level == 2){ + writeRam(&system, 0xFB02, 0x2); + }else if(m_start_level == 3){ + writeRam(&system, 0xFB02, 0x2); + }else if(m_start_level == 4){ + writeRam(&system, 0xFB02, 0x2); + }else if (m_start_level == 5){ + writeRam(&system, 0xFB02, 0x7); + }else if (m_start_level == 6){ + writeRam(&system, 0xFB02, 0x7); + }else if(m_start_level == 7){ + writeRam(&system, 0xFB02, 0x4); + }else if (m_start_level == 8){ + writeRam(&system, 0xFB02, 0x3); + } + } + + // // Set number of lives + m_lives = system.settings()->getInt("SOR_lives"); + writeRam(&system, 0xDF8A, m_lives * 0x1); +} + +ActionVect StreetsOfRageIIISettings::getExtraActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + + INSERT_NOPS(1 * num_of_nops) + + INSERT_ACTION_SINGLE_A(JOYPAD_START) +// +// // wait for level to begin + int start_level = system.settings()->getInt("SOR_start_level"); + if (start_level == 1){ + INSERT_NOPS(3 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(4 * num_of_nops) + }else if (start_level == 2){ + INSERT_NOPS(3.5 * num_of_nops) + }else if (start_level == 3){ + INSERT_NOPS(4.6 * num_of_nops) + }else if (start_level ==4){ + INSERT_NOPS(3.7 * num_of_nops) + }else if (start_level == 5){ + INSERT_NOPS(3.7 * num_of_nops) + }else if (start_level == 6){ + INSERT_NOPS(3.7 * num_of_nops) + }else if (start_level == 7){ + INSERT_NOPS(1 * num_of_nops) + }else if (start_level == 8){ + INSERT_NOPS(4 * num_of_nops) + } + + return startingActions; +} diff --git a/src/games/supported/StreetsOfRageIII.hpp b/src/games/supported/StreetsOfRageIII.hpp new file mode 100644 index 0000000..95734a2 --- /dev/null +++ b/src/games/supported/StreetsOfRageIII.hpp @@ -0,0 +1,84 @@ +/* ***************************************************************************** + * The line 67 is based on Xitari's code, from Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ + +#ifndef __STREETS_OF_RAGE_III_SETTINGS_HPP__ +#define __STREETS_OF_RAGE_III_SETTINGS_HPP__ +/* RL wrapper for AtariCollection settings */ + +#include "../GenesisSettings.hpp" +#include + +namespace rle { + +class StreetsOfRageIIISettings : public GenesisSettings { + + public: + + StreetsOfRageIIISettings(); + + // reset + void reset(); + + // the rom-name + const char* rom() const { return "streets_of_rage_iii"; } + + // create a new instance of the rom + RomSettings* clone() const; + + // process the latest information from ALE + void step(const RleSystem& system); + + + // saves the state of the rom settings + void saveState( Serializer & ser ); + + + // loads the state of the rom settings + void loadState( Deserializer & des ); + + + virtual const int lives() { return 0; } + + virtual ActionVect getStartingActions(const RleSystem& system); + virtual ActionVect getExtraActions(const RleSystem& system); + + void startingOperations(RleSystem& system); + private: + reward_t m_score; + int m_start_level; + int m_end_level; + int m_current_level; + int m_lives; + int m_health; + int m_difficulty; + int m_screen; + +}; + +} // namespace rle + +#endif // __STREETS_OF_RAGE_III_SETTINGS_HPP__ diff --git a/src/games/supported/StreetsOfRageIII2Players.cpp b/src/games/supported/StreetsOfRageIII2Players.cpp new file mode 100644 index 0000000..84d5bc5 --- /dev/null +++ b/src/games/supported/StreetsOfRageIII2Players.cpp @@ -0,0 +1,412 @@ +/* ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ +#include "../RomUtils.hpp" +#include + +#include "../RomUtils.hpp" + +#include "RleSystem.hxx" +#include "RleException.h" + +#include "StreetsOfRageIII2Players.hpp" +#include + + +using namespace rle; + + +StreetsOfRageIII2PlayersSettings::StreetsOfRageIII2PlayersSettings() { + reset(); + + minimalActions = {JOYPAD_NOOP, + JOYPAD_DOWN, //Walk down + JOYPAD_UP, // Walk up + JOYPAD_LEFT, // Walk left + JOYPAD_RIGHT, // Walk right + + JOYPAD_GENESIS_C, // Jump + JOYPAD_GENESIS_C | JOYPAD_LEFT, // Jump left + JOYPAD_GENESIS_C | JOYPAD_RIGHT, // Jump right + + JOYPAD_GENESIS_A, // Special attack + JOYPAD_LEFT | JOYPAD_GENESIS_A, + JOYPAD_RIGHT |JOYPAD_GENESIS_A, + + JOYPAD_GENESIS_B, // Regular attack + JOYPAD_GENESIS_B | JOYPAD_GENESIS_C, // Rear attack or Super slam + JOYPAD_GENESIS_B | JOYPAD_LEFT,//Blitz attack or + JOYPAD_GENESIS_B | JOYPAD_RIGHT, + + }; +} + + +/* create a new instance of the rom */ +RomSettings* StreetsOfRageIII2PlayersSettings::clone() const { + RomSettings* rval = new StreetsOfRageIII2PlayersSettings(); + *rval = *this; + return rval; +} + + +void StreetsOfRageIII2PlayersSettings::step(const RleSystem& system) { +// Begin code for testing + if(system.settings()->getBool("SOR_test") == true){ + + // Fix Agent health + writeRam(&system, 0xDF6D, 0x34); + + // Make invincible + writeRam(&system, 0xDF5D, 0xFF); + + // Freeze Time + // writeRam(&system, 0xFC3C, 0x99); +} + +// This setting gives all enemies minimal health and lives + if((system.settings()->getBool("SOR_test") == true) || system.settings()->getInt("SOR_difficulty") == 0){ + // Fix enemy health + writeRam(&system, 0xE16D, 0x0); + writeRam(&system, 0xE26D, 0x0); + writeRam(&system, 0xE36D, 0x0); + writeRam(&system, 0xE46D, 0x0); + writeRam(&system, 0xE56D, 0x0); + writeRam(&system, 0xE66D, 0x0); + + } +// End code for testing + +// Read out current score, health, lives, kills +// Score set to 0. Will read score from rle/gym wrapper + reward_t score = 0; //getDecimalScore(0xEF99, 0xEF96, &system); + player_1_lives = readRam(&system, 0xDFA1); + player_2_lives = readRam(&system, 0xE0A1); +// update the reward + m_reward = score - m_score; + m_score = score; + + + if (system.settings()->getBool("SOR_2p_terminal_both_win") == true){ + if (((player_1_lives == 255) || (player_2_lives == 255)) && (readRam(&system, 0xFB00) == 14)){ + m_terminal = true; + } + }else{ + if ((player_1_lives == 255) && (player_2_lives == 255) && ((readRam(&system, 0xFB00) == 14))) + m_terminal = true; + } + + + + + + // Get level information + m_current_level = readRam(&system, 0xFB04) + 1; + m_end_level = system.settings()->getInt("SOR_end_level"); + + // Get information on agent position + int m_position = 256 * readRam(&system, 0xDF41) + readRam(&system, 0xDF40); + int scene = readRam(&system, 0xFB02); + m_screen = readRam(&system, 0xFB00); + + // Get boss information + int boss_1_ID = readRam(&system, 0xE10C); + int boss_present = readRam(&system, 0xE10C) + readRam(&system, 0xE20C) + readRam(&system, 0xE30C); + int boss_1_health = readRam(&system, 0xE16D); + int boss_2_health = readRam(&system, 0xE26D); + int boss_3_health = readRam(&system, 0xE36D); + int boss_health = boss_1_health + boss_2_health + boss_3_health; + int boss_1_lives = readRam(&system, 0xE18A); + int boss_lives = readRam(&system, 0xE18A) + readRam(&system, 0xE28A) + readRam(&system, 0xE38A); + + // Win if we accidentily go past the end level + if(m_end_level < m_current_level){ + std::cout << "ADVANCED TO NEXT LEVEL" << std::endl; + m_terminal = true; + } + // Win if round clear + if ((system.settings()->getBool("SOR_round_clear") == true) && ((m_current_level != 7) || (m_current_level != 8))){ + if ((m_end_level == m_current_level) && (readRam(&system, 0xFB00) == 46)){ + std::cout << "ROUND CLEAR!" << std::endl; + m_terminal = true; + } + }else{ + // Win if agent is in right place, with bosses present, and bosses dead + if((m_end_level == 1) && (m_current_level == 1)){ + if ((scene == 2) && (m_position > 456) && (boss_present > 0) && ((boss_1_health + boss_1_lives == 0))){ + m_terminal = true; + } + }else if ((m_end_level == 2) && (m_current_level == 2)){ + if ((scene == 2) && (m_position > 100) && (boss_present > 0) && ((boss_health + boss_lives) == 0) ){ + std::cout << " won game!" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 3) && (m_current_level == 3)){ + if ((scene == 2) && (m_position > 400) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 4) && (m_current_level == 4)){ + if ((scene == 2) && (m_position> 300) && (boss_present > 0) && ((boss_1_health + boss_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 5) && (m_current_level == 5)){ + if ((scene == 7) && (m_position > 30) && (boss_1_ID == 56) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 6) && (m_current_level == 6)){ + if ((scene == 7) && (m_position > 50) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 7) && (m_current_level == 7)){ + if ((scene == 4) && (m_position > 30) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + }else if ((m_end_level == 8) && (m_current_level == 8)){ + if ((scene == 3) && (m_position > 30) && (boss_present > 0) && ((boss_1_health + boss_1_lives) == 0)){ + std::cout << "won game" << std::endl; + m_terminal = true; + } + } + + } +} + + +/* reset the state of the game */ +void StreetsOfRageIII2PlayersSettings::reset() { + m_reward = 0; + m_score = 0; + m_terminal = false; +} + + +/* saves the state of the rom settings */ +void StreetsOfRageIII2PlayersSettings::saveState( Serializer & ser ) { + ser.putInt(m_reward); + ser.putInt(m_score); + ser.putBool(m_terminal); +} + + +// loads the state of the rom settings +void StreetsOfRageIII2PlayersSettings::loadState( Deserializer & des ) { + m_reward = des.getInt(); + m_score = des.getInt(); + m_terminal = des.getBool(); +} + + +ActionVect StreetsOfRageIII2PlayersSettings::getStartingActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + +// // Wait for intro to end + INSERT_NOPS((3 - readRam(&system, 0xFB00)) * num_of_nops) + + INSERT_ACTION_SINGLE_A(JOYPAD_START) + + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + + INSERT_ACTION_SINGLE_A(JOYPAD_DOWN) + INSERT_NOPS(0.5 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(2 * num_of_nops) + +// // // // Choose Player 1 character + string player_1 = system.settings()->getString("SOR_player_1_character"); + string player_2 = system.settings()->getString("SOR_player_2_character"); + + if((player_1 == "axel") && (player_2 == "blaze")){ + //INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if((player_1 == "axel") && (player_2 == "skate")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + // INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if((player_1 == "axel") && (player_2 == "zan")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + // INSERT_ACTION_SINGLE_A(JOYPAD_START) + }else if((player_1 == "zan") && (player_2 == "blaze")){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + }else if ((player_1 == "zan") && (player_2 == "skate")){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + }else if ((player_1 == "zan") && (player_2 == "axel")){ + INSERT_ACTION_SINGLE(JOYPAD_LEFT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + }else if((player_1 == "skate") && (player_2 == "blaze")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + }else if((player_1 == "skate") && (player_2 == "axel")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + }else if((player_1 == "skate") && (player_2 == "zan")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + }else if((player_1 == "blaze") && (player_2 == "skate")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + }else if ((player_1 == "blaze") && (player_2 == "zan")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + }else if ((player_1 == "blaze") && (player_2 == "axel")){ + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + INSERT_ACTION_SINGLE(JOYPAD_RIGHT, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) + } + + INSERT_NOPS(1 * num_of_nops) + +return startingActions; +} + + +void StreetsOfRageIII2PlayersSettings::startingOperations(RleSystem& system){ + /*This function sets the difficulty, number of continues, starting level, + and number of lives by writing directly to RAM*/ + + //set difficulty + m_difficulty = system.settings()->getInt("SOR_difficulty"); + // Also setting enemy health low (see above). + if(0 == m_difficulty){ + writeRam(&system, 0xFF08, 0x2); + }else if(1 == m_difficulty){ + writeRam(&system, 0xFF08, 0x2); + }else if(2 == m_difficulty){ + writeRam(&system, 0xFF08, 0x4); + }else if(3 == m_difficulty){ + writeRam(&system, 0xFF08, 0x6); + }else if(4 == m_difficulty){ + writeRam(&system, 0xFF08, 0x8); + }else if(5 == m_difficulty){ + writeRam(&system, 0xFF08, 0x0A); + } + + //set number of continues. By Default continues set to zero. + writeRam(&system, 0xDFA0, 0x1); + writeRam(&system, 0xE0A0, 0x1); + + // //set start level for testing or to access Levels 7 and 8 + m_start_level = system.settings()->getInt("SOR_start_level"); + if(m_start_level == 1){ + writeRam(&system, 0xFB04, 0x0); + }else if(m_start_level == 2){ + writeRam(&system, 0xFB04, 0x1); + }else if(m_start_level == 3){ + writeRam(&system, 0xFB04, 0x2); + }else if(m_start_level == 4){ + writeRam(&system, 0xFB04, 0x3); + }else if (m_start_level == 5){ + writeRam(&system, 0xFB04, 0x4); + }else if (m_start_level == 6){ + writeRam(&system, 0xFB04, 0x5); + }else if(m_start_level == 7){ + writeRam(&system, 0xFB04, 0x6); + writeRam(&system, 0xFB02, 0x1); + }else if (m_start_level == 8){ + writeRam(&system, 0xFB04, 0x7); + writeRam(&system, 0xFB02, 0x1); + } + + if(system.settings()->getBool("SOR_test") == true){ + // Max out the difficulty + writeRam(&system, 0xFF08, 0x0A); + // Go to the last scene of the chosen level + if(m_start_level == 1){ + writeRam(&system, 0xFB02, 0x2); + }else if(m_start_level == 2){ + writeRam(&system, 0xFB02, 0x2); + }else if(m_start_level == 3){ + writeRam(&system, 0xFB02, 0x2); + }else if(m_start_level == 4){ + writeRam(&system, 0xFB02, 0x2); + }else if (m_start_level == 5){ + writeRam(&system, 0xFB02, 0x7); + }else if (m_start_level == 6){ + writeRam(&system, 0xFB02, 0x7); + }else if(m_start_level == 7){ + writeRam(&system, 0xFB02, 0x4); + }else if (m_start_level == 8){ + writeRam(&system, 0xFB02, 0x3); + } + } + + // // Set number of lives + int m_lives = system.settings()->getInt("SOR_lives"); + writeRam(&system, 0xDF8A, m_lives * 0x1); + writeRam(&system, 0xE08A, m_lives * 0x1); +} + +ActionVect StreetsOfRageIII2PlayersSettings::getExtraActions(const RleSystem& system){ + int num_of_nops(100); + ActionVect startingActions; + + INSERT_NOPS(1 * num_of_nops) + + INSERT_ACTION_SINGLE(JOYPAD_START, A) + INSERT_ACTION_SINGLE(JOYPAD_NOOP, A) + INSERT_ACTION_SINGLE(JOYPAD_START, B) +// +// // wait for level to begin + int start_level = system.settings()->getInt("SOR_start_level"); + if (start_level == 1){ + INSERT_NOPS(3 * num_of_nops) + INSERT_ACTION_SINGLE_A(JOYPAD_START) + INSERT_NOPS(4 * num_of_nops) + }else if (start_level == 2){ + INSERT_NOPS(3.5 * num_of_nops) + }else if (start_level == 3){ + INSERT_NOPS(4.6 * num_of_nops) + }else if (start_level ==4){ + INSERT_NOPS(3.7 * num_of_nops) + }else if (start_level == 5){ + INSERT_NOPS(3.7 * num_of_nops) + }else if (start_level == 6){ + INSERT_NOPS(3.7 * num_of_nops) + }else if (start_level == 7){ + INSERT_NOPS(1 * num_of_nops) + }else if (start_level == 8){ + INSERT_NOPS(4 * num_of_nops) + } + + return startingActions; +} diff --git a/src/games/supported/StreetsOfRageIII2Players.hpp b/src/games/supported/StreetsOfRageIII2Players.hpp new file mode 100644 index 0000000..8304132 --- /dev/null +++ b/src/games/supported/StreetsOfRageIII2Players.hpp @@ -0,0 +1,86 @@ +/* ***************************************************************************** + * The line 67 is based on Xitari's code, from Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * ***************************************************************************** + * A.L.E (Arcade Learning Environment) + * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and + * the Reinforcement Learning and Artificial Intelligence Laboratory + * Released under the GNU General Public License; see License.txt for details. + * + * Based on: Stella -- "An Atari 2600 VCS Emulator" + * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * + * ***************************************************************************** + */ + +#ifndef __STREETS_OF_RAGE_III_TWO_PLAYERS_SETTINGS_HPP__ +#define __STREETS_OF_RAGE_III_TWO_PLAYERS_SETTINGS_HPP__ +/* RL wrapper for AtariCollection settings */ + +#include "../GenesisSettings.hpp" +#include + +namespace rle { + +class StreetsOfRageIII2PlayersSettings : public GenesisSettings { + + public: + + StreetsOfRageIII2PlayersSettings(); + + // reset + void reset(); + + // the rom-name + const char* rom() const { return "streets_of_rage_iii_2_players"; } + + // create a new instance of the rom + RomSettings* clone() const; + + // process the latest information from ALE + void step(const RleSystem& system); + + + // saves the state of the rom settings + void saveState( Serializer & ser ); + + + // loads the state of the rom settings + void loadState( Deserializer & des ); + + + virtual const int lives() { return 0; } + + virtual ActionVect getStartingActions(const RleSystem& system); + virtual ActionVect getExtraActions(const RleSystem& system); + + void startingOperations(RleSystem& system); + private: + reward_t m_score; + int m_start_level; + int m_end_level; + int m_current_level; + int player_1_lives; + int player_2_lives; + int player_1_health; + int player_2_health; + int m_difficulty; + int m_screen; + +}; + +} // namespace rle + +#endif // __STREETS_OF_RAGE_III_TWO_PLAYERS_SETTINGS_HPP__