Skip to content

Commit

Permalink
"Deck of cards" shuffling of systems and games
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaz82 committed Jul 8, 2021
1 parent 7029c91 commit 9bb203b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 27 deletions.
59 changes: 32 additions & 27 deletions es-app/src/SystemData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using namespace Utils;

std::vector<SystemData*> SystemData::sSystemVector;
std::vector<SystemData*> SystemData::sSystemVectorShuffled;
std::ranlux48 SystemData::sURBG = std::ranlux48(std::random_device()());

SystemData::SystemData(const std::string& name, const std::string& fullName, SystemEnvironmentData* envData, const std::string& themeFolder, bool CollectionSystem) :
mName(name), mFullName(fullName), mEnvData(envData), mThemeFolder(themeFolder), mIsCollectionSystem(CollectionSystem), mIsGameSystem(true)
Expand Down Expand Up @@ -533,29 +535,20 @@ unsigned int SystemData::getGameCount() const

SystemData* SystemData::getRandomSystem()
{
// this is a bit brute force. It might be more efficient to just to a while (!gameSystem) do random again...
unsigned int total = 0;
for(auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); it++)
if(sSystemVectorShuffled.empty())
{
if ((*it)->isGameSystem())
total ++;
if(!sSystemVector.empty())
{
sSystemVectorShuffled = sSystemVector;
std::shuffle(sSystemVectorShuffled.begin(), sSystemVectorShuffled.end(), sURBG);
}
}

// get random number in range
int target = (int)Math::round((std::rand() / (float)RAND_MAX) * (total - 1));
for (auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); it++)
if(!sSystemVectorShuffled.empty())
{
if ((*it)->isGameSystem())
{
if (target > 0)
{
target--;
}
else
{
return (*it);
}
}
SystemData* random_system = sSystemVectorShuffled.back();
sSystemVectorShuffled.pop_back();
return random_system;
}

// if we end up here, there is no valid system
Expand All @@ -564,14 +557,26 @@ SystemData* SystemData::getRandomSystem()

FileData* SystemData::getRandomGame()
{
std::vector<FileData*> list = mRootFolder->getFilesRecursive(GAME, true);
unsigned int total = (int)list.size();
int target = 0;
// get random number in range
if (total == 0)
return NULL;
target = (int)Math::round((std::rand() / (float)RAND_MAX) * (total - 1));
return list.at(target);
if(mGameVectorShuffled.empty())
{
std::vector<FileData*> gameVector = mRootFolder->getFilesRecursive(GAME, true);

if(!gameVector.empty())
{
mGameVectorShuffled = gameVector;
std::shuffle(mGameVectorShuffled.begin(), mGameVectorShuffled.end(), sURBG);
}
}

if(!mGameVectorShuffled.empty())
{
FileData* random_game = mGameVectorShuffled.back();
mGameVectorShuffled.pop_back();
return random_game;
}

// if we end up here, there is no valid game
return NULL;
}

unsigned int SystemData::getDisplayedGameCount() const
Expand Down
5 changes: 5 additions & 0 deletions es-app/src/SystemData.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "PlatformId.h"
#include <algorithm>
#include <memory>
#include <random>
#include <string>
#include <vector>

Expand Down Expand Up @@ -54,6 +55,8 @@ class SystemData
static std::string getConfigPath(bool forWrite); // if forWrite, will only return ~/.emulationstation/es_systems.cfg, never /etc/emulationstation/es_systems.cfg

static std::vector<SystemData*> sSystemVector;
static std::vector<SystemData*> sSystemVectorShuffled;
static std::ranlux48 sURBG;

inline std::vector<SystemData*>::const_iterator getIterator() const { return std::find(sSystemVector.cbegin(), sSystemVector.cend(), this); };
inline std::vector<SystemData*>::const_reverse_iterator getRevIterator() const { return std::find(sSystemVector.crbegin(), sSystemVector.crend(), this); };
Expand Down Expand Up @@ -92,6 +95,8 @@ class SystemData
FileFilterIndex* mFilterIndex;

FileData* mRootFolder;

std::vector<FileData*> mGameVectorShuffled;
};

#endif // ES_APP_SYSTEM_DATA_H

0 comments on commit 9bb203b

Please sign in to comment.