Skip to content

Instantly share code, notes, and snippets.

@baltazarparra
Last active September 16, 2016 01:35
Show Gist options
  • Save baltazarparra/2c00a151c42cb3513775c750314deb83 to your computer and use it in GitHub Desktop.
Save baltazarparra/2c00a151c42cb3513775c750314deb83 to your computer and use it in GitHub Desktop.
(function(jokenpo){
'use strict';
var $rock = document.querySelector('[data-js="rock"]');
var $paper = document.querySelector('[data-js="paper"]');
var $scissor = document.querySelector('[data-js="scissor"]');
var $userChoice = document.querySelector('[data-js="user-choice"]');
var $cpuChoice = document.querySelector('[data-js="cpu-choice"]');
var $userScore = document.querySelector('[data-js="userScore"]');
var $cpuScore = document.querySelector('[data-js="cpuScore"]');
var app = (function appController() {
return {
init: function init() {
this.initEvents();
},
initEvents: function initEvents() {
$rock.addEventListener('click', this.optionChoice('rock'));
$paper.addEventListener('click', this.optionChoice('paper'));
$scissor.addEventListener('click', this.optionChoice('scissor'));
},
cpuChoice: function cpuChoice() {
var cpuChoice = Math.random();
if (cpuChoice < 0.3) {
var cpuChoiceOutput = 'rock';
$cpuChoice.setAttribute("src", cpuChoiceOutput + ".svg");
return cpuChoiceOutput;
} else if (cpuChoice < 0.6) {
var cpuChoiceOutput = 'paper';
$cpuChoice.setAttribute("src", cpuChoiceOutput + ".svg");
return cpuChoiceOutput;
}
var cpuChoiceOutput = 'scissor';
$cpuChoice.setAttribute("src", cpuChoiceOutput + ".svg");
return cpuChoiceOutput;
},
optionChoice: function optionChoice(option) {
return function () {
var cpuOption = app.cpuChoice();
$userChoice.setAttribute("src", option + ".svg");
jokenpo.play(option, cpuOption);
}
}
};
})();
app.init();
})(window.jokenpo);
@fdaciuk
Copy link

fdaciuk commented Sep 15, 2016

Só pra ver se te ajuda, vou colocar como eu resolvi a parte de dados (sem manipulação de DOM):

;(function (win) {
  'use strict';

  function jokenpo (firstUser, secondUser) {
    var usersPoints = {};
    usersPoints[firstUser] = 0;
    usersPoints[secondUser] = 0;

    function play (choices) {
      var users = Object.keys(usersPoints);
      var usersChoices = users.reduce(function (acc, user) {
        acc[user] = choices[user];
        return acc;
      }, {});

      return whoWins(usersChoices);
    }

    function whoWins (usersChoices) {
      var combinations = {
        'rock paper': 'paper',
        'rock scisor': 'rock',
        'paper scisor': 'scisor'
      };

      var choices = Object.keys(usersChoices).map((user) => {
        return usersChoices[user];
      });

      if (areChoicesTheSame(choices)) {
        return generateScore({
          usersChoices: usersChoices,
          result: null
        });
      }

      var combinationMatched = Object.keys(combinations).filter(function (combination) {
        return combination.indexOf(choices[0]) > -1 &&
          combination.indexOf(choices[1]) > -1
      })[0];

      var result = combinations[combinationMatched];

      return generateScore({
        usersChoices: usersChoices,
        result: result
      });
    }

    function areChoicesTheSame (choices) {
      return choices[0] === choices[1];
    }

    function generateScore (result) {
      Object.keys(usersPoints).forEach(function (user) {
        if (result.usersChoices[user] === result.result) {
          usersPoints[user] += 1;
        }
      });
      return score;
    }

    function score (user) {
      if (user && !isValidUser(user)) {
        throw new Error('Usuário não existe');
      }
      return user ? usersPoints[user] : usersPoints;
    }

    function isValidUser (user) {
      return Object.keys(usersPoints).some(function (u) {
        return user === u;
      });
    }

    return {
      score: score,
      play: play
    };
  }

  win.jokenpo = jokenpo;
})(window);

Um teste de uso:

var game = jokenpo('fernando', 'machine');
console.log(game.score());

game.play({
  fernando: 'rock',
  machine: 'scisor'
});
console.log(game.score());

Veja se você consegue entender tudo.
Baixe ele e tente ir modificando as opções, colocando console.log para ver o que acontece em cada momento do código. Assim vai ficar mais fácil de entender =)

Se ficou alguma dúvida com relação a esse código, só avisar =)

@fdaciuk
Copy link

fdaciuk commented Sep 16, 2016

Vou tentar explicar a ideia base de como você pode manter os valores usando uma "closure":

  1. Você cria uma função que vai conter todo o código;
  2. Dentro dessa função, você vai iniciar as variáveis que você quer guardar os valores;
  3. Essa função retorna um objeto, com algum método que vai alterar os valores internos dela.

Só isso! Fazendo isso, a cada vez que você executar essa função, os valores internos serão diferentes. Mas se você usar o objeto retornado, você estará trabalhando com os valores guardados pela "closure".

Como fica na prática, seguindo os passos acima?

// Passo 1: Criar a função que vai guardar toda a minha aplicação.
function main () {
  // Passo 2: Iniciar a variável que vai guardar os valores.
  var value = 0;

  // Passo 3: Retornar um objeto que contenha um método que modifica o valor guardado. Só como exemplo, a cada vez que chamar esse método, vou somar 1 ao valor de "value", e retornar esse valor:
  return {
    sum: function sum () {
      value += 1;
      return value;
    }
  };
}

É só isso! Como é o funcionamento da closure? Vamos criar uma aplicação usando essa função:

var app = main();
console.log(app.sum()); // 1
console.log(app.sum()); // 2
console.log(app.sum()); // 3

Veja que, a cada vez que eu chamo app.sum(), é incrementado 1 em value. app é o objeto retornado pela função main.

O real uso da closure se dá quando você precisa criar mais de uma aplicação ao mesmo tempo, fazendo uma "concorrência" entre as duas aplicações, mas usando a mesma função:

var app = main();
var app2 = main();
console.log(app.sum()); // 1
console.log(app.sum()); // 2
console.log(app2.sum()); // 1
console.log(app.sum()); // 3
console.log(app2.sum()); // 2

Olha só que legal! Uma não interfere na outra! Essa é a ideia de usar closures =)

Consegui entender?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment