Guest User

Safety0ff

a guest
Aug 11th, 2009
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.37 KB | None | 0 0
  1. /*
  2. Created by Safety0ff, derived from Jon King's work @ http://theamazingking.com/lock-rake.html
  3. */
  4. #include <iostream>
  5. #include <ctime>
  6. #include <cctype>
  7. #include <cmath>
  8. #include <string>
  9. #include <sstream>
  10. #include <fstream>
  11.  
  12.  
  13. using namespace std;
  14.  
  15. //----------------- Deflection options
  16.  
  17. #define DEFLEC                  // Defining DEFLECT uses model which is more difficult to pick
  18. //----------------- Progress Report options
  19. #define PROGRES                // Defining PROGRESS enables progress output as % complete (more useful)
  20. #define NOPROGRESS               // Defining NOPROGRESS means you'll only get final results (faster)
  21. #define ITERATIONDISPLA                 // Define ITERATIONDISPLAY and NOPROGRESS for iteration display
  22. //---------------------------------------
  23. #define numOfPinLengths 10
  24. #define numPinTolerances 100
  25. #define numTopCombos 5
  26.  
  27.  
  28. void convertConvention();
  29.  
  30. class Lock
  31. {
  32. private:
  33.  
  34.     int numPins;
  35.     int *pins;              // Pin lengths
  36.     int *pinTolerance;      // Determines bind order
  37.     bool *pinSet;          // Pin set or not
  38.     int patience;           // Number of times to rake
  39.     int *rakeOrder;
  40.  
  41.     bool isBinding(int index)
  42.     {
  43.         if (pinSet[index])
  44.         {
  45.             return false;
  46.         }
  47.         for (int i=0;i<numPins;i++)
  48.         {
  49.             if ((pinTolerance[i]>pinTolerance[index])&&(!pinSet[i]))
  50.             {
  51.                 return false;
  52.             }
  53.         }
  54.         return true;
  55.     }
  56. public:
  57.     Lock (int thisManyPins,int rakeThisManyTimes )   // Constructor
  58.     {
  59.         int i;
  60.         srand(time(NULL));
  61.         numPins=thisManyPins;
  62.         patience=rakeThisManyTimes;
  63.         pins=new int [numPins];
  64.         pinTolerance=new int [numPins];
  65.         pinSet=new bool [numPins];
  66.         rakeOrder=new int [patience];
  67.         for (i=0;i<numPins;i++)
  68.         {
  69.             pins[i] = rand() % numOfPinLengths;
  70.             pinTolerance[i] = rand() % numPinTolerances;
  71.             pinSet[i]=false;
  72.         }
  73.         for (i=0;i<patience;i++)
  74.         {
  75.             rakeOrder[i]=numPins-1;
  76.         }
  77.     }
  78.     ~Lock ()   // Destructor
  79.     {
  80.         delete [] pins;
  81.         delete [] pinTolerance;
  82.         delete [] pinSet;
  83.         delete [] rakeOrder;
  84.     }
  85.     bool isOpen()
  86.     {
  87.         for (int i=0;i<numPins;i++)
  88.         {
  89.             if (pinSet[i]==false)
  90.             {
  91.                 return false;
  92.             }
  93.         }
  94.         return true;
  95.     }
  96.     void setRandomCombo()
  97.     {
  98.         int i;
  99.         for (i = 0; i < patience; i++)
  100.         {
  101.             rakeOrder[i] = rand() % numPins;
  102.         }
  103.     }
  104.     void setRandomPins()
  105.     {
  106.         int i;
  107.         for (i=0;i<numPins;i++)
  108.         {
  109.             pins[i] = rand() % numOfPinLengths;
  110.             pinTolerance[i] = rand() % numPinTolerances;
  111.             pinSet[i]=false;
  112.         }
  113.     }
  114.     void lockLock()
  115.     {
  116.         int i;
  117.         for (i=0;i<numPins;i++)
  118.         {
  119.             pinSet[i]=false;
  120.         }
  121.     }
  122.     void setZeroCombo()
  123.     {
  124.         int i;
  125.         for (i = 0; i < patience; i++)
  126.         {
  127.             rakeOrder[i] = 0;
  128.         }
  129.     }
  130.     void setCombo()
  131.     {
  132.         int temp,i;
  133.         for (i=0;i<patience;i++)
  134.         {
  135.             cout<<"Position #"<<i+1<<" rake pin number:";
  136.             cin>>temp;
  137.             if (cin.fail())
  138.             {
  139.                 cin.clear();
  140.                 cin.ignore(INT_MAX, '\n');
  141.                 cout << "\n\nAn input error occured - please try again.\n\n";
  142.                 i--;
  143.                 continue;
  144.             }
  145.             temp--;
  146.             if (temp<numPins&&temp>=0)
  147.             {
  148.                 rakeOrder[i]=temp;
  149.             }
  150.             else
  151.             {
  152.                 cout<<"Invalid pin number, try again.\n";
  153.                 i--;
  154.                 continue;
  155.             }
  156.         }
  157.     }
  158.     bool incrementCombo()
  159.     {
  160.         int i;
  161.         rakeOrder[0]++;
  162.         for (i = 0; i<patience-1; i++)
  163.         {
  164.             if (rakeOrder[i]>=numPins)
  165.             {
  166.                 rakeOrder[i+1]++;
  167.                 rakeOrder[i]=0;
  168.             }
  169.             else
  170.             {
  171.                 break;
  172.             }
  173.         }
  174.         if (rakeOrder[patience-1]>=numPins)
  175.         {
  176.             setZeroCombo();
  177.             return false;
  178.         }
  179.         else
  180.         {
  181.             return true;
  182.         }
  183.  
  184.     }
  185.     int getNumberOfPins()
  186.     {
  187.         return numPins;
  188.     }
  189.     void newLock ()
  190.     {
  191.         for (int i=0;i<numPins;i++)
  192.         {
  193.             pins[i] = rand() % numOfPinLengths;
  194.             pinTolerance[i] = rand() % numPinTolerances;
  195.             pinSet[i]=false;
  196.         }
  197.     }
  198.     bool rakeUpwards()
  199.     {
  200.         int i,j,rakeHeight;
  201.         for (i=0;i<patience;i++)
  202.         {
  203.             rakeHeight=numOfPinLengths;     // Greater than the max height
  204.             // The following line determines the "direction" you rake in
  205.             // ex: for(j=rakeOrder[i]; j >=0; j--) will rake out
  206.             for (j=rakeOrder[i]; j <numPins ; j++)
  207.             {
  208. #ifdef DEFLECT
  209.                 if (pins[j] <= rakeHeight-1)        // Requires the rake to be higher to set pins
  210.                 {
  211.                     if (isBinding(j))
  212.                     {
  213.                         pinSet[j] = true;
  214.                         rakeHeight=pins[j];
  215.                     }
  216.                     else if (pinSet[j])
  217.                     {
  218.                         rakeHeight=pins[j];       // Deflecting off a set pin
  219.                     }
  220.                 }
  221. #endif
  222.                 if (pins[j] <= rakeHeight)
  223.                 {
  224. #ifndef DEFLECT
  225.                     if (isBinding(j))
  226.                     {
  227.                         pinSet[j] = true;
  228.                         rakeHeight=pins[j];
  229.                     }
  230.                     else if (pinSet[j])
  231.                     {
  232.                         rakeHeight=pins[j];       // Deflecting off a set pin
  233.                     }
  234. #endif
  235. #ifdef DEFLECT
  236.                     if (isBinding(j))       // In this model the rake has to be 1 higher than the pin length to set, otherwise it deflects
  237.                     {
  238.                         rakeHeight--;
  239.                     }
  240. #endif
  241.                     if (rakeHeight < numOfPinLengths)
  242.                     {
  243.                         rakeHeight++;
  244.                     }
  245.                 }
  246.             }
  247.         }
  248.         if (isOpen())
  249.         {
  250.             return true;
  251.         }
  252.         return false;
  253.     }
  254.  
  255.     bool rake()
  256.     {
  257.         int i,j,rakeHeight;
  258.         for (i=0;i<patience;i++)
  259.         {
  260.             rakeHeight=numOfPinLengths;     // Greater than the max height
  261.             // The following line determines the "direction" you rake in
  262.             // ex: for(j=rakeOrder[i]; j >=0; j--) will rake out
  263.             for (j=rakeOrder[i]; j <numPins ; j++)
  264.             {
  265. #ifdef DEFLECT
  266.                 if (pins[j] <= rakeHeight-1)
  267.                 {
  268.                     if (isBinding(j))
  269.                     {
  270.                         pinSet[j] = true;
  271.                         rakeHeight=pins[j];
  272.                     }
  273.                     else if (pinSet[j])
  274.                     {
  275.                         rakeHeight=pins[j];
  276.                     }
  277.                 }
  278. #endif
  279.                 if (pins[j] <= rakeHeight)
  280.                 {
  281. #ifndef DEFLECT
  282.                     if (isBinding(j))
  283.                     {
  284.                         pinSet[j] = true;
  285.                         rakeHeight=pins[j];
  286.                     }
  287.                     else if (pinSet[j])
  288.                     {
  289.                         rakeHeight=pins[j];
  290.                     }
  291. #endif
  292. #ifdef DEFLECT
  293.                     if (isBinding(j))       // In this model the rake has to be 1 higher than the pin length to set, otherwise it deflects
  294.                     {
  295.                         rakeHeight--;
  296.                     }
  297. #endif
  298.                 }
  299.             }
  300.         }
  301.         if (isOpen())
  302.         {
  303.             return true;
  304.         }
  305.         return false;
  306.     }
  307.  
  308.     string currentCombo()
  309.     {
  310.         stringstream temp;
  311.         temp<<(rakeOrder[0]+1);
  312.         for (int i=1;i<patience;i++)
  313.         {
  314.             temp<<'-';
  315.             temp<<(rakeOrder[i]+1);
  316.         }
  317.         return temp.str();
  318.     }
  319.  
  320. };
  321.  
  322.  
  323.  
  324. int main()
  325. {
  326.     char command,saveFile;
  327.     int iterations,timesToRake,numberOfPins,lockTrials,updateFreq=0,bestPercentages[numTopCombos],openedLocks=0,progress=0;
  328.     bool rakeUpwards;
  329.     Lock *bogusLock;
  330.     string fastestCombo[numTopCombos],filename,firstCombo;
  331.     cout<<"JK's Raking Analyser rewritten in funky C++ BY Safety0ff\n"
  332.     "--------------------------------------------------------\n"
  333.     "Pin number convention:\n"
  334.     " i.e.:\n"
  335.     "     pin #  1 2 3 4 5 6...etc\n"
  336.     " back of lock <======> front of lock\n"
  337.     " tip of key <=========> bow of key\n"
  338.     "----------------------------------------\n"
  339.     "The values in parentheses represent static test parameters used to generate the results on JK's site\n\n"
  340.     "Upward raking consists of moving the pick up by one position for each pin you pass\n"
  341.     "----------------------------------------\n";
  342.     while (true)    // Main loop
  343.     {
  344.         for (int k=0;k<numTopCombos;k++)
  345.         {
  346.             bestPercentages[k]=0;
  347.         }
  348.         cout<<
  349.         "\n\n--------------------\n"
  350.         "Menu\n"
  351.         "--------------------\n"
  352.         "(R)andom Rakes\n"
  353.         "(S)ingle Rake\n"
  354.         "(B)rute Force all Rakes\n"
  355.         "(D)Brute force range of rakes\n"
  356.         "(T)ranslate pin # conventions\n"
  357.         "(Q)uit\n"
  358.         "\nCommand: ";
  359.         cin>>command;
  360.         cin.sync();
  361.         command=toupper(command);
  362.         switch (command)
  363.         {
  364.         case 'T':
  365.             convertConvention();
  366.             continue;
  367.         case 'D':
  368.         case 'R':
  369.         case 'B':
  370.             break;
  371.         case 'Q':
  372.             cout<<"Quitting...";
  373.             return 0;
  374.         case 'S':
  375.             iterations=1;
  376.             updateFreq=0;
  377.             break;
  378.         default:
  379.             cout<<"**Invalid choice**";
  380.             continue;
  381.         }
  382.         while (true)        // Setup loop
  383.         {
  384.  
  385.             cout<<"Rake upwards(Y/N)? ";
  386.             if (toupper(getchar())=='Y')
  387.             {
  388.                 rakeUpwards=true;
  389.             }
  390.             else
  391.             {
  392.                 rakeUpwards=false;
  393.             }
  394.             cin.sync();
  395.             cout<<"How many pins? ";
  396.             cin>>numberOfPins;
  397.             cout<<"How many rakes per combo? ";
  398.             cin>>timesToRake;
  399.             cout<<"How many locks to test each combo(20000)? ";
  400.             cin>>lockTrials;
  401.             if (command!='S')
  402.             {
  403.                 if (command=='B')
  404.                 {
  405.                     iterations=(int) pow((float)numberOfPins,(float)timesToRake);
  406.                     cout<<"Going to iterate through "<<iterations<<" rake(s)\n";
  407.                 }
  408.                 else if (command=='R')
  409.                 {
  410.                     cout<<"How many random combos to try (200000)? ";
  411.                     cin>>iterations;
  412.                 }
  413.                 else
  414.                 {
  415.                     cout<<"How many combos to try? ";
  416.                     cin>>iterations;
  417.                 }
  418. #ifndef NOPROGRESS
  419. #ifndef PROGRESS
  420.                 cout<<"How often do you want results so far? ";
  421.                 cin>>updateFreq;
  422. #endif
  423. #endif
  424.             }
  425.             if (numberOfPins<=0||timesToRake<=0||lockTrials<=0||iterations<=0
  426. #ifndef PROGRESS
  427. #ifndef NOPROGRESS
  428.                     ||updateFreq<0
  429. #endif
  430. #endif
  431.                )
  432.             {
  433.                 cout<<"\n\nNo values less than or equal to zero dummy.\n\n";
  434.                 continue;
  435.             }
  436.             if (cin.fail())
  437.             {
  438.                 cin.clear();
  439.                 cin.ignore(INT_MAX, '\n');
  440.                 cout << "\n\nAn input error occured - please try again.\n\n";
  441.                 continue;
  442.             }
  443.             else
  444.             {
  445.                 break;
  446.             }
  447.         }
  448.         bogusLock=new Lock(numberOfPins,timesToRake);
  449.         if (command=='R')
  450.         {
  451.             bogusLock->setRandomCombo();
  452.         }
  453.         else if (command=='B')
  454.         {
  455.             bogusLock->setZeroCombo();
  456.         }
  457.         else
  458.         {
  459.             bogusLock->setCombo();
  460.             firstCombo=bogusLock->currentCombo();
  461.         }
  462.  
  463.  
  464.         progress=iterations/100;
  465. #ifdef PROGRESS
  466.         cout<<"\rSimulation 0% completed";
  467. #endif
  468.         for (int i=1;i<=iterations;i++)
  469.         {
  470.             openedLocks=0;
  471.             if (rakeUpwards)
  472.             {
  473.                 for (int j=0;j<lockTrials;j++)
  474.                 {
  475.                     bogusLock->newLock();
  476.                     if (bogusLock->rakeUpwards())
  477.                     {
  478.                         openedLocks++;
  479.                     }
  480.                 }
  481.             }
  482.             else
  483.             {
  484.                 for (int j=0;j<lockTrials;j++)
  485.                 {
  486.                     bogusLock->newLock();
  487.                     if (bogusLock->rake())
  488.                     {
  489.                         openedLocks++;
  490.                     }
  491.                 }
  492.             }
  493.  
  494.  
  495.  
  496.             if (openedLocks>0)
  497.             {
  498.                 for (int k=0;k<numTopCombos;k++)
  499.                 {
  500.                     if (openedLocks>=bestPercentages[k])
  501.                     {
  502.                         for (int i=numTopCombos-1;i>k;i--)
  503.                         {
  504.                             bestPercentages[i]=bestPercentages[i-1];
  505.                             fastestCombo[i]=fastestCombo[i-1];
  506.                         }
  507.                         bestPercentages[k]=openedLocks;
  508.                         fastestCombo[k]=bogusLock->currentCombo();
  509.                         break;
  510.                     }
  511.                 }
  512.             }
  513. #ifndef NOPROGRESS
  514. #ifndef PROGRESS
  515.             if ((updateFreq>0)&&((i)%updateFreq==0))
  516.             {
  517.                 cout<<endl<<i<<" combo's tested!\nBest so far:\n";
  518.                 for (int k=0;k<numTopCombos;k++)
  519.                 {
  520.                     cout<<(k+1)<<".  "<<fastestCombo[k]<<" ["<<(int)((double)bestPercentages[k]*100/(double)lockTrials)<<"%]\n";
  521.                 }
  522.             }
  523. #endif
  524. #ifdef PROGRESS
  525.             if (i%progress==0)
  526.             {
  527.                 cout<<"\rSimulation "<<(int)((double)i*100/(double)iterations)<<"% completed";
  528.  
  529.             }
  530. #endif
  531. #endif
  532. #ifdef ITERATIONDISPLAY
  533.             cout<<"\rCombo "<<i<<"/"<<iterations;
  534. #endif
  535.             if (command=='R')
  536.             {
  537.                 bogusLock->setRandomCombo();
  538.             }
  539.             else
  540.             {
  541.                 if (!bogusLock->incrementCombo())
  542.                 {
  543.                     break;
  544.                 }
  545.             }
  546.         }
  547.         cout<<"\nSimulation Ended.\n"
  548.         "Results:\n";
  549.         for (int j=0;j<numTopCombos;j++)
  550.         {
  551.             if (bestPercentages[j]!=0)
  552.             {
  553.                 cout<<(j+1)<<".  "<<fastestCombo[j]<<" ["<<(int)((double)bestPercentages[j]*100/(double)lockTrials)<<"%] ["<<bestPercentages[j]<<"]\n";
  554.             }
  555.         }
  556.         cout<<"\nSave results?";
  557.         cin>>saveFile;
  558.         cin.sync();
  559.         if (saveFile=='Y'||saveFile=='y')
  560.         {
  561.             ofstream fout;
  562.             while (true)
  563.             {
  564.                 cout << "Enter filename for data file: ";
  565.                 cin  >> filename;
  566.                 filename+=".txt";
  567.                 fout.open (filename.c_str(),ios_base::app);
  568.                 if (fout.fail())
  569.                 {
  570.                     cout << "Unable to open file output stream <" << filename << ">.\nPlease try again.";
  571.                     fout.clear();
  572.                 }
  573.                 else
  574.                 {
  575.                     fout.seekp(0, ios::end);
  576.                     fout<<
  577.                     "-----------------\n"
  578.                     "Settings:\n";
  579. #ifdef DEFLECT
  580.                     fout<<"    DEFLECT defined\n";
  581. #endif
  582.                     if (command=='R')
  583.                     {
  584.                         fout<<" Random mode:\n";
  585.                     }
  586.                     else if (command=='S')
  587.                     {
  588.                         fout<<" Single mode:\n";
  589.                         if (rakeUpwards)
  590.                         {
  591.                             fout<<"  -Raking upwards\n";
  592.                         }
  593.                         fout<<"    # of Pins: "<<numberOfPins;
  594.                         fout<<"\n    Rakes per combo: "<<timesToRake;
  595.                         fout<<"\n    # of locks to test: "<<lockTrials;
  596.                         fout<<"\nResults:\n"
  597.                         <<firstCombo<<"   ["<<(int)((double)openedLocks*100/(double)lockTrials)<<"%] ["<<openedLocks<<"]\n";
  598.                         fout<<"-----------------";
  599.                         cout<<"Results saved to: "<<filename<<endl;
  600.                         break;
  601.                     }
  602.                     else if (command=='B')
  603.                     {
  604.                         fout<<" Brute force mode:\n";
  605.                     }
  606.                     else if (command=='D')
  607.                     {
  608.                         fout<<" Range mode:\n";
  609.                         fout<<"    First combo: "<<firstCombo<<endl;
  610.                         fout<<"    Last combo: "<<bogusLock->currentCombo()<<endl;
  611.                     }
  612.                     if (rakeUpwards)
  613.                     {
  614.                         fout<<"  -Raking upwards\n";
  615.                     }
  616.                     fout<<"    # of Pins: "<<numberOfPins;
  617.                     fout<<"\n    Rakes per combo: "<<timesToRake;
  618.                     fout<<"\n    # of locks to test: "<<lockTrials;
  619.                     if (command=='R')
  620.                     {
  621.                         fout<<"\n    Random Combos tried: "<<iterations;
  622.                     }
  623.                     else
  624.                     {
  625.                         fout<<"\n    Total Combos tried: "<<iterations;
  626.                     }
  627.                     fout<<"\nResults:\n";
  628.                     for (int k=0;k<numTopCombos;k++)
  629.                     {
  630.                         if (bestPercentages[k]!=0)
  631.                         {
  632.                             fout<<(k+1)<<".  "<<fastestCombo[k]<<" ["<<(int)((double)bestPercentages[k]*100/(double)lockTrials)<<"%] ["<<bestPercentages[k]<<"]\n";
  633.                         }
  634.                     }
  635.                     fout<<"-----------------";
  636.                     cout<<"Results saved to: "<<filename<<endl;
  637.                     break;
  638.                 }
  639.             }
  640.             fout.close();
  641.         }
  642.         else
  643.         {
  644.             cout<<"Proceeding without saving results\n";
  645.         }
  646.         delete bogusLock;
  647.     }
  648.     return 0;
  649. }
  650. void convertConvention()
  651. {
  652.     int numberOfPins,timesToRake,i,j;
  653.     int *temp;
  654.     bool *converted;
  655.     while (true)
  656.     {
  657.         cout<<"How many pins? ";
  658.         cin>>numberOfPins;
  659.         cout<<"How many rakes per combo? ";
  660.         cin>>timesToRake;
  661.         if (cin.fail())
  662.         {
  663.             cin.clear();
  664.             cin.ignore(INT_MAX, '\n');
  665.             cout << "\n\nAn input error occured - please try again.\n\n";
  666.             continue;
  667.         }
  668.         else
  669.         {
  670.             break;
  671.         }
  672.     }
  673.     temp=new int [timesToRake];
  674.     converted=new bool [timesToRake];
  675.     for(j=0;j<timesToRake;j++){
  676.         converted[j]=false;
  677.     }
  678.     for ( i=0;i<timesToRake;i++)
  679.     {
  680.         cout<<"Position #"<<i+1<<" rake pin number:";
  681.         cin>>temp[i];
  682.         if (cin.fail())
  683.         {
  684.             cin.clear();
  685.             cin.ignore(INT_MAX, '\n');
  686.             cout << "\n\nAn input error occured - please try again.\n\n";
  687.             i--;
  688.             continue;
  689.         }
  690.         if (!(temp[i]<=numberOfPins&&temp[i]>0))
  691.         {
  692.             cout<<"Invalid pin number, try again.\n";
  693.             i--;
  694.         }
  695.     }
  696.     for( i=1;i<=numberOfPins;i++)
  697.     {
  698.         for( j=0;j<timesToRake;j++)
  699.         {
  700.             if(temp[j]==i&&!converted[j]){
  701.                 temp[j]=numberOfPins-i+1;
  702.                 converted[j]=true;
  703.             }
  704.         }
  705.     }
  706.     for(j=0;j<timesToRake;j++){
  707.         if(j==timesToRake-1){
  708.             cout<<temp[j];
  709.         }
  710.         else{
  711.             cout<<temp[j]<<"-";
  712.         }
  713.     }
  714.     delete [] temp;
  715. }
Advertisement
Add Comment
Please, Sign In to add comment