<pedrocorreia.net ⁄>
corner
<mySearch ⁄> <mySearch ⁄>

corner
 
corner
<mySnippets order="rand" ⁄> <mySnippets order="rand" ⁄>

corner
 
corner
<myContacts ⁄> <myContacts ⁄>

<email ⁄>


pc@pedrocorreia.net

<windows live messenger ⁄>


pedrojacorreia@hotmail.com

<myCurriculum type="pdf" ⁄>


Download
corner
 
corner
<myBlog show="last" ⁄> <myBlog show="last" ⁄>

corner
 
corner
<myNews show="rand" ⁄> <myNews show="rand" ⁄>

corner
 
corner
<myNews type="cat" ⁄> <myNews type="cat" ⁄>

corner
 
corner
<myQuote order="random" ⁄> <myQuote order="random" ⁄>

corner
 
corner
<myPhoto order="random" ⁄> <myPhoto order="random" ⁄>

<pedrocorreia.net ⁄>
corner
 
corner
<myAdSense ⁄> <myAdSense ⁄>

corner
 
corner
<myVisitorsMap ⁄> <myVisitorsMap ⁄>

corner
 
 

<Array.prototype, Shuffling e ... EuroMilhões ⁄ >




clicks: 10910 10910 2008-10-12 2008-10-12 goto mySnippets mySnippets javascript  Download  Bookmark This Bookmark This



Lendo o titulo, o jogo EuroMilhões parece estar um pouco fora do contexto, mas é mesmo propositado, pois irei dar um exemplo do preenchimento de um boletim do EuroMilhões, sendo esse preenchimento totalmente aleatório, lá mais para a frente estará tudo explicado.

O Javascript é uma linguagem de programação Prototype-based, é um estilo de OOP, porém as Classes não existem e paradigmas como a herença são obtidas através de cloning, se tiverem curiosidade consultem este link para obter mais informações.

Neste snippet iriei adicionar métodos à Class Array, para tal recorro ao prototype, isto faz como possa possa utilizar os métodos novos, em qualquer array, pois fica disponibilizado para toda a class e as variáveis instanciadas.

Shuffling, neste snippet, terá como sentido baralhar um Array, de modo a podermos obter valores aleatórios. Não fará muito sentido num jogo como o EuroMilhões obter os números de forma aleatória, pois para a chave final é irrelevante que saia o 1,2,3 ou 3,1,2; porém fica esse exemplo também.

O exemplo de shuffling que vou dar é quase que intuitivo, imaginemos que temos 1 array de 20 posições e que queremos aleatoriamente alterar a disposição do mesmo, porém o Array terá de manter todo o seu conteúdo inicial, i.e, se tiver os elements 1,2,3 no Array aleatoriamente gerado terei de conter esses valores igualmente, poderá (deverão) estar é em posições diferentes.

Tendo um array deste tipo var x=new Array(1, 2, 4, 5);, geramos 1 número aleatóro (número esse que irá corresponder ao indice do array, logo o número gerado terá de ser entre 0 e o tamanho do array-1, neste exemplo seria (0,3)), e copiamos esse valor para um array auxiliar, depois de copiado o valor o que fazemos é eliminar esse elemento no array; isto faz com que da próxima vez que geramos outro indice aleatório não corremos o risco de voltar a tirar o mesmo valor; e assim por diante ... Pode parecer confuso mas a olhar para o código será simples.

Irei dar 2 exemplos de shuffling, um que será destrutivo e outro que irá preservar o conteúdo do Array original, ou seja, num método o Array original irá ser substituido pelo Array aleatoriamente gerado, ao passo que outro irá preserver o Array original e irá retornar um novo Array, esse sim aleatorio.


Mas passemos ao código que irá (espero eu :)) facilitar a compreensão.

style.css
  1. *{padding: 0; margin: 0;}
  2.  
  3. body{
  4. font-family: Verdana, Tahoma, Arial, sans-serif;font-size: 62.5%;
  5. color: #000;background-color: #fff;text-align: center;
  6. }
  7.  
  8. div#title{
  9. margin: 0 auto; text-align: center; font-weight: 900;color: #cc0000;
  10. font-size: 3em;width: 27.4em; margin-bottom: .5em;
  11. }
  12.  
  13. div#board{
  14. margin: 0 auto; width: 11em; height: 24em;
  15. line-height: 1.8em;color: #00457B; text-align: center;
  16. }
  17.  
  18. div#board div.number, div#board div.star{
  19. float: left;border: solid .1em #ce5c00;
  20. width: 1.4em;height: 1.4em; margin-right: .1em; line-height: 1.4em;
  21. }
  22. div#board div.star {border: solid .1em #B71313;}
  23.  
  24. div#board div.number_selected{background-color: #ce5c00; color: #fff;}
  25. div#board div.star_selected{background-color: #D01F3C; color: #fff;}
  26.  
  27. input#bt_generate, select#ddl_bets{
  28. background-color: #ffffd4; border: solid .1em #e9b96e;
  29. font-size: 1em; font-weight: 700; padding: .4em;
  30. }
  31. select#ddl_bets {font-weight: normal; }



Events.js, este ficheiro será responsável por adicionar ou remover eventos a elementos/ objectos da página, por ex. load da página, quanto um elemento é actualizado, etc, etc.
  1. /**
  2. * Class Estática
  3. * Gerir Eventos
  4. */
  5. Events = function(){}
  6.  
  7. /**
  8. * Adicionar Evento
  9. *
  10. * Adaptada do seguinte url:
  11. * http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
  12. *
  13. * @param Object
  14. * @param Object
  15. * @param Object
  16. */
  17. Events.AddEvent = function(obj, type, fn){
  18. if(!obj) return;
  19.  
  20. this.RemoveEvent(obj, type, fn);
  21. if (obj.addEventListener) {
  22. obj.addEventListener(type, fn, false);
  23. }
  24. else {
  25. if (obj.attachEvent) {
  26. obj["e" + type + fn] = fn;
  27. obj[type + fn] = function(){
  28. obj["e" + type + fn](window.event);
  29. }
  30. obj.attachEvent("on" + type, obj[type + fn]);
  31. }
  32. }
  33. }
  34.  
  35. /**
  36. * Remover Evento
  37. *
  38. * Adaptada do seguinte url:
  39. * http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
  40. *
  41. * @param Object
  42. * @param Object
  43. * @param Object
  44. */
  45. Events.RemoveEvent = function(obj, type, fn){
  46. if (obj.removeEventListener) {
  47. try{obj.removeEventListener(type, fn, false);}catch(e){}
  48. }
  49. else{
  50. if (obj.detachEvent) {
  51. obj.detachEvent("on" + type, fn);
  52. obj[type + fn] = null;
  53. obj["e" + type + fn] = null;
  54. }
  55. }
  56. }



Dom.js, será o responsável por interagir com o DOM
  1. /**
  2. * Class estática
  3. * Class de suporte à interacção com o DOM
  4. *
  5. * @author: pedrocorreia.net
  6. */
  7. Dom = function(){}
  8.  
  9. /**
  10. * Obter objecto Html
  11. *
  12. * @param String Id Objecto
  13. */
  14. $=function(id){return document.getElementById(id);}
  15.  
  16. /**
  17. * Construir casa
  18. *
  19. * @param String Id
  20. * @param String Class Css
  21. * @param String Valor
  22. * @param String Objecto Html onde vai ser adicionada a caixa
  23. */
  24. $box = function(id, css_class, value, div) {
  25. var box = document.createElement('div');
  26. box.setAttribute('id', id);
  27. box.setAttribute((document.all?"className":"class"), css_class);
  28. box.innerHTML=value;
  29. $(div).appendChild(box);
  30. }
  31.  
  32. /**
  33. * Construir quebra de linha
  34. *
  35. * @param String Objecto Html onde vai ser adicionado a quebra de linha
  36. */
  37. $br = function(el){
  38. $(el).appendChild(document.createElement('br'));
  39. }
  40.  
  41. /**
  42. * Obter, atribuir ou acrescentar a Class Css
  43. * a um objecto Html
  44. *
  45. * @param String Id
  46. * @param Optional String Nome da Class
  47. * @param Optional Int Acrescentar Class?
  48. */
  49. $class=function(obj /**, css_class**/ /**, append*/){
  50. if(arguments[1] && arguments[2]){$(obj).className+=" "+arguments[1];}
  51. else if(arguments[1]){$(obj).className=arguments[1];}
  52. else{return $(obj).className;}
  53. }
  54.  
  55. /**
  56. * Private Method
  57. * Adicionar Elemento a uma DropdownList
  58. *
  59. * @param String Id
  60. * @param String Valor
  61. * @param String Descrição
  62. */
  63. var $ddListOption = function(id, value, description){
  64. var ddlOption = document.createElement("option");
  65. ddlOption.value = value;
  66. ddlOption.text = description;
  67. $(id).options.add(ddlOption);
  68. }



ArrayPrototype.js, como tinha dito anteriormente vamos adicionar vários métodos ao Objecto Array, que poderão ser utilizados por qualquer Array.
  1. /**
  2. * Array.prototype
  3. * Esta class adiciona vários métodos ao objecto Array
  4. *
  5. * @author pedrocorreia.net
  6. */
  7.  
  8. /**
  9. * Obter Array com valores aleatórios,
  10. * porém <u>preservando</u> o Array Original
  11. *
  12. * @param Optional Int Número máximo de elementos a preencher
  13. * @param Optional Bool Ordenar Array
  14. * @return Array
  15. */
  16. Array.prototype.PreserveShuffle = function(/** n_elems*/ /**, ordered*/){
  17. var n_elems=arguments[0];
  18. var ordered=arguments[1];
  19. if(isNaN(n_elems) || n_elems==""){n_elems=this.length;}
  20.  
  21. //fazer cópia fiel do array
  22. var randArray=this.Clone();
  23. //novo array para preencher
  24. var result=new Array();
  25. var pos=-1;
  26.  
  27. for(var i=0;i<n_elems;i++){
  28. pos=randArray.RandomIndex(); //gerar indice aleatório
  29. result.push(randArray[pos]); //preencher valor
  30. randArray.splice(pos,1); //remover elemento para não repetir
  31. }
  32.  
  33. randArray=null; //limpar array auxiliar
  34. return (ordered==1)?result.sort(this.SortNumber):result;
  35. }
  36.  
  37. /**
  38. * Gerar Array com valores aleatórios,
  39. * porém <u>destruindo</u> o Array Original
  40. *
  41. * @param Optional Int Número máximo de elementos a preencher
  42. * @param Optional Bool Ordenar Array
  43. * @return Array
  44. */
  45. Array.prototype.DestructiveShuffle = function(/** n_elems */ /**, ordered*/){
  46. var n_elems=arguments[0];
  47. var ordered=arguments[1];
  48. if(isNaN(n_elems) || n_elems==""){n_elems=this.length;}
  49.  
  50. //novo array para preencher
  51. var result=new Array();
  52. var pos=-1;
  53.  
  54. for(var i=0;i<n_elems;i++){
  55. pos=this.RandomIndex(); //gerar indice aleatório
  56. result.push(this[pos]); //preencher valor
  57. this.splice(pos,1); //remover elemento para não repetir
  58. }
  59.  
  60. this.Clear(); //remover todo o conteúdo do array
  61. for(var i=0, count=result.length;i<count;i++){
  62. //preencher novo array
  63. this.push(result[i]);
  64. }
  65. result=null;
  66. return (ordered==1)?this.sort(this.SortNumber):this;
  67. }
  68.  
  69. /**
  70. * Apagar todos (ou parcialmente) os itens do array
  71. *
  72. * @param Optional Int Começar em que posição?
  73. * @param Optional Int Acabar em que posição?
  74. */
  75. Array.prototype.Clear = function(/**start_at*/ /**, end_at*/){
  76. var len=this.length;
  77. if(len==0) return; //o array já se encontra vazio
  78.  
  79. var start_at=arguments[0];
  80. var end_at=arguments[1];
  81. if(isNaN(start_at)||start_at=="") start_at=0;
  82. if(isNaN(end_at)||end_at=="") end_at=len;
  83. if(start_at>end_at) {throw "INVALID_START_AT_ARGUMENT";}
  84.  
  85. this.splice(start_at, end_at);
  86. }
  87.  
  88. /**
  89. * Clonar array
  90. *
  91. * nota: esta é uma clonagem simples, se o array contiver
  92. * objectos, estes não serão "clonados"
  93. *
  94. * @return Array Clone
  95. */
  96. Array.prototype.Clone = function(){return this.slice(0);}
  97.  
  98. /**
  99. * Debug
  100. *
  101. * @param String Controlo Html
  102. * @param Optional String Legenda
  103. * @param Optional Bool Adicionar ou substituir informação?
  104. */
  105. Array.prototype.Verbose = function(obj /**, caption*/ /**, append */){
  106. var caption=arguments[1];
  107. var append=arguments[2];
  108. if(!caption) caption="";
  109.  
  110. if(append) {$(obj).innerHTML+=caption;}
  111. else{$(obj).innerHTML=caption;}
  112.  
  113. for (var i=0, count=this.length;i<count;i++){
  114. $(obj).innerHTML+=this[i]+";";
  115. }
  116. }
  117.  
  118. /**
  119. * Preencher Array com números
  120. *
  121. * @param Int Número de Elementos
  122. * @param Optional Int Começar em que valor
  123. */
  124. Array.prototype.FillNumbers = function (end_at /**, start_at*/ ){
  125. var start_at=arguments[1];
  126. if(isNaN(start_at) || start_at=="" ) {start_at=1;}
  127. if(start_at>end_at) {throw "INVALID_START_AT";}
  128.  
  129. for (var i=start_at; i<=end_at; i++){this.push(i);}
  130. return this;
  131. }
  132.  
  133. /**
  134. * Gerar indice aleatório
  135. * @return Int Indice gerado
  136. */
  137. Array.prototype.RandomIndex = function(){
  138. return Math.floor(Math.random() * this.length);
  139. }
  140.  
  141. /**
  142. * Ordenar Números
  143. * Adaptada de: http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_sort2
  144. *
  145. * @param Int
  146. * @param Int
  147. * @return Int
  148. */
  149. Array.prototype.SortNumber = function(a, b) {return a - b;}








Euromilhoes.js, a Class fica responsável por gerar o quadro (sim, porque fazer os 59 quadrados ainda cansa um pouco :)), usar o ArrayPrototype, etc. A dropdown das apostas foi gentilmente cedida (or maybe not ...) pelo site dos Jogos da Santa Casa
  1. /**
  2. * Esta class tem como objectivo implementar a geração de uma aposta de EuroMilhões
  3. *
  4. * @author pedrocorreia.net
  5. */
  6. Euromilhoes = function(){
  7.  
  8. //necessário para permitir os métodos privados
  9. //acederem aos métodos não-privados da Class
  10. var self=this;
  11.  
  12. //configurações html e css
  13. var _conf = {
  14. board: "board", //div da board
  15. verbose_span: "complete_set", //span para debug
  16. prefix_number: "numero", //prefixo da chave
  17. prefix_star: "estrela", //prefixo das estrelas
  18. css_number: "number", //class css da chave
  19. css_star: "star", //class css das estrelas
  20. lbl_numbers: "Números",
  21. lbl_stars: "Estrelas",
  22. css_sufix_selected: "_selected", //sufixo de um item selecionado
  23. bt_generate: "bt_generate", //gerar nova chave
  24. ddl_bets: "ddl_bets" //dropdown de apostas
  25. }
  26.  
  27. //definições do jogo
  28. var _game = {
  29. total_number: 50, //total de números
  30. total_star: 9, //total de estrelas
  31. number_split_at: 6, //quadrados por linha
  32. star_split_at: 3 //estrelas por linha
  33. }
  34.  
  35. /**
  36. * Método privado
  37. *
  38. * Construir boletim (só 1 aposta)
  39. */
  40. var _BuildGrid = function(){
  41.  
  42. //números
  43. for(var i=1;i<=_game.total_number;i++){
  44. $box(_conf.prefix_number+"_"+i, _conf.css_number, i, _conf.board);
  45. if(i%_game.number_split_at==0) {$br(_conf.board);}
  46. }
  47. $br(_conf.board); //quebra de linha
  48. $br(_conf.board); //quebra de linha
  49.  
  50. //estrelas
  51. for(var i=1;i<=_game.total_star;i++){
  52. $box(_conf.prefix_star+"_"+i, _conf.css_star, i, _conf.board);
  53. if(i%_game.star_split_at==0) {$br(_conf.board);}
  54. }
  55. }
  56.  
  57. /**
  58. * Método privado
  59. * Preencher DropdownList com o conjunto de apostas
  60. */
  61. _BuildBets = function(){
  62.  
  63. //apostas válidas
  64. var bets ={
  65. 5: {start: 2, end: 9},
  66. 6: {start: 2, end: 9},
  67. 7: {start: 2, end: 9},
  68. 8: {start: 2, end: 5},
  69. 9: {start: 2, end: 4},
  70. 10: {start: 2, end: 3},
  71. 11: {start: 2, end: 2}
  72. }
  73.  
  74. var value="", description="";
  75.  
  76. for (var bet in bets){
  77. for (var i=bets[bet].start; i<=bets[bet].end;i++){
  78. value=bet+"-"+i;
  79. description=bet+" "+_conf.lbl_numbers+" + "+i+" "+_conf.lbl_stars;
  80. $ddListOption(_conf.ddl_bets, value, description);
  81. }
  82. }
  83. }
  84.  
  85. /**
  86. * Obter Apostas
  87. *
  88. * @return Array
  89. */
  90. _GetBet = function(){
  91. var bet=$(_conf.ddl_bets).value;
  92. return bet.split("-");
  93. }
  94.  
  95. /**
  96. * Método privado
  97. * Selecionar números gerados
  98. *
  99. * @param Array Array de números a selecionar
  100. * @param String Prefixo do nome do objecto a selecionar
  101. * @param String Class Css
  102. */
  103. var _SelectBoxes = function(o, prefix, css_class){
  104. for(var i=0, count=o.length;i<count;i++){
  105. $class(prefix+"_"+o[i],css_class+_conf.css_sufix_selected,1);
  106. }
  107. }
  108.  
  109. /**
  110. * Método privado
  111. * Adicionar eventos
  112. */
  113. var _EventHandlers = function(){
  114. Events.AddEvent($(_conf.bt_generate),"click",self.GenerateEuroMilhoes);
  115. }
  116.  
  117. /**
  118. * Limpar boletim
  119. */
  120. var _ClearGrid = function(){
  121. for(var i=1;i<=_game.total_number;i++){
  122. $class(_conf.prefix_number+"_"+i,_conf.css_number);
  123. }
  124.  
  125. for(var i=1;i<=_game.total_star;i++){
  126. $class(_conf.prefix_star+"_"+i,_conf.css_star);
  127. }
  128. }
  129.  
  130. /**
  131. * Responsável pela geração das chaves
  132. * bem como o seu preenchimento
  133. */
  134. this.GenerateEuroMilhoes = function(){
  135. _ClearGrid(); //limpar boletim
  136.  
  137. var bet = _GetBet(); //obter apostas
  138.  
  139. //gerar números usanto o método Array.PreserveShuffle
  140. var a=new Array();
  141. var chave=a.FillNumbers(_game.total_number).PreserveShuffle(bet[0],1);
  142. _SelectBoxes(chave,_conf.prefix_number, _conf.css_number);
  143. chave.Verbose(_conf.verbose_span,_conf.lbl_numbers+": ");
  144.  
  145. //gerar estrelas usando o método Array.DestructiveShuffle
  146. var estrelas=new Array();
  147. _SelectBoxes(estrelas.FillNumbers(_game.total_star).DestructiveShuffle(bet[1],1),_conf.prefix_star, _conf.css_star);
  148. estrelas.Verbose(_conf.verbose_span,"<br>"+_conf.lbl_stars+": ",1);
  149. }
  150.  
  151. //construir boletim
  152. _BuildGrid();
  153.  
  154. //construir apostas
  155. _BuildBets();
  156.  
  157. //inicializar EventHandlers
  158. _EventHandlers();
  159. }



Init.js, o nome esclarece a finalidade deste ficheiro, será o responsável pela criação do objecto Euromilhoes, bem como gerar a 1ª chave
  1. /**
  2. * Função de Inicialização
  3. *
  4. * @author pedrocorreia.net
  5. */
  6. Init = function(){
  7. var euro_milhoes=new Euromilhoes();
  8. euro_milhoes.GenerateEuroMilhoes();
  9. }
  10.  
  11. Events.AddEvent(window,"load",Init);



index.htm, o nosso amigo html
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <title>Array.Prototype e EuroMilhões</title>
  6.  
  7. <script type="text/javascript" src="Events.js"></script>
  8. <script type="text/javascript" src="Dom.js"></script>
  9. <script type="text/javascript" src="ArrayPrototype.js"></script>
  10. <script type="text/javascript" src="Euromilhoes.js"></script>
  11. <script type="text/javascript" src="Init.js"></script>
  12. <link rel="stylesheet" type="text/css" href="style.css" media="all" />
  13. </head>
  14.  
  15. <body>
  16. <div id="title">Gerar Euromilhões</div>
  17. <div id="board"></div>
  18. <span id="complete_set"></span>
  19. <br /><br />
  20. <input type="button" value="Gerar Nova Chave" id="bt_generate" />
  21. <select id="ddl_bets"></select>
  22. </body>
  23. </html>




Aqui fica um screenshot:





Qualquer erro/ dúvida é só dizer!









clicks: 10910 10910 2008-10-12 2008-10-12 goto mySnippets mySnippets javascript  Download  Bookmark This Bookmark This