/* LOTTERY.HPP - The basic structures and methods that are NOT specific to either DOS or WINDOWS. (No specific external output functions..???) Meaning that some functions are DECLARED(prototyped) here, but not DEFINED(no code) Separated from LOTTERY.CPP 08.02.97. LEntry class: UNdefined: friend ostream& operator << (ostream&, LEntry&); friend istream& operator >> (istream&, LEntry&); LDrawResult class: UNdefined: void EnterResult(); friend ostream& operator << (ostream&, LDrawResult&); friend istream& operator >> (istream&, LDrawResult&); DTDBase class : building block for: DTDAlpha class: keeps prize statistics DTDOmega class: keeps complete result statistics (num. Correct and Additional) AN EVEN-WORSE MESS!!!! */ #include //Due to RANDOMIZE() #include #include #include #include #include //Mathematical probability precalc'ed values... #define MAX_ENTRY_COMBS 5379616 // 34!/(34-7)!/7! = 34C7 #define MAX_ADDITIONAL_COMBS 351 #define MAX_DRAW_COMBS (MAX_ENTRY_COMBS*MAX_ADDITIONAL_COMBS) //#define NUM_COMBS_1ST_PRIZE 1 //Are these correct???? Don't kno' fer sure... //#define NUM_COMBS_2ND_PRIZE 14 // 7C6*2C1*25C0 //#define NUM_COMBS_3RD_PRIZE 175 // 7C6*2C0*25C1 //#define NUM_COMBS_4TH_PRIZE 7371 // 7C5*(2C2*25C0+2C1*25C1+2C0*25C2) //#define NUM_COMBS_5TH_PRIZE 21875 // 7C4*(2C2*25C1+2C1*25C2) //#define NUM_COMBS_NO_PRIZE 5350180 // #define MAX_NUMBER 34 #define MAX_SELECTED 7 #define MAX_ADDITIONAL 2 #define Entry_Sel_t unsigned char long NumCombs_Prize[6] = { 5350180L, 1, 14, 175, 7371, 21875 }; // LEntry class class LEntry { protected: Entry_Sel_t Num[MAX_SELECTED]; public: LEntry(); int Sort(); //Returns a NEGATIVE result on garbage int Contains(Entry_Sel_t); int CompareTo(LEntry); void Randomize(); void ResetAsCounter(); int operator ++ (void); friend ostream& operator << (ostream&, LEntry&); friend istream& operator >> (istream&, LEntry&); }; LEntry::LEntry() { for(int i=0;iNum[i+1]) { Es=Num[i]; Num[i]=Num[i+1]; Num[i+1]=Es; j=1; } }while(j!=0); for(i=0;iMAX_NUMBER)) return -2; return 0; } int LEntry::CompareTo(LEntry Other) { int i,j=0; for(i=0;i> (unsigned int) j )) i=MAX_SELECTED+1; }while( (j<1 || j>MAX_NUMBER || Contains(j))); Num[i]=j; } //if(i>MAX_SELECTED) for(j=0;j> (istream&, LDrawResult&); }; LDrawResult::LDrawResult() { for(int i=0;i> (unsigned int) j )) i=MAX_SELECTED+1; }while( (j<1 || j>MAX_NUMBER || WEntry.Contains(j))||ANum[0]==j); ANum[i]=j; } //if(i>MAX_SELECTED) for(j=0;jANum[1]) { j=ANum[0]; ANum[0]=ANum[1]; ANum[1]=j; } } int LDrawResult::Compare(LEntry LE) { return WEntry.CompareTo(LE); } int LDrawResult::CompareAdditional(LEntry LE) { int i,j=0; for(i=0;i3){ if(Correct==5) return 4; //Attempt to speed things up... if(Correct==7) return 1; Additional=CompareAdditional(LE); //if(Correct==6 && Additional==1) return 2; if(Correct==6) return 3; if(Correct==4 && Additional>0) return 5; if(Correct==6) if(Additional){ return 2; } else{ return 3;}; } return 0; } int LDrawResult::operator ++ () //Counter function... for statistics { do{ANum[1]++;}while((ANum[1]==ANum[0])||(WEntry.Contains(ANum[1]))); if(ANum[1]>MAX_NUMBER) { do{ANum[0]++;}while((WEntry.Contains(ANum[0]))); ANum[1]=ANum[0]; do{ANum[1]++;}while((WEntry.Contains(ANum[1]))); if(ANum[1]>MAX_NUMBER) { if(++WEntry){ ANum[0]=0; do{ANum[0]++;}while((WEntry.Contains(ANum[0]))); ANum[1]=ANum[0]; do{ANum[1]++;}while((WEntry.Contains(ANum[1]))); return 1; } else return 0; } } return 1; }; int PrizeFor(int C, int A) { if(C>3){ if(C==5) return 4; //Attempt to speed things up... if(C==7) return 1; if(C==4 && A>0) return 5; if(C==6) if(A){ return 2; } else{ return 3;}; } return 0; } /* The counter system is SLOW... manages about 850 000 ticks per second, but we have 1 888 245 216 of the bligthers... Thats a 2222 seconds = 37 minutes just for counting through every possible LDrawResult Imagine if we were to check 2 lists of 50 LEntries each against them... */ void LDrawResult::ResetAsCounter() { WEntry.ResetAsCounter(); ANum[0]=0; do{ANum[0]++;}while((WEntry.Contains(ANum[0]))); ANum[1]=ANum[0]; do{ANum[1]++;}while((WEntry.Contains(ANum[1]))); } //End of LDrawResult class // FileName class #define MAX_FILENAME_LENGTH 64 class FileNameClass { public: char FileName[MAX_FILENAME_LENGTH]; FileNameClass(); FileNameClass(char*); void SetFileName(char*); }; FileNameClass::FileNameClass() { FileName[0]=0; } void FileNameClass::SetFileName(char* N) { strncpy(FileName, N, MAX_FILENAME_LENGTH); FileName[MAX_FILENAME_LENGTH-1]=0; } FileNameClass::FileNameClass(char* N) { SetFileName(N); } //FileName class end... // LEList class #define MAX_ENTRIES_PR_LIST 512 class LEList : public FileNameClass { public: LEntry *LEs; unsigned long numLEs, maxLEs; //char FileName[MAX_FILENAME_LENGTH]; LEList(); //void SetFileName(char*); int LoadFile(); int SaveFile(); }; LEList::LEList() : FileNameClass() { numLEs=0; maxLEs=MAX_ENTRIES_PR_LIST; } //End LEList //DTD - classes... enum DTDTypeIDs { ID_DTDBase=0, ID_DTDAlpha=1, ID_DTDOmega=2, NumOf_DTDTypeIDs}; char DTDTypeDescription[NumOf_DTDTypeIDs][16] = { "(Base:N.A.)", "Alpha: Prizes", "Omega: C./A." }; enum TestingModes { RANDOM=0, FULL=1, NumOf_TestingModes}; char TestingModesDescription[NumOf_TestingModes][20] = { "Simulate draws", "Count thru draws" }; class DTDBase : public FileNameClass//Base class for DTD info { protected: TestingModes TDMode; DTDTypeIDs DTD_ID; long numLDRs; LDrawResult TestDraw; public: LEList *TDLEL[2]; public: DTDBase(); //Ctor DTDBase(LEList&, LEList&, TestingModes); void SaveDTDFile(); void LoadDTDFile(); /**/ void Load(char*); virtual void Report(ostream&)=0; virtual int ProcessDraw()=0; virtual DTDTypeIDs IsA(); virtual SaveIndividualDTD(ofstream&) =0; virtual LoadIndividualDTD(ifstream&) =0; int DTDBase::operator ++ (); friend ostream& operator << (ostream&, DTDBase&); }; DTDBase::DTDBase() : FileNameClass() //Ctor { numLDRs=0; TDMode=RANDOM; DTD_ID=ID_DTDBase; randomize(); } DTDBase::DTDBase(LEList& L1, LEList& L2, TestingModes M) : FileNameClass() //Ctor { numLDRs=0; DTD_ID=ID_DTDBase; TDMode=M; if(TDMode==RANDOM) randomize(); if(TDMode==FULL) TestDraw.ResetAsCounter(); TDLEL[0]=&L1; TDLEL[1]=&L2; } DTDTypeIDs DTDBase::IsA(){ return DTD_ID; } int DTDBase::operator ++ () { if(ProcessDraw()) { numLDRs++; return 1; }else return 0; } /*int DTDBase::ProcessDraw(){ return 1; } */ void DTDBase::SaveDTDFile() { ofstream OutFile; int i,j; OutFile.open(FileName); //OutFile << IsA() << "\n"; OutFile <<" "<numLEs <<" "<numLEs<<"\n"; OutFile<FileName<<"\n"<FileName<<"\n"; for(i=0;i<2;i++) { for(j=0;jnumLEs;j++) { OutFile<<" "<< TDLEL[i]->LEs[j]<<" "; } OutFile<<"\n"; } OutFile.close(); cout<<"\nSaved DTD "<> IsA() >> "\n"; InFile >>int(DTD_ID); //if(DTDTypeIDs(i)!=DTD_ID) // If the file isn't of the correct DTD format..abort //{ cout<<"\n Invalid DTD_ID!\n"; return; } //DTD_ID = DTDTypeIDs(i); InFile >> int(TDMode) >> numLDRs >> TestDraw; LoadIndividualDTD(InFile); //LELists... InFile>> TDLEL[0]->numLEs >> TDLEL[1]->numLEs; InFile>> TDLEL[0]->FileName >> TDLEL[1]->FileName; for(i=0;i<2;i++) { for(j=0;jnumLEs;j++) { InFile >> TDLEL[i]->LEs[j]; } } InFile.close(); if(TDMode==RANDOM) randomize(); } void DTDBase::Load(char* N) { SetFileName(N); LoadDTDFile(); } ostream& operator << (ostream& Out, DTDBase& D) { Out<<"\n\n"<FileName<<' '; Out<FileName; D.Report(Out); return Out; } ////////// class DTDAlpha : public DTDBase { protected: unsigned long Prizes[2][6], MaxPrizes[2][6]; public: DTDAlpha(); DTDAlpha( LEList&, LEList&, TestingModes); virtual SaveIndividualDTD(ofstream&); virtual LoadIndividualDTD(ifstream&); virtual int ProcessDraw(); virtual void Report(ostream&); }; DTDAlpha::DTDAlpha() : DTDBase() //Ctor { for(int i=0;i<2;i++) for(int j=0;j<6;j++) { Prizes[i][j]=0; MaxPrizes[i][j]=0; } DTD_ID=ID_DTDAlpha; } DTDAlpha::DTDAlpha( LEList& L1, LEList& L2, TestingModes M) : DTDBase(L1,L2,M) { //DTDAlpha::DTDAlpha(); for(int i=0;i<2;i++) for(int j=0;j<6;j++) { Prizes[i][j]=0; MaxPrizes[i][j]=0; } DTD_ID=ID_DTDAlpha; } DTDAlpha::SaveIndividualDTD(ofstream& Out) { for(int i=0;i<6;i++) { for(int j=0;j<2;j++) { Out <<" "<>Prizes[j][i]>>MaxPrizes[j][i]; } } return 1; } int DTDAlpha::ProcessDraw() { int maxPrize1=999, prize1; for(int j=0;j<2;j++) { maxPrize1=999; for(int i=0;inumLEs;i++) { //cout<<"\n!!!!!"; //prize1=T.TestDraw.PrizeTest(LEL[j].LEs[i]); prize1=TestDraw.PrizeTest(TDLEL[j]->LEs[i]); Prizes[j][prize1]++; if(prize1) if(prize15)maxPrize1=0; MaxPrizes[j][maxPrize1]++; } if(TDMode==FULL) { if(!(++TestDraw)) return 0; } else if(TDMode==RANDOM) { TestDraw.Randomize(); } return 1; } void DTDAlpha::Report(ostream& Out) { for(int i=0;i<6;i++) { Out<<"\n"<=0 && A>=0 && C<=MAX_SELECTED && A<=MAX_ADDITIONAL) Results[C][A]++; } unsigned long ResultFrequency::GetFreq(int C, int A) { if(C>=0 && A>=0 && C<=MAX_SELECTED && A<=MAX_ADDITIONAL) return Results[C][A]; else return 0; } void ResultFrequency::SetFreq(int C, int A, unsigned long L) { if(C>=0 && A>=0 && C<=MAX_SELECTED && A<=MAX_ADDITIONAL) Results[C][A]=L; } ////////// //New DTDOmega class for detailed info... class DTDOmega : public DTDBase { protected: ResultFrequency Result[2], MaxResult[2]; public: DTDOmega(); DTDOmega( LEList&, LEList&, TestingModes); virtual SaveIndividualDTD(ofstream&); virtual LoadIndividualDTD(ifstream&); virtual int ProcessDraw(); virtual void Report(ostream&); }; DTDOmega::DTDOmega() : DTDBase() //Ctor { //for(int i=0;i<2;i++) DTD_ID=ID_DTDOmega; } DTDOmega::DTDOmega( LEList& L1, LEList& L2, TestingModes M) : DTDBase(L1,L2,M) { // DTDOmega::DTDOmega(); DTD_ID=ID_DTDOmega; } DTDOmega::SaveIndividualDTD(ofstream& Out) { for(int i=0;i> l; Result[k].SetFreq(i,j,l); In >> l; MaxResult[k].SetFreq(i,j,l); } } } return 1; } int DTDOmega::ProcessDraw() { int C, A, mC=0, mA=0; for(int j=0;j<2;j++) { mC=0; mA=0; for(int i=0;inumLEs;i++) { //cout<<"\n!!!!!"; //prize1=T.TestDraw.PrizeTest(LEL[j].LEs[i]); //prize1=TestDraw.PrizeTest(TDLEL[j]->LEs[i]); C=TestDraw.Compare(TDLEL[j]->LEs[i]); A=TestDraw.CompareAdditional(TDLEL[j]->LEs[i]); Result[j].Accept(C,A); if((C>mC) || (C==mC && A>mA)) { mC=C; mA=A; } } //if(maxPrize1>5)maxPrize1=0; MaxResult[j].Accept(mC,mA); //[j][maxPrize1]++; } if(TDMode==FULL) { if(!(++TestDraw)) return 0; } else if(TDMode==RANDOM) { TestDraw.Randomize(); } return 1; } void DTDOmega::Report(ostream& Out) { for(int i=0;i0) && !(i==6 && j>1)) { Out<<"\n"<numLEs <<" "<numLEs<<"\n"; OutFile<FileName<<"\n"<FileName<<"\n"; for(i=0;i<2;i++) { for(j=0;jnumLEs;j++) { OutFile<<" "<< TDLEL[i]->LEs[j]<<" "; } OutFile<<"\n"; } OutFile.close(); } DTDClassAlpha::LoadFromFile(char *FileName) { ifstream InFile; int i,j; InFile.open(FileName); InFile >>int(TDMode)>>numLDRs>>TestDraw; //Prizes for(i=0;i<6;i++) { for(j=0;j<2;j++) { InFile >>Prizes[j][i]>>MaxPrizes[j][i]; } //InFile >>"\n"; } //InFile>>"\n\n"; //LELists... InFile>> TDLEL[0]->numLEs >>TDLEL[1]->numLEs; InFile>>TDLEL[0]->FileName; InFile>>TDLEL[1]->FileName; for(i=0;i<2;i++) { for(j=0;jnumLEs;j++) { InFile >> TDLEL[i]->LEs[j]; } //InFile>>"\n"; } InFile.close(); } void DTDClassAlpha::Report(ostream& Out) { } DTDClassAlpha::SaveIndividualDTD(ofstream& O) { } DTDClassAlpha::LoadIndividualDTD(ifstream& I) { } */