// LOTTERY LOSER - Prog. for analyzing statistics of lottery entries... /* MenThals first real work with O.O.P.!!!!! Start: 5.Oct.1996 Latest update:*/ #define VERSION_DATE "26.02.1997" /* For other information on the process of my analesys of the norwegian LOTTERY system, please see file: C:\DOKUMENT\KENT\SKOLE\MATTE\LOTTO.TXT Also note the file LOTTERY.HPP containing the IMPORTANT stuff... Norwegian lottery rules... bet on 7 numbers, 1-34, excluding. 7 numbers drawn + 2 additional numbers 1. 7 number 2. 6 + 1 additional 3. 6 4. 5 5. 4 + 1 additional 07.02.1997 - PrizeTest speed up... Fixed bug that took the LOWEST prize as the MAX prize in the Sim and AllDraws-tests... 08.02 - Split out the most basic classes and functions... Decided to make a LEList class, that encapsulates the list data... DTDClass split out - a mess.... 24.02 - Two DTD classes DTDAlpha and DTDOmega - seems to work... Dynamic loading routine that figures out which sort of object to create... really delicate, may boom. As may the Create New DTD command ... */ #include #include //******* IMPORTANT ********* #include #include #include #include #define DEBUG #define COMPILE_FOR DOS //I.e. - windows without GUI stuff... #define MAX_ENTRIES 2048 #define MAX_RESULTS 100 #define MAX_NUM_LELISTS 4 //LEntry class: The more platform-specific methods ostream& operator << (ostream& Os, LEntry& LE) // WRITING an entry { for(int i=0;i> (istream& Is, LEntry& LE) // READING an entry { int i,j; for(i=0;i> (unsigned int) j )) i=MAX_SELECTED+1; }while( (j<1 || j>MAX_NUMBER || LE.Contains(j)) && i<=MAX_SELECTED); LE.Num[i]=j; } if(i>MAX_SELECTED) for(j=0;j> WEntry; cout << "\nEnter additional numbers:\n"; int i,j; for(i=0;i> (unsigned int) j; cin.ignore(); }while((j<1 || j>MAX_NUMBER)|| WEntry.Contains(j)); ANum[i]=j; } } istream& operator >> (istream& Is, LDrawResult& LD) { int i,j; if(Is >> LD.WEntry) for(i=0;i> (unsigned int) j; }while((j<1 || j>MAX_NUMBER) || LD.WEntry.Contains(j) || (j==LD.ANum[i-1] && i>0)); LD.ANum[i]=j; } return Is; } // End of LDrawResult class LEntry LEntries[MAX_ENTRIES]; LDrawResult LResults[MAX_RESULTS]; unsigned long NumLEntries, NumLResults; unsigned char LEI[MAX_ENTRIES_PR_LIST]; unsigned long LNI[MAX_NUMBER+1]; int SecondaryListPresent = 0; enum LEListListIndex { PrimLEL=0, SecLEL=1 }; LEList LEL[MAX_NUM_LELISTS]; /*char LEFileName[50] = "Lottery.lot"; char SecondaryLEFileName[50]; */ #ifdef DEBUG clock_t clockStart, clockEnd; float testSeconds; float clockSeconds(clock_t t){return(float(t)/CLK_TCK);} #endif int LEList::LoadFile() //Loads ASCII file containing 7 number entries ->LEList { ifstream InFile; //LEntry LE; numLEs=0; InFile.open(FileName); if(InFile.rdstate()) { cout <<"\nUnknown file stream state occured...\nAborting LEFile loading for safety...\n"; return 0;} while (InFile >> LEs[numLEs], !InFile.eof()) numLEs++; InFile.close(); cout <<"\n Lottery entry file: " << FileName << " loaded.\n"; cout << " " << numLEs << " entries found.\n"; return 1; } int LEList::SaveFile() //Saves ASCII file containing 7 number entries ->LEList { ofstream OutFile; //LEntry LE; OutFile.open(FileName); if(OutFile.rdstate()) { cout <<"\nUnknown file stream state occured...\nAborting LEFile saving for safety...\n"; return 0;} for(int i=0;iLEI[i]) LEI[i]=c; //if(c>LEI[j]) LEI[j]=c; } } } void TestCrunchAlpha() //Attempt on a routine that lessens entry similarity and increases the probability of winnning... { int MaxEq,OldMaxEq,i,numAttempts=0; char ch; randomize(); GetLEI_CompareAllToAll(); MaxEq=0; for(i=0;iMaxEq)MaxEq=LEI[i]; OldMaxEq=MaxEq; cout << "CrunchAlpha: Randomized entries:\n"; do{ for(i=0;iMaxEq)MaxEq=LEI[i]; numAttempts++; /*if(numAttempts>90){ cout <<"\n MaxEq: "<> ch; if(ch==32) numAttempts=0; } */ }while((MaxEq>=OldMaxEq) && (numAttempts<100)); cout <<"\n MaxEq: "<IsA()!=T) cout<<"Invalid DTD_ID after spawning!\n"; //Booms...? return tmp; } DTDBase *CreateNewDTD(DTDTypeIDs T) { return CreateNewDTD(T, LEL[PrimLEL], LEL[SecLEL], FULL); } DTDBase *LoadAnyDTD(char* FName) //Dynamic loader of DTD files... { ifstream In; DTDTypeIDs I; int i; DTDBase *TmpDTD; In.open(FName); //Lets get the DTD_ID of the file... In>>i; In.close(); I = DTDTypeIDs(i); TmpDTD = CreateNewDTD(I); //Set up a correct object for the data TmpDTD->SetFileName(FName); TmpDTD->LoadDTDFile(); //and load it in.... return TmpDTD; } void RunDTDTest(DTDBase& T) //Generalized Testing procedure... { char ch, cont; #ifdef DEBUG long XCounter=0; float XTime; long SaveLim=1, incSaveLim=1; #endif cout<<"\n************ TESTING INITIATED ****************" <<"\n******* YOU MAY MINIMIZE THIS WINDOW *********" <<"\n**** BUT REMEMBER TO PRESS 'ESC' TO CLOSE *****"; #ifdef DEBUG clockStart=clock(); #endif do{ cont=T++; #ifdef DEBUG XCounter++; if((XCounter&255) && ((clockSeconds(clock()-clockStart)/60)>SaveLim) ) { SaveLim+=incSaveLim; T.SaveDTDFile(); } #endif if(kbhit()) { ch=getch(); if(ch==27)cont=0; cout<FileName<<"' DTD_ID:'"<IsA())<<"'\n"; RunDTDTest(*T); T->SaveDTDFile(); delete T; } void main(int argc, char *argv[]) { int i,j; char ch; int MenuChoice; cout << setw(40) << setfill('*') << '*'; cout << "\n\n LOTTERY LOSER - lottery entry analyzer\n"; cout << " - only 7 numbers/entry - version date: "<FileName<<"' DTD_ID:'"<IsA())<<"'\n"; RunDTDTest(*T); T->SaveDTDFile(); delete T; */ break; } case 'L': // Load LEfile { LEL[PrimLEL].SetFileName(argv[++i]); LEL[PrimLEL].LoadFile(); break;} } //End case } } do{ cout <<"\n'"< Lottery loser <*+-\n"; cout <<" 1. List lottery entries\n"; cout <<" 2. Compare to winning draw\n"; cout <<" 3. LE statistics\n"; cout <<" 4. Save LE's back to file\n"; cout <<" 5. CrunchAlpha...Make entries less similar!\n"; cout <<" 6. Copy current entries to secondary list.\n"; cout <<" 7. Create New DTD file\n"; cout <<" 8. Load new LE file...\n"; cout <<" 9. Load DTD file\n"; cout <<" 0. EXIT\n ->"; // LEL[PrimLEL].numLEs = NumLEntries; //ARG!! MenuChoice=0; do{cin >> MenuChoice; }while(MenuChoice>9 || MenuChoice<0); switch (MenuChoice) { case 1: cout << "\n Lottery entries from " << LEL[PrimLEL].FileName << " file.\n"; cout << "Num. of entries: " < "; break;} }; break; //End case 1 case 2: { //Win.EnterResult(); cout << "\n Enter winning draw\n-> "; if(cin >> Win) cout << "\nWinning entry: " << Win << "\n"; /*B = LEntries[0]; cout <<"\nB: "<< B;*/ for(i=0;i "; break;} } cout << "\n"; }; break; //End case 2 case 3: //LE Statistics { GetLEI_CompareAllToAll(); for(i=0;i "; break;} } /*int Max=0,Min=7; for(i=0;iMax) Max=LEI[i]; if(LEI[i] "; break;} } getch(); }; break; //End case 3 case 4: { cout << "\n Do you really want to save over "<>LEL[PrimLEL].FileName; LEL[PrimLEL].SaveFile();} break; } case 5: TestCrunchAlpha(); break; case 6: { cout << "\nCopying entries to secondary list..."; for(i=0;i> str; cout<<"\n\nSelect DTD type:"; for(i=1;i"; cin >> int(TId); cout<<"\n\nSelect DTD MODE:"; for(i=0;i"; cin >> int(M); T = CreateNewDTD(TId, LEL[PrimLEL], LEL[SecLEL], M); T->SetFileName(str); cout <<" File:'"<FileName<<"' DTD_ID:"<IsA())<<" TM:"<SaveDTDFile(); delete T; /*DTDAlpha T(LEL[PrimLEL], LEL[SecLEL], RANDOM); RunDTDTest(T); */ break;} case 8: { cout <<"\n\n Enter new LE file to load: "; cin >> LEL[PrimLEL].FileName; LEL[PrimLEL].LoadFile(); break; }//Case 8 case 9: { char str[80]; cout<<"\n\n Contine processing DTD file\nEnter filename:->"; cin >>str; ContinueProcessingDTD(str); /*DTDAlpha T(LEL[PrimLEL], LEL[SecLEL], FULL); T.Load("c:/temp/x.dtd"); //T.SetFileName("c:/temp/x.dtd"); RunDTDTest(T); T.SaveDTDFile(); */ break;} // LargeScaleDrawTesting(FULL,PrimLEL,SecLEL); break; case 10: { DTDBase *T; T = CreateNewDTD(ID_DTDOmega, LEL[PrimLEL], LEL[SecLEL], FULL); T->SetFileName("c:/temp/z.dtd"); cout << *T; RunDTDTest(*T); T->SaveDTDFile(); break;}//Case10 } //End all cases }while(MenuChoice!=0); //SaveLEFile(LEFileName); #ifdef DEBUG long l; /*DTDBase *T; T = CreateNewDTD(ID_DTDOmega); T->SetFileName("Ogga Bogga"); cout <<"\n"<< T->FileName<<" "<IsA()); T->Report(cout); delete T; //Deletes the contents... */ #endif } //End of MAIN /**/ /* Here follows the brute force method for calc. the probabilities... its the same as the simulation, but goes through EVERY possible DRAWRESULT... Testing X.LOT and LOTTERY.LOT, 2 lists of 50 entries each, program manages ca. 1600 draws per second on the P100... Thats a wooping 19547 minutes = 326 hours = 13.6 days to go through the complete 34C7*(34-7)C2 =1 888 245 216 possible draws.... This method is obviosly NO GOOD!!!!!! - 2 LEntries in two lists - 4900drraws/second => 6423 min = 107 h = 4.46 days ... speed up? 25000 draws/second after PrizeTest retuning.. 07.02.97 ??? 07.02.97 - 50 entry lists X.lot/Lottery.lot - manages 2100 draws/sec ostream& DTDClassAlpha::PrintReport1To(ostream& Os) { if(TDMode==FULL) Os << "\nCounter: "<FileName<<" || "<FileName; Os <<"\nPrize.: Cur.(All/Max) || Old.\n"; for(int i=0;i<6;i++){ Os << setfill(' ')<numLEs || TDLEL[1]->numLEs)) for(int i=0;i<6;i++){ Os << setfill(' ')<numLEs) Os <numLEs); else Os<<"..."; Os << ", " <numLEs;i++) { //cout<<"\n!!!!!"; //prize1=T.TestDraw.PrizeTest(LEL[j].LEs[i]); prize1=T.TestDraw.PrizeTest(T.TDLEL[j]->LEs[i]); T.Prizes[j][prize1]++; if(prize1) if(prize15)maxPrize1=0; T.MaxPrizes[j][maxPrize1]++; } if(T.TDMode==FULL) { if(!(++T.TestDraw)) cont=0; } else if(T.TDMode==RANDOM) { T.TestDraw.Randomize(); } #ifdef DEBUG if(T.numLDRs%255==0) if( clockSeconds(clock()-clockStart)/60>SaveLim ) { T.SaveToFile("C:\\TEMP\\LOTT.DTD"); cout<<"\nSaved to Lott.dtd\n"; SaveLim+=incSaveLim; } #endif if(kbhit()) { ch=getch(); if(ch=='s' || ch=='S'){ T.SaveToFile("C:\\TEMP\\LOT.dtd"); cout<<"\n DTD file saved. \n"; } if(ch=='l' || ch=='L'){ T.LoadFromFile("C:\\TEMP\\LOT.dtd"); cout <<"\n DTD file loaded. \n"; startNumLDRs=T.numLDRs; clockStart=clock(); } T.PrintReport1To(cout); #ifdef DEBUG clockEnd=clock(); testSeconds=clockSeconds(clockEnd-clockStart); cout << " Total/Time: "<FileName<<" || "<FileName; if(T.TDMode==FULL) cout <<"\nExtTest"; else if(T.TDMode==RANDOM) cout <<"\nSim Test"; cout <<"\nPrize.: Cur.(All/Ent, High/Draw) || Old.\n"; T.PrintReport2To(cout); if(DMode==LOAD_WORKFILE) { T.SaveToFile("C:\\TEMP\\LOT.dtd"); cout<<"\n DTD work file saved. \n"; }; cout << "\n(Press a key)"; ch=getch(); if(DMode!=LOAD_WORKFILE && (ch=='s' || ch=='S')){ T.SaveToFile("C:\\TEMP\\LOT.dtd"); cout<<"\n DTD file saved. \n"; } } */