Commit ffd91dbd authored by Bkg2k's avatar Bkg2k Committed by OyyoDams

Resolve "Demo more runs often the same games"

parent 49d71a84
......@@ -10,7 +10,8 @@ DemoMode::DemoMode(Window& window)
: mWindow(window),
mSettings(*Settings::getInstance()),
mRecalboxConf(*RecalboxConf::getInstance()),
mRandomGenerator(mRandomRevice())
mRandomGenerator(mRandomRevice()),
mGameRandomizer(0, 1 << 30)
{
// Default duration
mDefaultDuration = (int)mRecalboxConf.getUInt("global.demo.duration", 90);
......@@ -40,6 +41,16 @@ DemoMode::DemoMode(Window& window)
mDemoSystems.push_back(allSystems[i]);
mDurations.push_back(mDefaultDuration);
}
// Set system randomizer
mSystemRandomizer = std::uniform_int_distribution<int>(0, (int)mDemoSystems.size() - 1);
// Reset histories
for(int s = (int)PlatformIds::PLATFORM_COUNT; --s >= 0; )
{
mSystemHistory[s] = -1;
for (int g = MAX_HISTORY; --g >= 0;)
mGameHistories[s][g] = -1;
}
}
bool DemoMode::hasDemoMode()
......@@ -47,53 +58,66 @@ bool DemoMode::hasDemoMode()
return (mSettings.getString("ScreenSaverBehavior") == "demo");
}
bool DemoMode::getRandomSystem(SystemData*& outputSystem, int& outputDuration)
bool DemoMode::isInHistory(int item, int history[], int maxitems)
{
int max = MAX_HISTORY < maxitems ? MAX_HISTORY : maxitems;
for(int i = max; --i >= 0; )
if (history[i] == item)
return true;
return false;
}
void DemoMode::insertIntoHistory(int item, int history[])
{
memmove(&history[1], &history[0], (MAX_HISTORY - 1) * sizeof(int));
history[0] = item;
}
bool DemoMode::getRandomSystem(int& outputSystemIndex, int& outputDuration)
{
if (mDemoSystems.empty()) return false;
std::uniform_int_distribution<int> random(0, (int)mDemoSystems.size() - 1);
for (int i=5; --i>=0; ) // Maximum 5 tries to find a new game to launch
for (int i = (int)PlatformIds::PLATFORM_COUNT; --i >= 0; )
{
// Select random system
int randomPosition = random(mRandomGenerator);
outputSystem = mDemoSystems[randomPosition];
outputDuration = mDurations[randomPosition];
std::string outputName = outputSystem->getName();
outputSystemIndex = mSystemRandomizer(mRandomGenerator);
outputDuration = mDurations[outputSystemIndex];
if ((outputName != mLastSystem) || (mDemoSystems.size() == 1))
if (!isInHistory(outputSystemIndex, mSystemHistory, (int)mDemoSystems.size()) || (mDemoSystems.size() == 1))
{
// Set new game path
mLastSystem = outputName;
// Save history
insertIntoHistory(outputSystemIndex, mSystemHistory);
break;
}
// No luck, try again
}
LOG(LogInfo) << "Randomly selected system: " << outputSystem->getName();
//std::cout << "Randomly selected system: " << outputSystem->getName() << "\r\n";
LOG(LogInfo) << "Randomly selected system: " << mDemoSystems[outputSystemIndex]->getName();
//std::cout << "Randomly selected system: " << mDemoSystems[outputSystemIndex]->getName() << "\r\n";
return true;
}
bool DemoMode::getRandomGame(FileData*& outputGame, int& outputDuration)
{
SystemData* system = nullptr;
if (!getRandomSystem(system, outputDuration)) return false;
int systemIndex = 0;
if (!getRandomSystem(systemIndex, outputDuration)) return false;
SystemData* system = mDemoSystems[systemIndex];
// Get filelist
FileData::List gamelist = system->getRootFolder()->getAllDisplayableItemsRecursively(false);
if (gamelist.empty()) return false;
FileData::List gameList = system->getRootFolder()->getAllDisplayableItemsRecursively(false);
if (gameList.empty()) return false;
std::uniform_int_distribution<int> random(0, (int)gamelist.size() - 1);
for (int i=5; --i>=0; ) // Maximum 5 tries to find a new game to launch
for (int i = MAX_HISTORY; --i >= 0; )
{
// Select game
outputGame = gamelist[random(mRandomGenerator)];
std::string outputPath = outputGame->getPath().generic_string();
int gamePosition = mGameRandomizer(mRandomGenerator) % (int)gameList.size();
outputGame = gameList[gamePosition];
if ((outputPath != mLastGamePath) || (gamelist.size() == 1))
if (!isInHistory(gamePosition, mGameHistories[systemIndex], (int)gameList.size()) || (gameList.size() == 1))
{
// Set new game path
mLastGamePath = outputPath;
// Save history
insertIntoHistory(gamePosition, mGameHistories[systemIndex]);
break;
}
// No luck, try again
......
......@@ -6,6 +6,7 @@
#include "RecalboxConf.h"
#include "SystemData.h"
#include "FileData.h"
#include "PlatformId.h"
class DemoMode
{
......@@ -28,31 +29,58 @@ class DemoMode
//! Duration of game session per system
std::vector<int> mDurations;
//! Previously selected game path
std::string mLastGamePath;
//! Previously selected system
std::string mLastSystem;
//! Random device to seed random generator
std::random_device mRandomRevice;
//! Random generator
std::mt19937 mRandomGenerator;
//! Random repartition (system)
std::uniform_int_distribution<int> mSystemRandomizer;
//! Random repartition (game)
std::uniform_int_distribution<int> mGameRandomizer;
//! History deepness
static constexpr int MAX_HISTORY = 10;
//! Game History
int mGameHistories[(int)PlatformIds::PLATFORM_COUNT][MAX_HISTORY];
//! Previously selected system
int mSystemHistory[MAX_HISTORY];
/*!
* @brief Check if an item is in its history records
* @param item item to seek for
* @param history history records
* @param maxitems Maximum items
* @return True if the item is in the history records, false otherwise
*/
bool isInHistory(int item, int history[], int maxitems);
/*!
* @brief Insert an item into its history records
* @param item Item to insert
* @param history History records
*/
void insertIntoHistory(int item, int history[]);
/*!
* @brief Get next random game
* @return Game structure or nullptr if no game is available
* @param outputGame Selected game
* @param outputDuration Session Duration
* @return True if a game is available.
*/
/*!
* @brief Get next random game
* @param outputGame Choosen game
* @param outputDuration Session Duration
* @return True if a game is available.
*/
bool getRandomGame(FileData*& outputGame, int& outputDuration);
bool getRandomSystem(SystemData*& outputSystem, int& outputDuration);
/*!
* @brief Get next system
* @param outputSystemIndex Selected system index
* @param outputDuration Session Duration
* @return True if a system is available.
*/
bool getRandomSystem(int& outputSystemIndex, int& outputDuration);
public:
//! Default constructor
DemoMode(Window& window);
/*!
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment