I have refactored the code for this game thanks to some great suggestions from woxxom
Now, once again, any suggestions still welcome. I am going to be improving the UX as a next phase (giving hints to the user etc).
I have also improved the consistency of naming IDs and using single/double quotes etc.
There was one slight oversight with woxxom's code in that he did this:
function restart() {
container.className = 'female';
sectionTitle.textContent = 'Ladies';
sectionTitle.classList.remove('tada');
sectionTitle.classList.add('slideInLeft');
hide(answer);
choices.ladies = [];
choices.gents = [];
// ladiesChoice and gentsChoice are not defined here
deanimateChoice(ladiesChoice);
deanimateChoice(gentsChoice);
choices.forEach(function(c) { element.disabled = false; });
}
However, the rest of the code was spot on! Here it is in its entirety:
(function(){
// Initializtion
var intro = getByID('intro');
var container = getByID('mainContainer');
var positionsContainer = getByID('positions');
var sectionTitle = getByID('sectionTitle');
var results = getByID('results');
var chosenPositions = getByID('chosenPositions');
// create positions
var positions = [
"Sixty-Nine",
"Missionary",
"Doggy style",
"Rodeo",
"Reverse Cowgirl",
"Girl on top",
"Zeus",
"Venus",
"Workout"
];
// and insert them into the DOM
positionsContainer.insertAdjacentHTML('beforeend',
positions.map(function(position, i){
return ' <button id="position-' + i + '" ' +
'class="choice-buttons">' + position +
'</button>';
}).join('')
);
var MAX_CHOICES = 2;
var choices = positionsContainer.querySelectorAll('button');
choices.ladies = [];
choices.gents = [];
getByID('play').onclick = play;
getByID('restart').onclick = restart;
choices.forEach(function(c) { c.onclick = choose; });
// only the intro is shown on game start
hide(positionsContainer);
hide(sectionTitle);
hide(results);
container.className = 'female';
// overall game control
function play() {
hide(intro);
show(sectionTitle);
show(positionsContainer);
}
// in-game control
function choose() {
// prevent duplicate choices
this.disabled = true;
// Ladies first
if(choices.ladies.length < MAX_CHOICES) {
choices.ladies.push(this.id);
// change the classname to "male" once female choices reach 2
if(choices.ladies.length == MAX_CHOICES) {
container.className = 'male';
sectionTitle.textContent = 'Gents';
sectionTitle.classList.remove('slideInLeft');
sectionTitle.classList.add('slideInRight');
}
} else {
choices.gents.push(this.id);
if(choices.gents.length == MAX_CHOICES) {
showResults();
}
}
}
// results
function showResults() {
// change the classname to results once the gents selections reach 2
container.className = 'results';
sectionTitle.textContent = 'Results';
sectionTitle.classList.remove('slideInRight');
sectionTitle.classList.add('tada');
choices.forEach(function(c) { c.disabled = true });
// randomly get a selection from each array
do {
var ladiesIndex = Math.floor(Math.random() * MAX_CHOICES);
var gentsIndex = Math.floor(Math.random() * MAX_CHOICES);
} while (ladiesIndex === gentsIndex);
var ladiesChoice = getByID(choices.ladies[ladiesIndex]);
var gentsChoice = getByID(choices.gents[gentsIndex]);
animateChoice(ladiesChoice);
animateChoice(gentsChoice);
// print out the final choices
chosenPositions.textContent = "Looks like you'll be doing " +
ladiesChoice.textContent + " and " +
gentsChoice.textContent +
" tonight!";
show(results);
}
function restart() {
container.className = 'female';
sectionTitle.textContent = 'Ladies';
sectionTitle.classList.remove('tada');
sectionTitle.classList.add('slideInLeft');
sectionTitle.classList.remove('slideInRight');
hide(results);
choices.ladies = [];
choices.gents = [];
choices.forEach(function(c) {
c.disabled = false;
// somewhat crude approach at the moment for removing the classes
c.classList.remove('selected', 'animated', 'infinite', 'pulse');
});
}
// utility functions
function getByID(ID) {
return document.getElementById(ID);
}
function show(element) {
element.style.display = 'block';
}
function hide(element) {
element.style.display = 'none';
}
function animateChoice(element) {
element.classList.add('selected', 'animated', 'infinite', 'pulse');
}
function deanimateChoice(element) {
element.classList.remove('selected', 'animated', 'infinite', 'pulse');
}
})();