-
-
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); |
baltazarparra
commented
Sep 15, 2016
Show cara! Tá indo bem! A ideia é essa mesmo: faz funcionar, depois refatora =)
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 =)
Vou tentar explicar a ideia base de como você pode manter os valores usando uma "closure":
- Você cria uma função que vai conter todo o código;
- Dentro dessa função, você vai iniciar as variáveis que você quer guardar os valores;
- 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?