# include "pixelGameEngine.h"
# include "olcPGEX_QuickGUI.h"
# include <set>
using namespace olc ;
QuickGUI : : TextBox * prevTextBox = nullptr ;
// Override base class with your custom functionality
class ChampionsLeaguePointSolver : public olc : : PixelGameEngine
{
std : : string slurp ( std : : ifstream & in ) {
std : : ostringstream sstr ;
sstr < < in . rdbuf ( ) ;
return sstr . str ( ) ;
}
struct ScoreData {
int difficulty = 0 ;
std : : string song ;
int totalEX = 0 ;
int ex1 = 0 , ex2 = 0 , ex3 = 0 ;
std : : string str ( ) const {
return " [ " + std : : to_string ( difficulty ) + " ] " + song + " : " + std : : to_string ( totalEX ) + " total, " + " EX1: " + std : : to_string ( ex1 ) + " EX2: " + std : : to_string ( ex2 ) + " EX3: " + std : : to_string ( ex3 ) ;
}
friend std : : ostream & operator < < ( std : : ostream & os , const ScoreData & data ) {
os < < data . str ( ) ;
return os ;
}
} ;
std : : string GetNext ( int & marker , std : : string str ) {
int originalMarker = marker ;
marker = str . find_first_of ( ' , ' , originalMarker ) + 1 ;
return str . substr ( originalMarker , marker - 1 ) ;
} ;
struct TestCase {
int p1Amt , p2Amt , p3Amt ;
} ;
struct SongCombinations {
std : : vector < std : : pair < int , int > > p1 ; //Index to song followed by EX of song.
std : : vector < std : : pair < int , int > > p2 ;
std : : vector < std : : pair < int , int > > p3 ;
std : : set < int > p1Picked ;
std : : set < int > p2Picked ;
std : : set < int > p3Picked ;
int totalEX = 0 ;
int remainingA , remainingB , remainingC ;
} ;
std : : vector < ScoreData > dataA , dataB ;
std : : vector < std : : pair < int , int > > player1Score , player2Score , player3Score ;
void Evaluate ( ) {
std : : vector < TestCase > cases ;
for ( int i = 0 ; i < 5 ; i + + ) {
for ( int j = 0 ; j < 5 ; j + + ) {
for ( int k = 0 ; k < 5 ; k + + ) {
if ( i + j + k = = 6 ) {
cases . push_back ( TestCase { i , j , k } ) ;
}
}
}
}
auto ChooseSong = [ ] ( SongCombinations & combinations , std : : vector < ScoreData > & dat , int index ) {
if ( combinations . remainingA > 0 & & combinations . p1Picked . count ( index ) = = 0 & & combinations . p2Picked . count ( index ) = = 0 & & combinations . p3Picked . count ( index ) = = 0 ) {
combinations . remainingA - - ;
combinations . totalEX + = dat [ index ] . ex1 ;
combinations . p1 . push_back ( std : : pair < int , int > { index , dat [ index ] . ex1 } ) ;
combinations . p1Picked . insert ( index ) ;
} else
if ( combinations . remainingB > 0 & & combinations . p1Picked . count ( index ) = = 0 & & combinations . p2Picked . count ( index ) = = 0 & & combinations . p3Picked . count ( index ) = = 0 ) {
combinations . remainingB - - ;
combinations . totalEX + = dat [ index ] . ex2 ;
combinations . p2 . push_back ( std : : pair < int , int > { index , dat [ index ] . ex2 } ) ;
combinations . p2Picked . insert ( index ) ;
} else
if ( combinations . remainingC > 0 & & combinations . p1Picked . count ( index ) = = 0 & & combinations . p2Picked . count ( index ) = = 0 & & combinations . p3Picked . count ( index ) = = 0 ) {
combinations . remainingC - - ;
combinations . totalEX + = dat [ index ] . ex3 ;
combinations . p3 . push_back ( std : : pair < int , int > { index , dat [ index ] . ex3 } ) ;
combinations . p3Picked . insert ( index ) ;
}
} ;
std : : vector < SongCombinations > bestComboA , bestComboB ;
int caseInd = 0 ;
for ( TestCase & _case : cases ) {
bestComboA . push_back ( { } ) ;
bestComboA [ caseInd ] . remainingA = _case . p1Amt ;
bestComboA [ caseInd ] . remainingB = _case . p2Amt ;
bestComboA [ caseInd ] . remainingC = _case . p3Amt ;
SongCombinations testCombo = bestComboA [ caseInd ] ;
for ( int i = 0 ; i < 12 ; i + + ) {
SongCombinations c1 = testCombo ;
ChooseSong ( c1 , dataA , i ) ;
for ( int j = 0 ; j < 12 ; j + + ) {
SongCombinations c2 = c1 ;
ChooseSong ( c2 , dataA , j ) ;
for ( int k = 0 ; k < 12 ; k + + ) {
SongCombinations c3 = c2 ;
ChooseSong ( c3 , dataA , k ) ;
for ( int l = 0 ; l < 12 ; l + + ) {
SongCombinations c4 = c3 ;
ChooseSong ( c4 , dataA , l ) ;
for ( int m = 0 ; m < 12 ; m + + ) {
SongCombinations c5 = c4 ;
ChooseSong ( c5 , dataA , m ) ;
for ( int n = 0 ; n < 12 ; n + + ) {
SongCombinations c6 = c5 ;
ChooseSong ( c6 , dataA , n ) ;
if ( bestComboA [ caseInd ] . totalEX < c6 . totalEX ) {
bestComboA [ caseInd ] = c6 ;
bestComboA [ caseInd ] . totalEX = c6 . totalEX ;
std : : cout < < " New Best Song Combinations found for Case ( " < < _case . p1Amt < < " , " < < _case . p2Amt < < " , " < < _case . p3Amt < < " ) - Total EX: " < < bestComboA [ caseInd ] . totalEX < < " : " < < std : : endl ;
std : : cout < < " \t " ;
for ( std : : pair < int , int > & p1 : bestComboA [ caseInd ] . p1 ) {
std : : cout < < " P1[ " < < p1 . first < < " ]: " < < p1 . second < < " " ;
}
for ( std : : pair < int , int > & p2 : bestComboA [ caseInd ] . p2 ) {
std : : cout < < " P2[ " < < p2 . first < < " ]: " < < p2 . second < < " " ;
}
for ( std : : pair < int , int > & p3 : bestComboA [ caseInd ] . p3 ) {
std : : cout < < " P3[ " < < p3 . first < < " ]: " < < p3 . second < < " " ;
}
std : : cout < < std : : endl ;
}
}
}
}
}
}
}
caseInd + + ;
}
caseInd = 0 ;
for ( TestCase & _case : cases ) {
bestComboB . push_back ( { } ) ;
bestComboB [ caseInd ] . remainingA = _case . p1Amt ;
bestComboB [ caseInd ] . remainingB = _case . p2Amt ;
bestComboB [ caseInd ] . remainingC = _case . p3Amt ;
SongCombinations testCombo = bestComboB [ caseInd ] ;
for ( int i = 0 ; i < 12 ; i + + ) {
SongCombinations c1 = testCombo ;
ChooseSong ( c1 , dataB , i ) ;
for ( int j = 0 ; j < 12 ; j + + ) {
SongCombinations c2 = c1 ;
ChooseSong ( c2 , dataB , j ) ;
for ( int k = 0 ; k < 12 ; k + + ) {
SongCombinations c3 = c2 ;
ChooseSong ( c3 , dataB , k ) ;
for ( int l = 0 ; l < 12 ; l + + ) {
SongCombinations c4 = c3 ;
ChooseSong ( c4 , dataB , l ) ;
for ( int m = 0 ; m < 12 ; m + + ) {
SongCombinations c5 = c4 ;
ChooseSong ( c5 , dataB , m ) ;
for ( int n = 0 ; n < 12 ; n + + ) {
SongCombinations c6 = c5 ;
ChooseSong ( c6 , dataB , n ) ;
if ( bestComboB [ caseInd ] . totalEX < c6 . totalEX ) {
bestComboB [ caseInd ] = c6 ;
bestComboB [ caseInd ] . totalEX = c6 . totalEX ;
std : : cout < < " New Best Song Combinations found for Case ( " < < _case . p1Amt < < " , " < < _case . p2Amt < < " , " < < _case . p3Amt < < " ) - Total EX: " < < bestComboB [ caseInd ] . totalEX < < " : " < < std : : endl ;
std : : cout < < " \t " ;
for ( std : : pair < int , int > & p1 : bestComboB [ caseInd ] . p1 ) {
std : : cout < < " P1[ " < < p1 . first < < " ]: " < < p1 . second < < " " ;
}
for ( std : : pair < int , int > & p2 : bestComboB [ caseInd ] . p2 ) {
std : : cout < < " P2[ " < < p2 . first < < " ]: " < < p2 . second < < " " ;
}
for ( std : : pair < int , int > & p3 : bestComboB [ caseInd ] . p3 ) {
std : : cout < < " P3[ " < < p3 . first < < " ]: " < < p3 . second < < " " ;
}
std : : cout < < std : : endl ;
}
}
}
}
}
}
}
caseInd + + ;
}
int highestEX = 0 ;
SongCombinations picked1 , picked2 ;
for ( SongCombinations & A : bestComboA ) {
for ( SongCombinations & B : bestComboB ) {
if ( A . totalEX + B . totalEX > highestEX & & A . p1Picked . size ( ) + B . p1Picked . size ( ) = = 4 & & A . p2Picked . size ( ) + B . p2Picked . size ( ) = = 4 & & A . p3Picked . size ( ) + B . p3Picked . size ( ) = = 4 ) {
highestEX = A . totalEX + B . totalEX ;
picked1 = A ;
picked2 = B ;
std : : cout < < " New Best Song Combinations found for Final Picks - Total EX: " < < highestEX < < " : " < < std : : endl ;
std : : cout < < " \t Set A: " ;
for ( std : : pair < int , int > & p1 : picked1 . p1 ) {
std : : cout < < " P1[ " < < p1 . first < < " ]: " < < p1 . second < < " " ;
}
for ( std : : pair < int , int > & p2 : picked1 . p2 ) {
std : : cout < < " P2[ " < < p2 . first < < " ]: " < < p2 . second < < " " ;
}
for ( std : : pair < int , int > & p3 : picked1 . p3 ) {
std : : cout < < " P3[ " < < p3 . first < < " ]: " < < p3 . second < < " " ;
}
std : : cout < < std : : endl ;
std : : cout < < " \t Set B: " ;
for ( std : : pair < int , int > & p1 : picked2 . p1 ) {
std : : cout < < " P1[ " < < p1 . first < < " ]: " < < p1 . second < < " " ;
}
for ( std : : pair < int , int > & p2 : picked2 . p2 ) {
std : : cout < < " P2[ " < < p2 . first < < " ]: " < < p2 . second < < " " ;
}
for ( std : : pair < int , int > & p3 : picked2 . p3 ) {
std : : cout < < " P3[ " < < p3 . first < < " ]: " < < p3 . second < < " " ;
}
std : : cout < < std : : endl ;
}
}
}
}
public :
struct SongElement {
SongElement ( QuickGUI : : Manager & manager , std : : string songName , vf2d pos ) {
label = new QuickGUI : : Label ( manager , songName , pos , { 164 , 12 } ) ;
p1Score = new QuickGUI : : TextBox ( manager , " " , pos + vf2d { 192 , 0 } , { 36 , 12 } ) ;
p2Score = new QuickGUI : : TextBox ( manager , " " , pos + vf2d { 192 + 42 * 1 , 0 } , { 36 , 12 } ) ;
p3Score = new QuickGUI : : TextBox ( manager , " " , pos + vf2d { 192 + 42 * 2 , 0 } , { 36 , 12 } ) ;
if ( prevTextBox ! = nullptr ) {
prevTextBox - > tabNext = p1Score ;
}
p1Score - > tabNext = p2Score ;
p1Score - > tabPrev = prevTextBox ;
p2Score - > tabNext = p3Score ;
p2Score - > tabPrev = p1Score ;
prevTextBox = p3Score ;
p3Score - > tabPrev = p2Score ;
}
QuickGUI : : Label * label ;
QuickGUI : : TextBox * p1Score ;
QuickGUI : : TextBox * p2Score ;
QuickGUI : : TextBox * p3Score ;
} ;
QuickGUI : : Manager gui ;
std : : vector < SongElement > songs ;
ChampionsLeaguePointSolver ( )
{
// Name your application
sAppName = " Champions League Point Solver " ;
}
public :
bool OnUserCreate ( ) override
{
std : : ifstream file ( " assets/team2 " ) ;
std : : string line ;
//First two lines are garbage data.
std : : getline ( file , line ) ;
std : : getline ( file , line ) ;
for ( int i = 0 ; i < 12 ; i + + ) {
std : : getline ( file , line ) ;
int marker = 0 ;
ScoreData dat {
stoi ( GetNext ( marker , line ) ) ,
GetNext ( marker , line ) ,
stoi ( GetNext ( marker , line ) ) ,
stoi ( GetNext ( marker , line ) ) ,
stoi ( GetNext ( marker , line ) ) ,
stoi ( GetNext ( marker , line ) ) } ;
player1Score . push_back ( std : : pair < int , int > { dat . ex1 , 0 } ) ;
player2Score . push_back ( std : : pair < int , int > { dat . ex2 , 0 } ) ;
player3Score . push_back ( std : : pair < int , int > { dat . ex3 , 0 } ) ;
dataA . push_back ( dat ) ;
songs . push_back ( SongElement { gui , dat . song . substr ( 0 , dat . song . find ( ' , ' ) ) , { 4.f , 2.f + 12 * i + 16 } } ) ;
}
//Two more lines of garbage data.
std : : getline ( file , line ) ;
std : : getline ( file , line ) ;
for ( int i = 0 ; i < 12 ; i + + ) {
std : : getline ( file , line ) ;
int marker = 0 ;
ScoreData dat {
stoi ( GetNext ( marker , line ) ) ,
GetNext ( marker , line ) ,
stoi ( GetNext ( marker , line ) ) ,
stoi ( GetNext ( marker , line ) ) ,
stoi ( GetNext ( marker , line ) ) ,
stoi ( GetNext ( marker , line ) ) } ;
player1Score [ i ] . second = dat . ex1 ;
player2Score [ i ] . second = dat . ex2 ;
player3Score [ i ] . second = dat . ex3 ;
dataB . push_back ( dat ) ;
songs . push_back ( SongElement { gui , dat . song . substr ( 0 , dat . song . find ( ' , ' ) ) , { 4.f , 2.f + 12 * ( i + 13 ) + 16 } } ) ;
}
std : : cout < < " File Contents: " < < std : : endl < < std : : endl ;
for ( auto & list : { dataA , dataB } ) {
for ( auto & dat : list ) {
std : : cout < < dat < < std : : endl ;
}
}
std : : cout < < " =================== " < < std : : endl ;
return true ;
}
bool OnUserUpdate ( float fElapsedTime ) override
{
Clear ( VERY_DARK_CYAN ) ;
gui . Update ( this ) ;
gui . Draw ( this ) ;
return true ;
}
} ;
int main ( )
{
ChampionsLeaguePointSolver solver ;
if ( solver . Construct ( 320 , 320 , 4 , 4 ) )
solver . Start ( ) ;
return 0 ;
}