Orlin

Skrypt losujący wiele nagrod według list preferencji

Jul 28th, 2016
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // SPOSÓB UŻYCIA:
  2. // Otworzyć w przeglądarce Firefox / Opera / Chrome stronę z wpisem
  3. // otworzyć konsolę (CTRL+SHIFT+K w Fx, CTRL+SHIFT+J w Chrome/Opera)
  4. // wkleić poniższy kod do konsoli i go wykonać (Enter)
  5.  
  6.  
  7. // rozwiń listę plusujacych
  8. var vajax = document.getElementsByClassName('showVoters ajax');
  9. if(vajax.length>0)
  10.     vajax[0].click();
  11. console.log(new Date().toISOString()); // Data losowania
  12. alert('Lista plusujących rozwinięta'); // taki workaround, żeby nie bawić się w czekanie na AJAX-a (ale chyba tylko @ Firefox - w innych rozwiń ręcznie lub odpal skrypt 2 razy)
  13.  
  14.  
  15.   //////////////////////////////////////////////////////////////
  16.  /////////// zebranie danych z komentarzy
  17. //////////////////////////////////////////////////////////////
  18. var cmnts = document.getElementsByClassName('sub')[0].getElementsByClassName('author ellipsis'); // komentarze do wpisu
  19. var i, j, k, s='', name, prefs, maxPrefs=0, userPrefs, txts, txt, tm, tm0, cnt=0, rejected='';
  20. var preferences = [], notVoters='';
  21.  
  22. // najpierw zebranie listy plusujących
  23. var vs = ',';
  24. var vl = document.getElementsByClassName('voters-list')[0].getElementsByTagName('a');
  25. for(var i=0; i<vl.length; ++i)
  26.     vs += vl[i].innerHTML;
  27. vs+=',';
  28.  
  29. // a tu szukamy już komentarzy z głosami w formacie [[1,2,3,...]] (dopuszczalne spacje i inne białe znaki za cyframi i przecinkami)
  30. for(i=0; i<cmnts.length; ++i)
  31. {
  32.   name = cmnts[i].children[0].children[0].innerHTML;
  33.   txts = cmnts[i].parentNode.getElementsByClassName('text');
  34.   if(txts.length>0 && txts[0])
  35.   {
  36.     txt = txts[0].innerHTML;
  37.         tm = txt.match(/\[\[\s*\d+\s*(,\s*\d+\s*)*\]\]/);
  38. //    tm = txt.match(/\[{1,2}\s*\d+\s*(,\s*\d+\s*)*\]{1,2}/); // odkomentować, jeśli dopuszczamy też głosy z pojedynczymi nawiasami kwadratowymi    
  39.     if(tm)
  40.     {
  41. //      tm0 = tm[0].replace(/^\[([^\[])/, "[[$1"); //  [ -> [[
  42. //      tm0 = tm0.replace(/([^\[])\]$/, "$1]]");  //   ] -> ]]
  43. //      tm0 = tm0.replace(/\s*/g, '').replace(/\[/g, '').replace(/\]/g, '');
  44.       tm0 = tm[0].replace(/\s*/g, '').replace(/\[/g, '').replace(/\]/g, '');
  45.       prefs = tm0.split(',');
  46.       prefs2 = Array.from(new Set(prefs)); // usuwamy duplikaty...
  47.             if(prefs2.length != prefs.length)
  48.             {
  49.                 alert('Zdublowane... Czyżby próba oszustwa?\n'+name);
  50.                 continue;
  51.             }
  52.            
  53.             // czy zaplusowal(a) pierwszy wpis?
  54.             if(vs.indexOf(','+name+',') == -1)
  55.             {
  56.                 notVoters += name+',';
  57.                 continue; // zakomentować, jeśli nie dyskwalifikujemy tych, co nie zaplusowali
  58.           }
  59.       userPrefs = {};
  60.       userPrefs.name = name;
  61.       userPrefs.prefs = prefs2;
  62.       preferences.push(userPrefs);
  63.      
  64.       if(prefs.length > maxPrefs) // szukamy w listach preferencji najwyższego numeru nagrody
  65.         maxPrefs = prefs.length;
  66.     }
  67.     else
  68.     { // Tu sobie zapisujemy odrzucone komentarze - odrzucone ze względu na brak poprawnego głosu: [[w, x, y, z]]
  69.       rejected += name +': ' + txt.replace(/\s+/g, ' ').replace(/(<([^>]+)>)/ig,"").replace(/^\s+|\s+$/g,"") +'\n-----------------------\n';
  70.     }
  71.   }
  72. } // for(i)
  73.  
  74. console.log('----------------\nNie zaplusowali:\n' + notVoters);
  75. console.log('----------------\nOdrzucone komentarze:\n' + rejected);
  76.  
  77.  
  78. /////////// lista chętnych na kolejne nagrody - wraz z informacją o pozycji na liście preferencji danego użytkownika
  79.  
  80. var items = [];
  81. for(j=0; j<maxPrefs; ++j)
  82. {
  83.   for(i=0; i<preferences.length; ++i)
  84.   {
  85.     if(preferences[i].prefs.length>0 && preferences[i].prefs[0]>0)
  86.     {
  87.       if(items[preferences[i].prefs[0]] == undefined)
  88.             {
  89.         items[preferences[i].prefs[0]] = [];
  90.             }
  91.             var playerPri = {};
  92.             playerPri.name = preferences[i].name;
  93.             playerPri.priority = j;
  94.             playerPri.item = preferences[i].prefs[0];
  95.             items[preferences[i].prefs[0]].push(playerPri);
  96. //              items[preferences[i].prefs[0]].push(preferences[i].name +'('+ j + ')');
  97.             preferences[i].prefs.shift();
  98.     }
  99.   }
  100. }
  101.  
  102.   //////////////////////////////////////////////////////////////
  103.  // zwraca listę nagród wraz z zainteresowanymi (i priorytetem wg listy preferencji użytkownika)
  104. //////////////////////////////////////////////////////////////
  105. function listUsersPerItems(arr)
  106. {
  107.   var i, j, out='';
  108.   for(i=0; i<arr.length; ++i)
  109.   {
  110.     if(arr[i] == undefined)
  111.       continue;
  112. //    var il = arr[i].split(',').length - 1;
  113.         var il = arr[i].length;
  114.         if(arr[i].length>0)
  115.     out += (arr[i][0].item<10?' ':'') + arr[i][0].item + '(' + il + '): ';
  116.         for(j=0; j<arr[i].length; ++j)
  117.             out += arr[i][j].name + '(' + arr[i][j].priority + '), ';
  118.     out += '\n';
  119.   }
  120.   return out;
  121. }
  122.  
  123. //console.log(listUsersPerItems(items));
  124. //console.log(items.length);
  125. items.sort(function(a, b) {
  126.     return a.length - b.length;
  127. });  // posortowanie - od najmniej pożądanej pozycji, do najbardziej
  128. //console.log(items.length);
  129. console.log('----------------------------\nLista nagród wraz listą zainteresowanych:\n' + listUsersPerItems(items)); // wypisanie uczestników w podziale na nagrody
  130.  
  131. // rozdajemy/losujemy
  132.  
  133. //var firstTime = true; ////TEMP EDIT: żeby 4 wylosować dwa razy
  134.  
  135. var luckVsOptimalFactor = 4; // współczynnik definiujący, jak bardzo preferować tych, którzy mieli losowaną nagrodę wyżej na liście
  136.                             // 0 - wszyscy są traktowani po równo, max = liczba nagród - szanse )
  137. var winner, winners = [], pos, maxLuck, luckRuler, curLuckRange, rand;
  138. for(i=0; i<items.length; ++i)
  139. {
  140.     if(items[i] == undefined || items[i].length<1
  141. //     || items[i][0].item==15 ////TEMP EDIT: nagroda #15 chyba nic nie warta, więc jej też nie losujemy
  142.     )
  143.         continue;
  144.     winner = {};
  145.   if(items[i].length==1)
  146.   {
  147.          // wygrywa, bo nie było innych chętnych
  148.         winner.name = items[i][0].name;
  149.         winner.item = items[i][0].item;
  150.         winner.priority = items[i][0].priority;
  151.         winners.push(winner);
  152. //alert(winner.name);
  153.     } // if 1 chętny
  154.     else
  155.     {  // więcej chętnych
  156.     maxLuck = items.length;
  157.     luckRuler = [];
  158.     luckRangeSum = 0;
  159.    
  160.     for(k=0; k<items[i].length; ++k)
  161.     {
  162.      
  163.       curLuckRange = maxLuck - items[i][k].priority * luckVsOptimalFactor;
  164.       if(curLuckRange<1)    // żeby dać jakieś minimalne szanse nawet tym, którzy wg współczynnika luckVsOptimalFactor
  165.         curLuckRange = 1;  // nie powinni już być brani pod uwagę. W przeciwnym razie można zakomentować te 2 linijki
  166.      
  167.       ;                   // tak na wypadek nieumiejętnego zakomentowania powyższej linijki i pozostawienie samego ifa
  168.       luckRangeSum += curLuckRange;
  169.       luckRuler.push(luckRangeSum); // każdy chętny dostaje swój przedział
  170.     }      
  171.     rand = (Math.round(Math.random() * 1000000) + new Date().getTime() + items[i].length + luckRangeSum) % luckRangeSum;  // losujemy liczbę...
  172. //alert(luckRuler.toString() + '\nrand='+rand+'\nluckRangeSum='+luckRangeSum);
  173.     k=0;
  174.     while(rand > luckRuler[k])  // ... i sprawdzamy do czyjego przedziału wpadła
  175.       ++k;
  176.     winner.name = items[i][k].name;
  177.         winner.item = items[i][k].item;
  178.         winner.priority = items[i][k].priority;
  179.         winners.push(winner); // dodajemy zwycięzcę do listy
  180.    
  181.     } // else
  182.  
  183.     // usuwamy zwycięzce z pozostałych list - żeby nie wygrał ponownie
  184.     for(j=i+1; j<items.length; ++j)
  185.     {
  186.     if(items[j] != undefined && items[j].length>0 && winner.name != undefined)
  187.     {
  188.  
  189.       pos = items[j].map(function(e) { return e.name; }).indexOf(winner.name);
  190.      
  191.      if(pos>=0)
  192.        items[j].splice(pos, 1);
  193.     }  
  194.     } // for (j)
  195. //  //// TEMP EDIT: gra #4 jest dwa razy {
  196. //      if(items[i][0].item==4 && firstTime)
  197. //          {
  198. //              firstTime = false;
  199. //              --i;
  200. // TODO: usunąć zwycięzce z bieżącej listy - bo normalnie usuwamy tylko z kolejnych
  201. //          }
  202. //  //// TEMP EDIT - gra $4 KONIEC       }
  203. } // for(i)
  204.  
  205.   ////////////////////////////////////////////////
  206.  // Funkcja drukująca (w konsoli) zwycięzców
  207. //////////////////////////////////////////////
  208. function printWinners(arr)
  209. {
  210.     var out='------------\nZwycięzcy:\n';
  211.     for(var i=0; i<arr.length; ++i)
  212.     {
  213.       out += arr[i].name + ' - ' + arr[i].item + '(' + arr[i].priority + ')\n';
  214.     }  
  215.     // return out;
  216.     console.log(out);
  217. }
  218. /*
  219. // Opcjonalne sortowanie zwycięzców wg kolejności nagród (w przeciwnym razie jest od najmniej popularnej/pożądanej do najbardziej)
  220. winners.sort(function(a, b) {
  221.     return a.item - b.item;
  222. });
  223. */
  224. printWinners(winners);
  225.  
  226. // TODO: uporządkować
Advertisement
Add Comment
Please, Sign In to add comment